|
A minimalist Visual Basic implementation of Langton's Ant.
Start a new "Standard EXE" project and resize the default form to create a reasonable viewing area. Place a Picture Box on the form and resize this to take up most of the available space. Change the PictureBox Appearance to 'flat', set AutoRedraw to True and the ScaleMode to 3 - Pixels. Add three Command buttons, a horizontal scroll bar and a label to the remaining area. Declare a boolean value called RunOk in the general section. Give the three command buttons the following captions "Start", "Stop" and "End" in that order. Then set the scroll bar Max value to 200. The code below uses the default names for each of the controls added to the form. This code was written using VB6 but if you drop the keyword "Private" in the declaration of the Sub routines it should work fine in previous versions. Clearly the code can be further simplified but I hope it's straightforward to follow and adapt, if necessary, to other languages.
The scroll bar is used to "seed" the white picture box with random black pixels so that you can experiment with a range of starting positions. The default is the standard white surface. The label is used to display the number of moves as the model runs - watch carefully as the number approaches 10,000.
Place the following code under the click events of the three command buttons.
Private Sub Command1_Click() 'Start Picture1.Cls RunOk = True RunDemo End Sub
Private Sub Command2_Click() 'Stop RunOk = False End Sub
Private Sub Command3_Click() 'end End End Sub
Then create the following Sub:
Private Sub RunDemo() Dim CurX As Long, CurY As Long, MoveCounter As Long Dim NoiseX As Long, NoiseY As Long Dim Directn As Integer, NoiseLoop As Integer Dim ThisSq As Long, RandLimit As Long, RandHalf As Long
'Calculate the start position - at the centre CurX = Picture1.ScaleWidth / 2 CurY = Picture1.ScaleHeight / 2 Directn = Int(4 * Rnd - 1) 'Decide on a direction to face 'now draw in any "noise" level set by the scroll bar If HScroll1.Value > 0 Then RandLimit = 1000 / Screen.TwipsPerPixelY RandHalf = RandLimit / 2 Randomize For NoiseLoop = 1 To HScroll1.Value NoiseX = Int(((CurX + RandHalf) - (CurX - RandHalf) + 1) * Rnd + (CurX - RandHalf)) NoiseY = Int(((CurY + RandHalf) - (CurY - RandHalf) + 1) * Rnd + (CurY - RandHalf)) Picture1.PSet (NoiseX, NoiseY), QBColor(0) Next NoiseLoop End If 'Read the colour of the pixel at the start position ThisSq = Picture1.Point(CurX, CurY) Do While RunOk Select Case ThisSq Case QBColor(0) 'it is black Picture1.PSet (CurX, CurY), QBColor(15) 'set this pixel white 'then turn left Directn = Directn - 1 If Directn < 1 Then Directn = 4 End If Case Else 'it should be white Picture1.PSet (CurX, CurY), QBColor(0) 'set this pixel black 'then turn right Directn = Directn + 1 If Directn > 4 Then Directn = 1 End If End Select Picture1.Refresh Select Case Directn Case 1 'Up CurY = CurY - 1 Case 2 'Right CurX = CurX + 1 Case 3 'down CurY = CurY + 1 Case 4 'left CurX = CurX - 1 End Select ThisSq = Picture1.Point(CurX, CurY) 'read the colour of the next position MoveCounter = MoveCounter + 1 Label1.Caption = Format$(MoveCounter, "#,###,##0") Label1.Refresh DoEvents 'Gives you a chance to click the stop button If CurX = 0 Or CurX = Picture1.ScaleWidth Or CurY = 0 Or CurY = Picture1.ScaleHeight Then 'rather than scroll the view we come to a stop RunOk = False End If Loop End Sub
|