patternMinor
Follow-up: Randomizing Civilization 5 team choice
Viewed 0 times
teamrandomizingchoicefollowcivilization
Problem
This is a follow-up on my previous question about a VBA macro for randomizing a draw from a table. It can be found here:
Randomizing Civilization 5 team choice
The code has been improved with the help I got earlier and I now seek even further improvements.
```
Public Enum CivilizationTableColumns
CivilizationName = 1
CivilizationLeader = 2
End Enum
Public Enum TextColumns
PlayerTextColumn = 1
CivTextColumn = 2
End Enum
Public Sub Draw()
Dim ws As Worksheet
Set ws = ThisWorkbook.ActiveSheet
Dim resultsRange As Range
Set resultsRange = GetResultsRange(ws)
resultsRange.ClearContents
Dim CivilizationsTable As ListObject
Set CivilizationsTable = Worksheets("Civilizations").ListObjects("tblCivilizations")
Dim randCiv As String
For noOfPlayers = 1 To GetPlayerNum(ws)
resultsRange.Cells(GetPlayerNameRow(ws, noOfPlayers), PlayerTextColumn).Value = GetPlayerName(noOfPlayers)
For noOfOptions = 1 To GetOptionsNum(ws)
Dim endOfRange As Boolean
endOfRange = False
While Not endOfRange
randCiv = GetCivilizationCaption(GetRandomNum(CivilizationsTable), CivilizationsTable)
For Z = 1 To resultsRange.Rows.Count
If resultsRange.Cells(Z, CivTextColumn) = randCiv Then
Exit For
End If
If Z = resultsRange.Rows.Count Then
endOfRange = True
End If
Next Z
Wend
resultsRange.Cells(GetCivNameRow(ws, noOfPlayers, noOfOptions), CivTextColumn).Value = randCiv
Next noOfOptions
Next noOfPlayers
End Sub
Private Function GetRandomNum(ByVal CivilizationsTable As ListObject) As Integer
GetRandomNum = CInt(Int((CivilizationsTable.Range.Rows.Count - 1) * Rnd())) + 1
End Function
Private Function GetCivilizationCaption(ByVal index As Long, ByVal CivilizationsTable As ListObject)
Set Row = CivilizationsTable.ListRows(index)
civName = Row.Range(ColumnIndex:=Civili
Randomizing Civilization 5 team choice
The code has been improved with the help I got earlier and I now seek even further improvements.
```
Public Enum CivilizationTableColumns
CivilizationName = 1
CivilizationLeader = 2
End Enum
Public Enum TextColumns
PlayerTextColumn = 1
CivTextColumn = 2
End Enum
Public Sub Draw()
Dim ws As Worksheet
Set ws = ThisWorkbook.ActiveSheet
Dim resultsRange As Range
Set resultsRange = GetResultsRange(ws)
resultsRange.ClearContents
Dim CivilizationsTable As ListObject
Set CivilizationsTable = Worksheets("Civilizations").ListObjects("tblCivilizations")
Dim randCiv As String
For noOfPlayers = 1 To GetPlayerNum(ws)
resultsRange.Cells(GetPlayerNameRow(ws, noOfPlayers), PlayerTextColumn).Value = GetPlayerName(noOfPlayers)
For noOfOptions = 1 To GetOptionsNum(ws)
Dim endOfRange As Boolean
endOfRange = False
While Not endOfRange
randCiv = GetCivilizationCaption(GetRandomNum(CivilizationsTable), CivilizationsTable)
For Z = 1 To resultsRange.Rows.Count
If resultsRange.Cells(Z, CivTextColumn) = randCiv Then
Exit For
End If
If Z = resultsRange.Rows.Count Then
endOfRange = True
End If
Next Z
Wend
resultsRange.Cells(GetCivNameRow(ws, noOfPlayers, noOfOptions), CivTextColumn).Value = randCiv
Next noOfOptions
Next noOfPlayers
End Sub
Private Function GetRandomNum(ByVal CivilizationsTable As ListObject) As Integer
GetRandomNum = CInt(Int((CivilizationsTable.Range.Rows.Count - 1) * Rnd())) + 1
End Function
Private Function GetCivilizationCaption(ByVal index As Long, ByVal CivilizationsTable As ListObject)
Set Row = CivilizationsTable.ListRows(index)
civName = Row.Range(ColumnIndex:=Civili
Solution
Your indentation is generally fine, except the
Becomes that:
I like that you have lots of small functions - that's very good!
However
That's 4 layers of nested loops! I've seen worse arrow code, but I'd extract a method out of the body of the 2nd
Other than that, looks great!
Draw procedure isn't indented as it should; everything in a Sub block should be indented 1 level, so that this:Next noOfPlayers
End SubBecomes that:
Next noOfPlayers
End SubI like that you have lots of small functions - that's very good!
However
Draw could be further broken down; I'm removing the fluff to illustrate:Public Sub Draw()
For
For
While
For
'...
Next
Wend
Next
Next
End SubThat's 4 layers of nested loops! I've seen worse arrow code, but I'd extract a method out of the body of the 2nd
For loop, to make it look like this:Public Sub Draw()
For
For
ExtractedMethodCall
Next
Next
End SubOther than that, looks great!
Code Snippets
Next noOfPlayers
End SubNext noOfPlayers
End SubPublic Sub Draw()
For
For
While
For
'...
Next
Wend
Next
Next
End SubPublic Sub Draw()
For
For
ExtractedMethodCall
Next
Next
End SubContext
StackExchange Code Review Q#83684, answer score: 6
Revisions (0)
No revisions yet.