Khet

CS550 OpenGL Term Project

About The Game

Khet is a strategy board game sold by Innovention toys, where players move and rotate piece with mirrors, attempting to destroy each other's pieces.

How to Play

The rules are available on the Khet website.

In this version of Khet, obelisks cannot be stacked, but the rules are otherwise the same. You are silver, and the computer computer plays red. You move a piece by dragging it with the left mouse button to an adjacent space, or by rotating it by dragging with the right mouse button.

After you've made a valid move, your laser button in the lower right corner of the board will glow, indicating that it is armed. You must fire it after each move.

When one player wins, the board turns their color and no further moves are possible.

Download the windows binary or the mac binary here. For both of the binaries, you need to have glut libraries installed.

Implementation

The model is implemented in Board and related classes (in Board.h and Board.cpp). It keeps track of where the pieces are and whose turn it is. It checks what moves are legal, creates the computer's playing strategy, and calculates the path of the laser.

The view is implemented in BoardView and related clases in (Boardview.h, Boardview.cpp, ObjDrawer.h, ObjDrawer.cpp). These objects refer to the Board model and draw OpenGL objects to reflect the current state of the game.

The game is controlled by functions in main.cpp, which handle mouse events and animation, and coordination of the Board and Boardview objects. The Projetor class handles the translations among the different OpenGL coordinate spaces.

Download the raw source code. or the Visual Studio 2005 source code plus project files. The Windows code is identical except for the computer's gameplay: its lookahead is inferior because the windows machine I had access to was too slow on 3-move lookahead, so it's dialed down to 2-move lookahead. It's actually fairly stupid either way.

Challenges

Dragging pieces
I wanted to be able to click on a piece, and drag it freely around the screen, but have that motion interpreted as motion within the x-z plane, where the board is rendered. I attempted to do this by applying the current matrix transformations to the points (0,0,0), (1,0,0), and (0,0,1), finding their pixel locations, then mapping the mouse's x,y location in to that coordinate space. However it doesn't seem to be very accurate far from the origin; the piece strays further and further from the mouse the farther from the origin you get.
Normal directionality
I set OpenGL to render polygons front-and-back, thinking that this would save me from having to get the order of their vertices right when calculating normals. However the shading came out wonky. So I temporarily switched to a front-only rendering mode, and went through all the models and reordered vertices on faces that weren't right.
Animation
Animation is accomplished with a function, triggering itself repeatedly with a timer, that draws something different depending on the values of a "phase" integer and the system clock. The computer's move, a pause, the computer's laser shot, and the explosion are all considered different phases. The phase is incremented when a fixed amount of time has passed, regardless of the number of times the timer function is actually called. Similarly the animations are governed by the elapsed system time, rather than on the number of calls to animate(). For example the size of the exploding piece is determined by subtracting the current time from the start time of the animation, dividing by the total intended length of the animation, squaring that result (to get a gradual but accelerating expansion effect), and using that factor to increase the scale each time the object is drawn.

Future Work

Things that ought to be done to improve the game: