2016-08-16 179 views
2

我對C#很有新意(一週前開始學習它),在批處理和表達式2方面有一些經驗,並且我一直在嘗試基於文本的遊戲,學到更多。起初我使用了goto語句,但根據我發現的幾乎所有人,goto語句都是一些死亡和絕望的混合物,所以我想學習更清潔,更少的邪惡方法來達到同樣的效果。下面是我做證明我是什麼意思一個糟糕的示例腳本:goto語句的替代方法

using System; 

namespace TestScript 
{ 
class Program 
{ 
    public static void Main(string[] args) 
    { 
     string ConsoleReadinator; 
     string ConsoleReadinator2; 
     int Go = 0; 

    mainmenu: 
     do 
     { 
      Go = 0; 
      Console.Clear(); 
      Console.WriteLine("Main Menu:"); 
      Console.WriteLine("Store or something"); 
      ConsoleReadinator = Console.ReadLine().ToUpper(); 
      if (ConsoleReadinator == "STORE") { Go = 1; } 
     } while (Go == 0); 

     // In-game store example 

     { 
      Go = 0; 
      do 
      { 
       Console.Clear(); 
       Console.WriteLine("In-game store I guess"); 
       Console.WriteLine("Stuff you can buy, etc"); 
       ConsoleReadinator2 = Console.ReadLine().ToUpper(); 
       if (ConsoleReadinator2 == "GO") { Go = 1; } 
      } while (Go == 0); 
      goto mainmenu; 
     } 
    } 
    } 
} 

這個腳本是功能性的,但我想,以避免使用goto的一種方式回到以前的聲明,以瀏覽菜單並可能重複基於回合的遊戲的算法。我在Alternative to using goto statement in C#(這基本上與我的問題基本相同,除了更模糊一些)之外,我已閱讀了有關使用此方法的內容,但Greg做出的示例根本不適用於我,因此可能不值得嘗試使這個特定的例子有效。

+1

我認爲這個問題是一個更合適的網站是一個網站http://codereview.stackexchange.com/ – BWA

+1

是啊,不要使用goto語句,永遠 – Liam

+0

@Liam該帖子的全部內容是不使用goto聲明,永遠。 –

回答

0

您可以使用遞歸返回並再次執行代碼。爲此,你可以在你的代碼移到一個單獨的方法,並從它裏面調用它時,它是必要的:

class Program 
{ 
    public static void Main(string[] args) 
    { 
     string ConsoleReadinator; 
     string ConsoleReadinator2; 
     Method(0); 
    } 

    private static void Method(int Go) 
    {  
     do 
     { 
      .. 
     } while (Go == 0); 

     // In-game store example 

     do 
     { 
      ... 
     } while (Go == 0); 
     Method(Go); 
    } 
} 

或者你可以在更合適的方式來使用循環。讓我們看一下例子,當我們希望用戶輸入整數:

public static void Main(string[] args) 
    { 
     int num; 

     // This loop ends only when user enters proper integer number 
     do 
     { 
      Console.Clear(); 
      Console.Write("Please enter some integer number: "); 
     } while(!int.TryParse(Console.ReadLine(), out num));      
    } 

可以這樣做遞歸其他方式:

public static int EnterNumber() 
    { 
     Console.Clear(); 
     Console.Write("Please enter some integer number: "); 

     // if number is successfully parsed return number else run method again 
     return int.TryParse(Console.ReadLine(), out num)? 
        num : EnterNumber(); 
    } 

    public static void Main(string[] args) 
    { 
     int num = EnterNumber(); 
    } 

當我們可以使用的方法,循環和遞歸沒有實際上需要使用GO TO了。

-1

通常您使用方法或lambda表達式。因此,您的mainmenu將成爲您在代碼結尾再次調用的方法。

3

至於我可以看到你想要的無限循環

... 
    while (true) 
    { 
     do 
     { 
     ... 
     } while (Go == 0); 

     Go = 0; 

     do 
     { 
     ... 
     } while (Go == 0); 
    } 
+0

幾分鐘前,我評論了這一點,並說它行得通,而且它也適用於這個例子,但我忽略了提及將會有多種選擇;不只是一家商店。如果我像這樣使用了一個無限循環,我想我必須遍歷每個菜單,除非可能使用了很多循環。 –

+0

@Rowan Tarshis:爲什麼不添加另一個菜單項,*退出*,只是調用'break;'(只留下無限循環)或'return;'(離開Main函數,因此程序)? –

+0

我不確定你的意思。通過「另一個菜單項」,你是指另一個菜單,如商店,還是別的?此外,通過「剛纔調用break的exit」(上面只留下無限循環),「你的意思是它會'break',進入第二個無限循環,還是我誤解了這一點? –

0

一個建議是使用一個開關的情況下構建這樣的:

static void Main(string[] args) 
{ 
    string ConsoleReadinator; 
    string MENU_TEXT = "Main Menu:"; 
    string ADDITIONAL_INFO = "Store or something"; 

    bool endProg = false; 


    ConsoleReadinator = printMenu(MENU_TEXT, ADDITIONAL_INFO); 

    // as long "EXIT" is not typed 
    while (!endProg) 
    { 

     switch (ConsoleReadinator) 
     { 
      case "STORE": 
       // Do your Store Stuff 
       // maybe change MENU_TEXT and ADDITIONAL_INFO 
       // and print a new Menu 
       ConsoleReadinator = printMenu(MENU_TEXT, ADDITIONAL_INFO); 
       break; 
      case "GO": 
       // Do your Go Stuff 
       break; 
      case "EXIT": 
       endProg = true; // set exit condition to true 
       break; 

      default:       
       break; 
     } 
    } 

    Console.ReadKey(); 
} 

// one Method to use for Menu display 
public static string printMenu(string menuText, string additionalInfo) 
{ 
    Console.Clear(); 
    Console.WriteLine(menuText); 
    Console.WriteLine(additionalInfo); 

    return Console.ReadLine().ToUpper(); 

}