HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Follow-up: Randomizing Civilization 5 team choice

Submitted by: @import:stackexchange-codereview··
0
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

Solution

Your indentation is generally fine, except the Draw procedure isn't indented as it should; everything in a Sub block should be indented 1 level, so that this:

Next noOfPlayers
End Sub


Becomes that:

Next noOfPlayers
End Sub


I 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 Sub


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 For loop, to make it look like this:

Public Sub Draw()
    For
        For
            ExtractedMethodCall
        Next
    Next
End Sub


Other than that, looks great!

Code Snippets

Next noOfPlayers
End Sub
Next noOfPlayers
End Sub
Public Sub Draw()
    For
        For
            While
                For
                    '...
                Next
            Wend
        Next
    Next
End Sub
Public Sub Draw()
    For
        For
            ExtractedMethodCall
        Next
    Next
End Sub

Context

StackExchange Code Review Q#83684, answer score: 6

Revisions (0)

No revisions yet.