2014-01-06 89 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