Learn VB .NET Through Game Programming [Electronic resources]

Matthew Tagliaferri

نسخه متنی -صفحه : 106/ 44
نمايش فراداده

Developing the Voting Game

The final cellular automaton game is a bit subtler in its complexities than the Life variants. It’s called the Voting Game, and I read about it for the first time in the book The Armchair Universe: An Exploration of Computer Worlds by A. K. Dewdney (W .H. Freeman and Company, 1988). This book contained a compilation of excerpts of articles from Scientific American magazine from 1984 and 1987 (there I go dating myself again).

The lattice in the Voting Game contains cells of two colors. Each color represents a political party affiliation (Democrat and Republican if you want to assign an American slant to the game). At the start of the game, each cell is randomly assigned one party or the other. Within each tick of the clock, the game chooses asingle cell at random, as well as a single neighbor of that cell. The political party of the chosen cell changes to that of the neighbor cell, regardless of the party of either cell at the start of the process. Figure 5-5 shows a VB .NET representation of the Voting Game.

Figure 5-5: The Voting Game

Like in Conway’s Game of Life and its variants, you can find patterns in the Voting Game, though you often have to wait a bit longer to see them form. After a time, blocks of same-partied cells group themselves together. Usually, one of the two parties becomes dominant, leaving only a small island or two of the minority party. These small blocks sometimes migrate around the lattice over time. Finally, the dominant party often completely eliminates the minority party, leaving the entire population voting with a unanimous voice.

Creating TheVotingGame Class

The game class, which is unimaginatively named TheVotingGame, contains functionality that differs little from the game classes you’ve already seen. As required, the class implements the CreateOneCell method to return an instance of the cell class associated with this game, as shown in Listing 5-13.

Listing 5.13: The CreateOneCell Method of the TheVotingGame Class

Protected Overrides Function _ 
CreateOneCell(ByVal oPos As Point) As CellularAutomataCell 
Dim oC As VotingCell 
fSetupNeighbors = False 
oC = New VotingCell(oPos, Me.CellRadius) 
oC.IsDemocrat = HalfTheTime() 
Return oC 
End Function 

The only setup required for a voting cell class is its party affiliation. You implement this as a Boolean property named IsDemocrat, which is set to true 50 percent of the time, using the HalfTheTime method defined in the ancestor game class. Once the party affiliation is set, the cell class is returned.

The other required method for all descendant game classes is the RunAGeneration method, which is simpler in the Voting Game than it was in the Life games. Listing 5-14 shows this method.

Listing 5.14: The RunAGeneration Method of TheVotingGame Class

Protected Overrides Sub RunAGeneration() 
Dim oC As VotingCell 
If Not fSetupNeighbors Then 
SetupNeighbors() 
End If 
'choose a random neighbor 
oC = fCells.Item(oRand.Next(0, fcells.Count)) 
oC.ChangePartyAffiliation() 
End Sub 

Like the Life games, you need to set up the cell neighbors before the first generation runs. After that, however, each tick of the clock selects a random cell Listing 5-7 and thus not repeated here)—with one notable exception. When looking for the neighbor cells of a given cell, the RowColToCell method declared in the ancestor class is sent an additional parameter bWrap, which is set to True:

oCn = RowColToCell(iRow + iLRow, iCol + iLCol, bWrap:=True) 

The bWrap parameter tells the RowColToCell method to wrap around the edges of the lattice when looking for neighbors. Therefore, cells along the top row and bottom row are considered adjacent, as are the far-left and far-right columns. This gives every cell in the lattice exactly eight neighbors.

Creating the VotingCell Class

The VotingCell class contains the same neighbor handling code as the Life games did. As required, it implements the GetColor method, which returns blue or red depending on the party affiliation of the cell. As shown in Listing 5-13, the VotingCell class contains a property named IsDemocrat to denote the party affiliation of the cell. Listing 5-15 shows that property definition and the GetColor method.

Listing 5.15: The Overridden GetColor Method, the IsDemocrat Property, and the ChangePartyAffiliation Method of the VotingCell Class

Overrides Function GetColor() As Color 
Return IIf(Not FDemocrat, Color.Blue, Color.Red) 
End Function 
Private FDemocrat As Boolean = False 
Property IsDemocrat() As Boolean 
Get 
Return FDemocrat 
End Get 
Set(ByVal Value As Boolean) 
FDemocrat = Value 
End Set 
End Property 
Public Sub ChangePartyAffiliation() 
Dim oC As VotingCell 
oC = FNeighbors.Item(oRand.Next(0, FNeighbors.Count)) 
Me.IsDemocrat = oC.IsDemocrat 
End Sub 

The last important member in the VotingCell class is the ChangePartyAffiliation method, also shown in Listing 5-15. This function selects a random neighbor to the current cell and copies that neighbor cell’s party affiliation to the current cell. It’s quite possible (50-percent possible, in fact) that the current cell and the neighbor cell already have the same party affiliation. When this happens, there’s no change to the lattice during that timer tick.