2014-01-06 66 views
1

VBA非常新。尝试搜索无济于事。我有以下代码:If/Else GoTo VBA Excel

monsterRollingForHit: rollForMonsterHit = (Int(2 * Rnd)) 
MsgBox rollForMonsterHit, 0, "Monster Hit Roll" 
If rollForMonsterHit = 1 Then 
    GoTo monsterRollingForDmg 
Else 
    GoTo playerRollingForHit 
End If 

'if monster hits we then roll for his base damage 
'using a working around for randBetween due to Analysis Toolpak being required for that  function 
monsterRollingForDmg: rollForMonsterDmg = ((Int((6 * Rnd) + 1))) 
MsgBox rollForMonsterDmg, 0, "Monster Dmg Roll" 
GoTo monsterRollingForCrit 

'we then add crit if the monster critically hits 
monsterRollingForCrit: rollForMonsterCrit = (rollForMonsterDmg + ((Int(2 * Rnd)) * 8)) 
MsgBox rollForMonsterCrit, 0, "Monster Crit Roll" 
GoTo rollingForPlayerArmor 

'finally we reduce the monster's dmg with potential crit by the player's armor 
rollingForPlayerArmor: finalMonsterDmg = (rollForMonsterCrit * (((Int((26 * Rnd) + 75))) /100)) 
MsgBox finalMonsterDmg, 0, "Monster Final Dmg" 
GoTo reducePlayerHealth 

reducePlayerHealth: currentPlayerHP = (currentPlayerHP - finalMonsterDmg) 
MsgBox currentPlayerHP, 0, "Current Player HP" 
If currentPlayerHP > 0 Then 
    GoTo playerRollingForHit 
Else 
    MsgBox "Monster Wins" 
    Exit Sub 
End If 

的问题是,即使在0 rollForMonsterHit值它永远不会去playerRollingForHit。相反,它只是滚动,直到获得1,然后继续。

问题:需要的方式来跳过一段代码为else条件

+1

那不是足够的代码,你需要证明其中monsterrollingfordmg和playerrollingforhit –

+0

增加了更多的代码 – augusthippo

+0

你的代码是一个烂摊子,你一定要知道如何转到工作的?尽量避免goto,我只在紧急情况下使用该行,但它总是更好的方式来做到这一点,我个人不喜欢它,因为它很难读取你的代码 –

回答

-1

试试这个:monsterRollingForHit: rollForMonsterHit = Application.WorksheetFunction.RoundDown(2 * Rnd(), 0)

1

Option Explicit使用有助于找出错字的变量名。

这将是您看起来尝试的psedo代码。也注意到没有转到或标签。

Set MonsterHP and HeroHP 
while monsterHP>0 and HeroHP>0 
    if MonsterHit then 
     work out monsterdmg 
     decide if critical 
     deduct from heroHP, accounting for any armor/dodge/etc 
    endif 
    if HeroHit then 
     work out HeroDmg 
     decide if critical 
     deduct from MonsterHP, accounting for any armor/dodge/etc 
    endif 
wend 
if monsterdmg>0 then 
    print "Monster Wins" 
elseif heroHP>0 then 
    print "Hero wins" 
else 
    print "They killed each other with their final blow!" 
endif 
+0

非常好的想法,以块格式显示程序流。我用它作为演示程序的输入;我想这两个答案之间,OP应该更好地了解如何创建这样的游戏。 – Floris

+0

@augusthippo,'while ... wend'是vba中的一个有效循环,但'do ...直到monsterHP <0或HeroHP <0'也会起作用 – SeanC

0

您没有定义标签playerRollingForHit ...至少在您要显示的代码中没有定义。这是个问题。

正如其他人所指出的,没有代码结构的想法是一个更大的问题。 A GoTo声明,而法律应谨慎使用。你应该考虑让你的代码更加可重用。例如,你可以创建自己的数据类型:

Public Type player 
    health As Integer 
    strength As Integer 
    ' whatever other properties you might have... 
End Type 

然后你就可以创建玩家的数组:

Dim players(1 To 2) as player 

这意味着你将能够遍历所有的球员,和“播放器1攻击玩家2“可以使用与”玩家2攻击玩家1“相同的代码(如果他们具有相同的规则)。同样,你可能想创建自己的函数“rollBetween”,它允许你用一个简单的指令滚动不同的骰子。

Function rollBetween(n1 As Integer, n2 As Integer) 
' roll a number between n1 and n2, inclusive 
rollBetween = Round(Rnd * (n2 - n1 + 1) - 0.5, 0) + n1 
End Function 

全部放在一起,为了好玩,我创造了一些代码,可以帮助你明白我在说什么。请注意 - 这里的规则与您使用的规则并不相同,但这是相同的原则;随着玩家获得更多力量,他们变得更加免疫攻击,并且他们的攻击变得更加强大。我希望你能从中学到一些东西,并为创造你的游戏而开心!

Option Explicit 

Public Type player 
    health As Integer 
    strength As Integer 
End Type 

Sub monsters() 
' main program loop 
' can have more than two players: just change dimension of array 
' and rules of "who attacks whom" 
Dim players(1 To 2) As player 
Dim attacker As Integer 
Dim defender As Integer 

initPlayers players 
attacker = rollBetween(1, 2) ' who goes first: player 1 or 2 
Debug.Print "Player " & attacker & " gets the first roll" 

While stillAlive(players) 
    defender = (attacker Mod 2) + 1 
    playTurn players, attacker, defender 
    attacker = defender ' person who was attacked becomes the attacker 
Wend 

MsgBox winner(players()) 

End Sub 

'------------------------------ 
' functions that support the main program loop 'monsters': 

Function rollBetween(n1 As Integer, n2 As Integer) 
' roll a number between n1 and n2, inclusive 
rollBetween = Round(Rnd * (n2 - n1 + 1) - 0.5, 0) + n1 
End Function 

Sub initPlayers(ByRef p() As player) 
' initialize the strength of the players etc 
Dim ii 
For ii = LBound(p) To UBound(p) 
    p(ii).health = 10 
    p(ii).strength = 1 
Next 

End Sub 

Function stillAlive(p() As player) As Boolean 
' see whether players are still alive 
' returns false if at least one player's health is less than 0 
Dim ii 
For ii = LBound(p) To UBound(p) 
    If p(ii).health <= 0 Then 
    stillAlive = False 
    Exit Function 
    End If 
Next ii 
stillAlive = True 
End Function 

Sub playTurn(ByRef p() As player, n As Integer, m As Integer) 
' attack of player(n) on player(m) 
Dim roll As Integer 

' see if you can attack, or just heal: 
roll = rollBetween(1, 2) 
Debug.Print "player " & n & " rolled a " & roll 

If roll = 1 Then 
    ' roll for damage 
    roll = rollBetween(1, 4 + p(n).strength) ' as he gets stronger, attacks become more damaging 
    Debug.Print "player " & n & " rolled a " & roll & " for attack" 
    If p(m).strength > roll Then 
    p(n).strength = p(n).strength - 1 ' attacker gets weaker because attack failed 
    p(m).strength = p(m).strength + 2 ' defender gets stronger 
    Else 
    p(n).strength = p(n).strength + 1 ' attacker gains strength 
    p(m).health = p(m).health - roll ' defender loses health 
    End If 
Else 
    ' roll for healing 
    roll = rollBetween(1, 3) 
    Debug.Print "player " & n & " rolled a " & roll & " for health" 
    p(n).health = p(n).health + roll 
End If 
Debug.Print "statistics now: " & p(1).health & "," & p(1).strength & ";" & p(2).health & "," & p(2).strength 

End Sub 

Function winner(p() As player) 
Dim ii, h, w 
' track player with higher health: 
h = 0 
w = 0 

For ii = LBound(p) To UBound(p) 
    If p(ii).health > h Then 
    w = ii 
    h = p(ii).health 
    End If 
Next ii 

winner = "Player " & w & " is the winner!" 

End Function 

一个典型的游戏的输出可能是:

Player 2 gets the first roll 
player 2 rolled a 2 
player 2 rolled a 2 for health 
statistics now: 10,1;12,1 
player 1 rolled a 1 
player 1 rolled a 2 for attack 
statistics now: 10,2;10,1 
player 2 rolled a 2 
player 2 rolled a 1 for health 
statistics now: 10,2;11,1 
player 1 rolled a 2 
player 1 rolled a 3 for health 
statistics now: 13,2;11,1 
player 2 rolled a 2 
player 2 rolled a 1 for health 
statistics now: 13,2;12,1 
player 1 rolled a 1 
player 1 rolled a 6 for attack 
statistics now: 13,3;6,1 
player 2 rolled a 2 
player 2 rolled a 2 for health 
statistics now: 13,3;8,1 
player 1 rolled a 2 
player 1 rolled a 3 for health 
statistics now: 16,3;8,1 
player 2 rolled a 1 
player 2 rolled a 5 for attack 
statistics now: 11,3;8,2 
player 1 rolled a 1 
player 1 rolled a 4 for attack 
statistics now: 11,4;4,2 
player 2 rolled a 2 
player 2 rolled a 1 for health 
statistics now: 11,4;5,2 
player 1 rolled a 2 
player 1 rolled a 2 for health 
statistics now: 13,4;5,2 
player 2 rolled a 1 
player 2 rolled a 4 for attack 
statistics now: 9,4;5,3 
player 1 rolled a 2 
player 1 rolled a 1 for health 
statistics now: 10,4;5,3 
player 2 rolled a 1 
player 2 rolled a 6 for attack 
statistics now: 4,4;5,4 
player 1 rolled a 2 
player 1 rolled a 2 for health 
statistics now: 6,4;5,4 
player 2 rolled a 2 
player 2 rolled a 3 for health 
statistics now: 6,4;8,4 
player 1 rolled a 1 
player 1 rolled a 6 for attack 
statistics now: 6,5;2,4 
player 2 rolled a 2 
player 2 rolled a 1 for health 
statistics now: 6,5;3,4 
player 1 rolled a 2 
player 1 rolled a 1 for health 
statistics now: 7,5;3,4 
player 2 rolled a 2 
player 2 rolled a 3 for health 
statistics now: 7,5;6,4 
player 1 rolled a 1 
player 1 rolled a 6 for attack 
statistics now: 7,6;0,4 

最终输出 - 声明球员1赢家消息框。

+0

[StillAlive()](https://www.youtube .com/watch?v = Y6ljFaKRTrI):) – SeanC

+1

您的某个功能的名称,'StillAlive'总是让我想起那首歌。显然这是一个有点太薄弱的链接 – SeanC

-3
For i = 1 To ActiveWorkbook.Worksheets.Count 
    If Worksheets(i).Name = "Table B" Or Worksheets(i).Name = "Table C" Then GoTo line1 
    If Worksheets(i).Name = "Table N" Then GoTo line3 
    If Worksheets(i).Name = "Table O" Then GoTo line2 
Next i 
+2

这是如何解决这个问题? – LordWilmore