The source code of all applications is included in the JGameGrid distribution.
PacMan
is an arcade game developed in Japan on May 22, 1980. Immensely popular all over the world from its original release to the present day, Pac-Man is universally considered as one of the classics of the medium, virtually synonymous with video games, and an icon of the 1980s popular culture. The player controls Pac-Man through a maze, eating pac-dots. When all dots are eaten, Pac-Man is taken to the next stage. Four ghosts (Blinky, Pinky, Inky and Clyde) roam the maze, trying to catch Pac-Man. If a ghost touches Pac-Man, a life is lost. When all lives have been lost, the game ends.
[Ref. http://en.wikipedia.org/wiki/Pac-Man]
This is a basic implementation to keep the code simple for the purpose of demonstration. There are only two ghosts with a simple strategy: One ghost moves arbitrarily through the maze but may block the Pac-Man to move. The other ghost knows the position of the Pac-Man and moves toward him.
Execute the program locally using WebStart.
Sokoban
is a transport puzzle in which the player pushes boxes around a maze, viewed from above, and tries to put them in designated locations. Only one box may be pushed at a time, and boxes cannot be pulled. Sokoban was created in 1980 by Hiroyuki Imabayashi.
Sokoban can be studied using the theory of computational complexity. The problem of solving Sokoban puzzles has been proven to be NP-hard. This is interesting also for artificial intelligence researchers, because solving Sokoban can be compared to designing a robot which moves boxes in a warehouse.
Sokoban is difficult due to its enormous search tree depth; some levels require more than 1000 "pushes". Skilled human players rely mostly on heuristics; they are usually able to quickly discard futile or redundant lines of play, and recognize patterns and subgoals, drastically cutting down on the amount of search.
[Ref. http://en.wikipedia.org/wiki/Sokoban]
The basic JGameGrid implementation is straightforward and uses a simple data structure for the game layout. It's a string arranged line by line where each character represents a cell in the rectangular playground. The characters are coded as follows:
<space> |
Empty cell outside |
<dot> |
Empty cell inside |
x |
Border cell |
* |
Stone |
o |
Target cell |
A |
Sokoban actor |
The following string represents the game layout shown below:
private final static String soko_0 =
" xxxxx " + // 0
" x...x " + // 1
" x*..x " + // 2
" xxx..*xx " + // 3
" x..*.*.x " + // 4
"xxx.x.xx.x xxxxxx" + // 5
"x...x.xx.xxxxx..oox" + // 6
"x.*..*..........oox" + // 7
"xxxxx.xxx.xAxx..oox" + // 8
" x.....xxxxxxxxx" + // 9
" xxxxxxx "; //10
The 4 cursor keys are used to move the Sokoban actor. It is easy to extend the basic implementation by adding an improved user action (selecting level of difficulty, choosing appearance of stones, storing/resuming current game state, withdraw a move, etc.)
Execute Level 0 using WebStart.
Execute Level 1 using WebStart.
Execute Level 2 using WebStart.
Game of Life
is a cellular automaton invented by the British mathematician John Horton Conway in 1970. It is the best-known example of a cellular automaton. The "game" is a zero-player game, meaning that its evolution is determined by its initial state, requiring no further input from humans. One interacts with the Game of Life by creating an initial configuration and observing how it evolves.
The universe of the Game of Life is an infinite two-dimensional orthogonal grid of square cells, each of which is in one of two possible states, live or dead. Every cell interacts with its eight neighbours, which are the cells that are directly horizontally, vertically, or diagonally adjacent. At each step in time, the following transitions occur:
- Any live cell with fewer than two live neighbours dies, as if caused by underpopulation.
- Any live cell with more than three live neighbours dies, as if by overcrowding.
- Any live cell with two or three live neighbours lives on to the next generation.
- Any dead cell with exactly three live neighbours becomes a live cell.
The initial pattern constitutes the seed of the system. The first generation is created by applying the above rules simultaneously to every cell in the seed—births and deaths happen simultaneously, and the discrete moment at which this happens is sometimes called a tick (in other words, each generation is a pure function of the one before). The rules continue to be applied repeatedly to create further generations.
Ref. http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life]
Our implementation with JGameGrid is not very efficient but nevertheless quite natural: Every cell contains an actor of the class Creature that is visible (alive) or invisible (dead). GameGrid.act() applies the generation rule and sets a flag isAlive of each creature accordingly. It is not a good idea to change the visibility of an actor immediately because for one generation the current state of all creatures must be maintained when applying the generation rule to each creature.
public void act()
{
// Every creature "sees" the same population, because it
// is based on isVisible()
for (Creature creature : creatures)
{
// Get number of (living) neighbours
ArrayList<Actor> neighbours = creature.getNeighbours(1);
int nbNeighbours = 0;
for (Actor neighbour : neighbours)
{
if (neighbour.isVisible())
nbNeighbours++;
}
// Generation rule:
if (creature.isVisible()) // alive
{
if (!(nbNeighbours == 2 || nbNeighbours == 3))
creature.isAlive = false; // dying
}
else // dead
{
if (nbNeighbours == 3)
{
creature.isAlive = true; // become alive
}
}
}
showPopulation();
}
private void showPopulation()
{
for (Creature creature : creatures)
{
if (creature.isAlive)
creature.show();
else
creature.hide();
}
}
At startup 200 creatures are alive and distributed randomly in 400 cells. The navigation bar may be used to create the next generation manually by clicking the Step button.
Execute the program locally using WebStart.
It is interesting to investigate the behavior of special population patterns. Instead of creating the population randomly you may change the state of a creature by clicking in the cell in this program version.
Some static patterns:
Some oscillating patterns:
Some gliders:
Cat Game
is a typical example of a game with a complex scenario that is built-up by using a tile map and a moving background image. The cat can be moved with the left and right cursor keys. When pressing the space bar, the cat jumps up. After the cat passes the two dogs it should eat as many flies as possible.
This application uses the build-in collision detection in the JGameGrid library in many aspects:
- Collision between cat/dogs and tiles to know where is the floor and where is the wall
- Collision between dogs and the cat to threaten the cat
- Collision between the cat's mouth and the flies to eat the flies
Execute the program locally using WebStart.
[Tile images from "Brackeen, Developing Games in Java"]
|