The Prisoner's Dilemma: Technical Notes
 

I thought it would be interesting to write a little bit about the structure of the program itself. So here we go. You can also consult the javadoc (generated with version 1.1, I'm afraid).

The main consideration was to make the program structure as flexible as possible to be able to reuse bits and pieces in other similar endeavors. Indeed, such a representation of the Prisoner's Dilemma is part of the great family of the cellular automata and it would have been a shame making such a development and not reusing part of it for other cellular automata situations.

Of course, reuse is the big thing in object-oriented programming, but with Java you get much cleaner results than in C++ thanks to interfaces. You can design your objects any way you want and then tell them to behave in a certain way by having them implement a given interface.

In the case of the Prisoner's Dilemma what is needed basically are the prisoners themselves, a kind of board to arrange them inside some structure and a couple of functions to run the show. So that would be three classes, that would have to be rewritten everytime something changes.

Enter interfaces, ta-dah! The thinking is to say that whatever structure is going to hold the prisoners, it should behave in a precise way, say like a "game board". On the other hand, the structure should not have to worry about what kind of elements it holds. They should all just be "pawns". This is represented in the figure below:

Prisoner's Dilemma diagram

No matter what kind of board is used, it behaves as a GameBoard. And the prisoners are welcome aboard, as long as they can behave as Pawns. All that is needed to use another board is to program the board itself and make sure it behaves as a proper GameBoard. The PrisonerGame needs only change the call to the constructor (at the moment, the applet is stuck using a square board, but in a future version it will be possible to dynamically change the board in the options of the game). The board also tells the pawns which shape they should use to represent themselves. This shape class is dynamically loaded at runtime.

The basic functions required of a board are:

  • adding a new pawn to the board;
  • indicating the shape requested for the graphical representation of the pawns;
  • indicating the maximum number of neighbors (this is used by the pawns to dimension their array of neighbors; the list of neighbors could have been kept in a List, but it seems more efficient this way if a bit constraining);
  • telling the pawns their list of neighbors;
  • iterators to cycle through the pawns contained by the board.

Such a definition of a board makes it possible to use structures that do not look like a board at all such as the "Network Game Board" pictured above. A pawn, on the other hand, must be capable of:

  • giving its id;
  • drawing itself;
  • setting its list of neighbors.

All these functionalities will be expanded in the future. In particular, I want to make it possible to start with a uniform configuration (e.g. all prisoners honest) and click on individual prisoners to change their state. Here again, the interface concept is a big help. Each board will have to be able to tell which pawn has been clicked on and any class implementing Pawn will have a method for handling mouse clicks (e.g. toggling or cycling through states or simply ignoring the click).