Results 1 to 3 of 3

Thread: Assertions, Assertions, Assertions - How much is too much?

  1. #1

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Assertions, Assertions, Assertions - How much is too much?

    PS. What I'm specifically asking about is when the same thing is being asserted multiple times as it gets passed from procedure to procedure.

    This is all in place and working very well, thank you.

    But as I review the code for the brazillionth time, I'm wondering about when an Assertion should be made.

    What is going on is Items. Specifically passing them around.

    I can make as many Item Pools (collection class) as I want.

    I have these Items classes:

    AllItems - Always holds all Items. This one is just an easy place to look up any item. It does nothing in the app except be a bag of everything.
    WildItems - these are the items you find in the wild when you dig a hole or explore a cave or whatever
    EquippedItems
    BackpackItems
    VendorItems

    AllItems withstanding, no item can be in two places at the same time so I have to be really careful about ensuring items are where I think they are.

    So lots of assertions.

    I can see three arguments about them.

    1) Assert as early as possible to skip out of code quickly if the assertion fails.

    2) Don't assert until it actually matters if the thing is true even if that means running a bunch of code I could have skipped if the assertion fails.

    3) Always assert everything even if that's less efficient. This is mostly the route I've taken.

    Also, Items can be randomly created in the game. These Items are always flagged as Destroy on Unequip.

    Thus you can buy it, store it, sell it, lose it, equip it. Once equipped you can use it forever until you take it off and then it's gone forever.

    Code:
    Public Function TryBuyItem(Optional ByRef ItemSlotID As ITEM_SLOT) As Long
    Dim m_Item As cItem
    
    Set m_Item = RandomItemSlotItem(ItemSlotID, VendorItems)
    
    BuyItemDialog ItemSlotID
    
    If CanBuyItem(m_Item) <> 1 Then Exit Function
    
    If ItemIsGift(m_Item) <> 1 Then
    
      If BuyItem(m_Item) <> 1 Then Exit Function
    
    End If
    
    EquipOrStoreNewItem m_Item, VendorItems
    
    TryBuyItem = 1
    
    End Function
    
    Private Property Get RandomItemSlotItem(ByRef ItemSlotID As ITEM_SLOT, ByRef Items As cItems) As cItem
    Dim m_Item As cItem
    Dim colTemp As Collection
    
    If Not ValidObject(Items) Then Exit Property
    
    If Items.Count = 0 Then Exit Property
    
    Set colTemp = New Collection
    
    For Each m_Item In Items
    
      With m_Item
    
        If .ItemSlot = ItemSlotID Then colTemp.Add m_Item
    
      End With
    
    Next m_Item
    
    If colTemp.Count = 0 Then Exit Property
    
    Set RandomItemSlotItem = colTemp(RollDie(colTemp.Count))
    
    End Property
    
    Private Sub EquipOrStoreNewItem(ByRef Item As cItem, ByRef FromItems As cItems)
    Dim m_EquippedItem As cItem
    
    If RollDie(d2) = 1 Or Not CanEquipItem(Item) Then  ' Store Item in the Backpack.
    
      TransferItem Item, FromItems, BackpackItems
    
    Else ' Equip Item.
    
      Set m_EquippedItem = EquippedItem(Item.ItemSlot)
    
      TransferItem m_EquippedItem, EquippedItems, BackpackItems
    
      TransferItem Item, FromItems, EquippedItems
    
    End If
    
    Public Function TransferItem(ByRef Item As cItem, ByRef FromItems As cItems, ByRef ToItems As cItems) As Long
    
    If Not ValidObject(Item) Then Exit Function
    If Not ValidObject(FromItems) Then Exit Function
    If Not ValidObject(ToItems) Then Exit Function
    
    If ToItems Is EquippedItems Then
    
      If Not CanEquipItem(Item) Then Exit Function
    
    End If
    
    FromItems.Remove Item
    
    If (FromItems Is EquippedItems) And (Item.DestroyOnUnequip = vbChecked) Then
    
      ' Do nothing. All the Item's stats are destroyed with the Item.
      ' It is safe to keep it in AllItems as Items are never drawn from it.
      ' The downside is that AllItems will end up with tens of thousands of Items in it that aren't doing anything.
    
      ' Or... go ahead and destroy it. Screw stats.
    
      'AllItems.Remove Item
    
      'Set Item = Nothing
    
    Else
    
      ToItems.Add Item
    
    End If
    
    TransferItem = 1
    
    End Function
    
    Private Function CanBuyItem(ByRef Item As cItem) As Long
    Dim nLevelDifference As Long
    Dim nRemainingBalance As Long
    
    If VendorItems.Count = 0 Then Exit Function
    
    If Not ValidObject(Item) Then
    
      ItemNotAvailable
    
      Exit Function
    
    End If
    
    nRemainingBalance = (McGuffin.Count - Item.Value - MIN_MCGUFFINS_TO_ACTIVATE_MULTIPLIERS)
    
    If nRemainingBalance < 0 Then
    
      AddMessage AddAsterisks("You can't afford a " & Item.Name & " (" & -Item.Value & ")."), vbTab, 0, idx_PlayerMessage_Primary
    
      Exit Function
    
    End If
    
    nLevelDifference = Item.LevelRequirement - Player.Level
    
    If nLevelDifference > 0 Then
    
      If RollFor("Buy Deck-Requirement-Not-Met Item", nLevelDifference, idx_PlayerMessage_Notification) <> nLevelDifference Then
    
        AddMessage AddAsterisks("You Have Not Reached the Deck " & Item.LevelRequirement & " Requirement to Equip a " & Item.Name & "."), vbTab, 0, idx_PlayerMessage_Primary
    
        Exit Function
    
      End If
    
    End If
    
    CanBuyItem = 1
    
    End Function
    Last edited by cafeenman; Apr 30th, 2025 at 09:26 PM.

  2. #2

    Thread Starter
    PowerPoster cafeenman's Avatar
    Join Date
    Mar 2002
    Location
    Florida
    Posts
    2,819

    Re: Assertions, Assertions, Assertions - How much is too much?

    Man do I need to learn to comment my code.

    I just spent too many minutes trying to remember what this does:

    Code:
    nLevelDifference = Item.LevelRequirement - Player.Level
    
    If nLevelDifference > 0 Then
    
      If RollFor("Buy Deck-Requirement-Not-Met Item", nLevelDifference, idx_PlayerMessage_Notification) <> nLevelDifference Then
    
        AddMessage AddAsterisks("You Have Not Reached the Deck " & Item.LevelRequirement & " Requirement to Equip a " & Item.Name & "."), vbTab, 0, idx_PlayerMessage_Primary
    
        Exit Function
    
      End If
    
    End If
    You *can* purchase any item if you have the funds even if the level requirement is much higher than your current level.

    The number of Die Sides is the difference in the level requirement from your level.

    Thus it is less probable to roll a high-level item. For example, if the item is 20 levels higher then you have to roll a 20 on a D20 to get it.

    You will never fail a roll that is one level higher than your level or less because rolling a D1 will always return 1.

    That's what it does.

    I should write this in the code now so I don't have to read the code next time.

    That is all.
    Last edited by cafeenman; Apr 30th, 2025 at 09:47 PM.

  3. #3
    Fanatic Member
    Join Date
    Feb 2019
    Posts
    924

    Re: Assertions, Assertions, Assertions - How much is too much?

    For a while I thought you were talking about Debug.Assert, but it seems that you are not.

    Validation checks are better put inside functions(as you may have discovered, like IsValid()) because you can forget some of the rules. For example, if you always need to check for a flag and a counter each time you access an array element, you will forget that rule a year later, and introduce bugs. A function checks all the rules. Yes, it may slow things down but a reliable code is better than fast buggy code.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width