2013-10-04 182 views
3

我一直在用C#編寫文本冒險遊戲。我想做一個場景,你遇到一個寵物小精靈。我想有3個隨機口袋妖怪可以遇到,並且我製作了一個返回你找到的寵物小精靈名字的方法。代碼是:返回if語句

public string choosePokemon() 
{ 
    Random random = new Random(); 
    int pokemonChosen = random.Next(); 
    if (pokemonChosen == 1) 
    { 
     string pokemon = "Pidgey"; 
     return pokemon; 
    } 
    if (pokemonChosen == 2) 
    { 
     string pokemon = "Charmander"; 
     return pokemon; 
    } 
    if (pokemonChosen == 3) 
    { 
     string pokemon = "Geodude"; 
     return pokemon; 
    } 
    return "missingno"; 
} 

每當我執行代碼它說:「你遇到一個失蹤!」。我希望它返回名稱並打破方法,返回到場景的方法。我在末尾放了一個return "missingno";,因爲Studio會給我一個錯誤,那就是不是所有的代碼路徑都返回一個值。

+2

你認爲'random.Next();'可以產生什麼數字?編輯:好的,你編輯了沒有參數的'Next()'調用。 –

+1

除了下面幾乎可以解釋這個問題的所有答案之外,每次調用該方法時,您可能都不應該創建一個Random的新實例 – SpaceghostAli

+0

您每次調用時都會重新創建隨機類,它將以相同的種子開始並重新開始。所以它會一直返回相同的順序,但只能選擇第一個。 (請參閱我的回答) –

回答

5

讓我們從Random號碼發生器開始。爲了有效,你只應該實例化一次Random。要做到這一點,你可以爲這個類製作一個靜態實例。如果您不這樣做,每次撥打random.Next()時可能會得到相同的號碼。

public class PokemonChooser 
{ 
    private static Random random = new Random(); 

    public static string ChoosePokemon() { ... } 
} 

然後,我們需要認識到,random.Next()返回任何非負integer價值,不只是你想要的人。所以,我們需要對結果進行四捨五入以適合您的情況。由於您有3個要隨機選擇的項目,因此我們可以使用模數運算符(%)對其進行四捨五入,這基本上爲您提供除法操作的剩餘部分(/)。例如:(int)(5/2) == 25 % 2 == 1

var pokemonChosen = random.Next() % 3;

其次,由於這個結果是從零開始,我們需要考慮的是,在if語句。

 if (pokemonChosen == 0) 
     { 
     string pokemon = "Pidgey"; 
     return pokemon; 
     } 

     if (pokemonChosen == 1) 
     { 
     string pokemon = "Charmander"; 
     return pokemon; 
     } 

     if (pokemonChosen == 2) 
     { 
     string pokemon = "Geodude"; 
     return pokemon; 
     } 

由於口袋妖怪的名字是很明顯的,我們可以擺脫pokemon變量,而不會丟失任何可讀性。

 if (pokemonChosen == 0) 
     { 
     return "Pidgey"; 
     } 

     if (pokemonChosen == 1) 
     { 
     return "Charmander"; 
     } 

     if (pokemonChosen == 2) 
     { 
     return "Geodude"; 
     } 

我們可以可能使通過使用case語句而不是多個if聲明本更清晰和更短。

 switch (pokemonChosen) { 
     case (0): return "Pidgey"; 
     case (1): return "Charmander"; 
     case (2): return "Geodude"; 
     } 

而且,由於我們簡單地返回"missingno"如果我們不能找到數口袋妖怪,我們可以使用一個默認的情況下:

 switch (pokemonChosen) { 
     case (0): return "Pidgey"; 
     case (1): return "Charmander"; 
     case (2): return "Geodude"; 
     default: return "missingno"; 
     } 

總而言之,我們最終得到:

public class PokemonChooser 
{ 
    private static Random random = new Random(); 

    public static string ChoosePokemon() 
    { 
     var pokemonChosen = random.Next() % 3; 

     switch (pokemonChosen) { 
     case (0): return "Pidgey"; 
     case (1): return "Charmander"; 
     case (2): return "Geodude"; 
     default: return "missingno"; 
     } 
    } 
} 

而我們這樣使用它:

var pokemon = PokemonChooser.ChoosePokemon();

但是,您可能希望選擇比中的3更高的數字,否則,將永遠不會返回"missingno"

+0

不要使用模操作來限制返回隨機整數的函數的輸出,因爲這樣做會使可能出現的最大數目減少(在這種情況下,'random.Next()%3'不太可能返回2比1和0)。你應該將'random.Next()/ 2147483647.0'乘以3,然後使用'Math.Floor()'將結果向下滾動。 – dorukayhan

+0

從技術上講,你是對的。但是,這個答案主要是爲了證明原始代碼是* range *錯誤的錯誤。增加多餘的數學可能會分散OP對潛在問題的理解,IMO。如果關於隨機數的公平性和準確性的問題,使用'random.Next()%n'會是一個非常糟糕的主意。 –

3

你需要指定隨機值範圍:

int pokemonChosen = random.Next(3) + 1; 

否則,值的範圍是高達Int32.MaxValue,它給你約一在十億次的機會被1-4之間。

+0

我發佈了一分鐘後,我明白了我的錯誤,非常感謝! – Ilan321

10

Random.Next()(不帶參數)將返回一個隨機的非負整數。你可能意味着它限制在一定的範圍內,這樣的:

int pokemonChosen = random.Next(1, 4); 

另外請注意,您可以通過只返回一個恆定的if - 塊內像這樣使你的代碼有點清潔:

if (pokemonChosen == 1) 
{ 
    return "Pidgey"; 
} 

甚至更​​好,將你的隨機選項封裝在一個數組中。這樣,你可以擺脫你的所有if完全-blocks的:

var options = new [] { "Pidgey", "Charmander", "Geodude" }; 
int pokemonChosen = random.Next(options.Length); // array indexes start at 0 
return options[pokemonChosen]; 
+0

@韓庚是好點。 –

10

的問題是,你的random.Next()通話中的任意範圍內的任何返回號碼 - 你需要random.Next的替代版本()只返回1,2或3,或者你需要自己執行。嘗試這樣做代替:int pokemonChosen = random.Next(1, 4)(下界是包容性,而上限是獨佔的)

3

Random.next()將返回(= Integer.MaxValue)0和2147483647之間的值,以便你的數爲1,2或3的機會很苗條,這就是它通常返回最後一個值的方式。您需要限制值:

random.Next(1, 4); 
4

你需要指定上限random.Next()

int pokemonChosen = random.Next(4); 

將範圍返回一個整數0 - 3

使其返回1-4你可以使用:

int pokemonChosen = random.Next(1, 5); 
3

不應該在每次調用時重新創建隨機類。並調用它像:_random.Next(3) + 1

Random _random = new Random(); 

public string choosePokemon() 
{ 
    int pokemonChosen = _random.Next(3) + 1; 
    if (pokemonChosen == 1) 
    { 
     string pokemon = "Pidgey"; 
     return pokemon; 
    } 
    if (pokemonChosen == 2) 
    { 
     string pokemon = "Charmander"; 
     return pokemon; 
    } 
    if (pokemonChosen == 3) 
    { 
     string pokemon = "Geodude"; 
     return pokemon; 
    } 
    return "missingno"; 
} 
2

你流汗以外的值比1, 2, or 3,調試和檢查什麼的pokemonChosen值。您可能希望限制您的隨機val的最大值爲3

int pokemonChosen = random.Next(4); 
2

測試,你的代碼工作正常 - 不知道你實際使用什麼樣的代碼,你有總是準確的方法正常工作。 但是,您應將其更改爲

int pokemonChosen = random.Next(1, 4); 

UPD:哎,路要走改變你原來的問題那行,當我打開它,你有INT pokemonChosen = random.Next(1,3);在那裏...

+0

是的,我編輯它,因爲它有一個錯誤,然後我意識到/是/錯誤。對不起,它現在回來了。 – Ilan321

9

一個很好的方法來做到這一點,正如我通過試用我自己的基於口袋妖怪的遊戲所發現的,將New Random()放在功能之外。此外,你可以在函數外面實例化字符串,以防萬一你有不同的口袋妖怪選項用於遊戲的不同部分。這樣,你不必返回任何東西,只需調用該函數,然後使用字符串。假設你正在做一個基於故事輸出標籤的窗口:

Random random = new Random(); 
string pokemon; 

    public void choosePokemon() 
    { 
     int pokemonChosen = random.Next(2); 
     if (pokemonChosen == 0) { 
     pokemon = "Pidgey"; 
     } 
     if (pokemonChosen == 1) { 
     pokemon = "Charmander"; 
     } 
     if (pokemonChosen == 2) { 
     pokemon = "Geodude"; 
     } 
    } 

    lblStory.Text += "You encountered a wild " + pokemon + "!"; 

我做了一件非常類似於我爲朋友做的遊戲。

編輯:此外,我在我的遊戲中做的其他事情是縮短pkmn的變量名稱中的寵物小精靈。輸入較短,並且通過主遊戲看到,通常被接受。不是說玩家會閱讀你的代碼。