Honours project: Distributed simulation of predator-prey interactions.
The goal of my Honours project was to develop a software system
which allowed for the simulation of a simplified ecosystem, in which
different types of creature attempted to survive. The simulation was
to be distributed across multiple machines using Java's Remote Method
Invocation (RMI). This project specification was deliberately
open-ended, allowing a good deal of exploration, reading,
experimenting with ideas, and so forth.
In the finished project, simulated environments are distributed by chopping landscapes up into smaller rectangular sections. Each of these sections is sent to a remote machines ready to accept work; remote machines can each hold zero or more segments of "work". Each section of land coordinates with adjacent sections on remote machines to handle moving creatures across borders, spreading of vegetation, etc. To ease spurious network traffic, each section maintains small amounts of remote state locally (thus allowing creatures to see across borders which, to them, should be transparent).
Creatures are split into two basic categories: predators and prey. The prey eat any natural vegetation around the landscape (of which there is only one type), and the predators eat the prey. A certain level of creature configurability was catered for, allowing slightly different behaviours to be observed. For example, a creature type defines certain characteristics, such as how fast it can walk or run, how hungry it gets before it starts to look for food, etc.
The simulation, although simple, serves as an example of an
application running on top of the distributed framework built for the
project. Heavy use of simple object oriented design principles allowed
for much of the functionality to be kept in a generic 'Core' package,
with the actual simulation-specific code appearing only in a 'World'
package. A generic Worker component, which has no knowledge of the
type of simulation to be run, must be instantiated in machines willing
to take on work. Provided components adhere to the 'Work' interface
correctly, a Worker requires no further information.
Controlling the distributed simulations was an application-specific centralised server, which also dealt with splitting up user-submitted 'worlds' into smaller sections of roughly equal proportions, and then sharing those sections between connected workers.
The code design for the project allowed for a generic framework to be built, allowing for the majority of server code and for worker nodes to be generic. Thus, the work to be done and how portions of it interact, plus a UI if required, are all that's required to build an entirely new system out of the framework developed.
World Generator
The world generator is where configuration of a simulation took
place before submitting it to the server. Various attributes could be
altered, such as the basic dimensions of the landscape, modification
of land height post-generation, population density, addition of
creatures or vegetation to the landscape, etc. New creature types can
also be configured via the world generator.
The terrains are generated randomly using the Diamond-square algorithm. The different land types (sea, beach, grassland, snow) being determined by their value in the generated heightmap. This is a simple, but effective, way of creating landscapes which look reasonable.
World Viewer:
A
user interface (pictured here) could connect to the server, and
request to view any given simulation which was currently running. This
required each section of land to periodically send enough information
back to the UI to draw a representation of the current state in the
correct location. It is the responsibility of the viewer to stitch the
pieces back together accordingly.
"Mind Games": An intelligent Draughts playing program.
3rd year team project, a required part of the degree. Worth approximately 1/6 of the year. Teams consisted of 5 members, my main role being lead programmer.
The project was written entirely in Java, the aim being to build an intelligent (in some sense of the word) Draughts game, using object oriented design principles. The intelligence of the artificial players was achieved using the well-known minimax algorithm, with alpha-beta pruning implemeted later to reduce the search time. The object oriented design allowed for the simple minimax analyser to be swapped for the minimax analyser with alpha-beta pruning, for testing purposes (no in-game facility was provided to allow switching of the analysers at runtime, though this would be particularly easy to implement).
The scores with which the analysers dealt were generated by the evaluator, which generated remarkably good scores for most scenarios, leading to a fairly powerful artificial player for reasonably shallow search trees. The game will generally always beat me, though I'm certainly not known for my Draughts playing abilities.
Screenshots
![[IMAGE: Draughts screenshot.]](./images/draughts1.png)
The outcome of a game between myself and the computer set to the most intelligent level offered as an in-game option. Notice the move history logging captures whereby multiple pieces were removed from the board. Pieces upgraded to kings are those with an inner black ring.
![[IMAGE: Draughts screenshot.]](./images/draughts2.png)
The tutorial menu option, running through some of the simple functionality of the game.
![[IMAGE: Draughts screenshot.]](./images/draughts3.png)
A match pitting an easy computer player against a more difficult computer player. As would be expected, the difficult computer player wins.
![[IMAGE: Draughts screenshot.]](./images/draughts4.png)
Red player -- in action! The square whose number is highlighted red is the selection that that player has made.
![[IMAGE: Draughts screenshot.]](./images/draughts5.png)
Human vs. Computer. When a human player is to move, pieces which can legally move are highlighted by having their current square number displayed as yellow. Selections are red, and deselections return to yellow.