You are on page 1of 4

Attribute VB_Name = "Module1"

Option Explicit
Sub simu()
Dim nCols As Integer, nRows As Integer, NSim As Integer, strng As String, i As I
nteger, j As Integer, N As Integer
Dim edgecells, conctvt As Integer, totalcon As Integer, nMoves As Integer, nFill
ed As Integer
Dim a As Single, b As Single, c As Single, d As Single, e As Single, f As Single
, g As Single, h As Single, k As Single
Open "C:\Documents and Settings\Kevin\Desktop\simlog.txt" For Output As #1
Print #1, "Started at " & Now
Print #1, ""
Print #1, "Iteration"; " "; "Average connectivity"; " "; "Number of moves"
; " "; "Filled cell count"
'format area
nCols = 30
nRows = 30
strng = ConvertToLetter(1) & ":" & ConvertToLetter(nCols)
With Columns(strng)
.ColumnWidth = 2.05
.NumberFormat = ";;;"
End With
'initialize border
Range(Cells(1, 1), Cells(1, nCols)).Interior.ThemeColor = xlThemeColorDark1
Range(Cells(1, 1), Cells(1, nCols)).Interior.TintAndShade = -0.25 'gray
Range(Cells(1, 1), Cells(1, nCols)).Value = 0
Range(Cells(1, nCols), Cells(nRows, nCols)).Interior.ThemeColor = xlThemeColorDa
rk1
Range(Cells(1, nCols), Cells(nRows, nCols)).Interior.TintAndShade = -0.25
Range(Cells(1, nCols), Cells(nRows, nCols)).Value = 0
Range(Cells(nRows, nCols), Cells(nRows, 1)).Interior.ThemeColor = xlThemeColorDa
rk1
Range(Cells(nRows, nCols), Cells(nRows, 1)).Interior.TintAndShade = -0.25
Range(Cells(nRows, nCols), Cells(nRows, 1)).Value = 0
Range(Cells(nRows, 1), Cells(1, 1)).Interior.ThemeColor = xlThemeColorDark1
Range(Cells(nRows, 1), Cells(1, 1)).Interior.TintAndShade = -0.25
Range(Cells(nRows, 1), Cells(1, 1)).Value = 0
'initialize cells
For i = 2 To nRows - 1
For j = 2 To nCols - 1
If Rnd() > 0.5 Then 'fill the cell
Cells(i, j).Interior.ThemeColor = xlThemeColorLight1 'black cell
Cells(i, j).Value = 1 'occupy cell
Else 'do not fill
Cells(i, j).Interior.ThemeColor = xlThemeColorDark1 'white cell
Cells(i, j).Value = 0 'empty cell
End If
Next j
Next i
'run simulation N times, excluding edge cells
NSim = 20
For N = 1 To NSim
totalcon = 0
nFilled = 0
nMoves = 0
'move cells randomly
For i = 2 To nRows - 1
For j = 2 To nCols - 1
If Cells(i, j).Value = 1 Then 'if current cell is occupied
Cells(i, j).Select 'calculate number of connected cells (including d
iagonals)
With ActiveCell
.FormulaR1C1 = "=R[-1]C[-1]+R[-1]C+R[-1]C[1]+RC[-1]+RC[1]+R[1]C[
-1]+R[1]C+R[1]C[1]"
conctvt = .Value
.Value = 1
edgecells = -4 * (.Offset(-1, -1).Interior.TintAndShade + .Offse
t(-1, 0).Interior.TintAndShade + .Offset(-1, 1).Interior.TintAndShade + .Offset(
0, -1).Interior.TintAndShade + .Offset(0, 1).Interior.TintAndShade + .Offset(1,
-1).Interior.TintAndShade + .Offset(1, 0).Interior.TintAndShade + .Offset(1, 1).
Interior.TintAndShade)
End With
edgecells = Round(edgecells, 0) 'rounding correction
'probability of move is inversely proportional to degree of connecti
vity
'no move if completely surrounded by filled cells and edge cells
If Rnd < (WorksheetFunction.Ceiling((8 - conctvt - edgecells) / 8, 1
) * Exp(-conctvt)) Then 'choose to move
'randomize the relative chances of moving into the 8 adjacent ce
lls (a,b,c,d,e,f,g,h)
'if cell is occupied, chance of moving into it becomes zero as (
1 + 1) Mod 2 = 0
'body cells are treated normally, TintAndShade = 0 -> does not a
ffect
'but edge cells will not be moved into, TintAndShade = -0.25 ->
(0 + 4 * -0.25 + 1) Mod 2 = 0
a = Rnd * ((Cells(i, j).Offset(-1, -1).Value + 4 * Cells(i, j).O
ffset(-1, -1).Interior.TintAndShade + 1) Mod 2)
b = Rnd * ((Cells(i, j).Offset(-1, 0).Value + 4 * Cells(i, j).Of
fset(-1, 0).Interior.TintAndShade + 1) Mod 2)
c = Rnd * ((Cells(i, j).Offset(-1, 1).Value + 4 * Cells(i, j).Of
fset(-1, 1).Interior.TintAndShade + 1) Mod 2)
d = Rnd * ((Cells(i, j).Offset(0, -1).Value + 4 * Cells(i, j).Of
fset(0, -1).Interior.TintAndShade + 1) Mod 2)
e = Rnd * ((Cells(i, j).Offset(0, 1).Value + 4 * Cells(i, j).Off
set(0, 1).Interior.TintAndShade + 1) Mod 2)
f = Rnd * ((Cells(i, j).Offset(1, -1).Value + 4 * Cells(i, j).Of
fset(1, -1).Interior.TintAndShade + 1) Mod 2)
g = Rnd * ((Cells(i, j).Offset(1, 0).Value + 4 * Cells(i, j).Off
set(1, 0).Interior.TintAndShade + 1) Mod 2)
h = Rnd * ((Cells(i, j).Offset(1, 1).Value + 4 * Cells(i, j).Off
set(1, 1).Interior.TintAndShade + 1) Mod 2)
k = 0 'find the cell with largest chance of being moved into
If k < a Then
k = a
End If
If k < b Then
k = b
End If
If k < c Then
k = c
End If
If k < d Then
k = d
End If
If k < e Then
k = e
End If
If k < f Then
k = f
End If
If k < g Then
k = g
End If
If k < h Then
k = h
End If
If k = a Then
Cells(i, j).Offset(-1, -1).Select
ElseIf k = b Then
Cells(i, j).Offset(-1, 0).Select
ElseIf k = c Then
Cells(i, j).Offset(-1, 1).Select
ElseIf k = d Then
Cells(i, j).Offset(0, -1).Select
ElseIf k = e Then
Cells(i, j).Offset(0, 1).Select
ElseIf k = f Then
Cells(i, j).Offset(1, -1).Select
ElseIf k = g Then
Cells(i, j).Offset(1, 0).Select
ElseIf k = h Then
Cells(i, j).Offset(1, 1).Select
End If
Selection.Interior.ThemeColor = xlThemeColorLight1 'make new cel
l black
Selection.Value = 1 'occupy new cell
Cells(i, j).Interior.ThemeColor = xlThemeColorDark1 'make old ce
ll white
Cells(i, j).Value = 0 'empty old cell
End If
nMoves = nMoves + 1
End If
Next j
Next i
'check cells
For i = 2 To nRows - 1
For j = 2 To nCols - 1
If Cells(i, j).Value = 1 Then 'if current cell is occupied
Cells(i, j).Select 'calculate number of connected cells (including d
iagonals)
With ActiveCell
.FormulaR1C1 = "=R[-1]C[-1]+R[-1]C+R[-1]C[1]+RC[-1]+RC[1]+R[1]C[
-1]+R[1]C+R[1]C[1]"
conctvt = .Value
.Value = 1
End With
totalcon = totalcon + conctvt 'running total
nFilled = nFilled + 1
End If
Next j
Next i
Print #1, N; " "; Round(totalcon / nFilled, 4); " "; nMov
es; " "; nFilled
Next N
Cells(nRows + 1, nCols + 1).ClearContents
Print #1, ""
Print #1, "Ended at " & Now
Close #1
End Sub
Function ConvertToLetter(iCol As Integer) As String
'adapted from http://support.microsoft.com/kb/833402
Dim iAlpha As Integer
Dim iRemainder As Integer
If iCol > 0 Then
iAlpha = Int((iCol - 1) / 26)
iRemainder = iCol - (iAlpha * 26)
End If
If iAlpha > 0 Then
ConvertToLetter = Chr(iAlpha + 64)
End If
If iRemainder > 0 Then
ConvertToLetter = ConvertToLetter & Chr(iRemainder + 64)
End If
End Function