2013-03-07 33 views
6

這是一個井字趾發生器。只有計算機與計算機相比,通常的玩家與計算機有點不同。我的大部分代碼都是爲此編寫的,但是我遇到的問題有時是在生成遊戲時,整個板子會填滿,並且會出現一行X和一行O,它會以配合形式出現。有時候會有兩行X或兩行O,並且遊戲在連續3行之後不會停止...有什麼見解?謝謝。井字趾 - 檢測輸贏

namespace TicTacToe 
{ 
    public partial class Form1 : Form 
    { 
     private Random rn = new Random(); 

     const int SIZE = 9; 
     char[] cell = new char[SIZE]; 
     char firstPlayer = ' ', secondPlayer = ' '; 

     private void button1_Click(object sender, EventArgs e) 
     { 
      //Clear the labels and starting values 

      for (int i = 0; i < SIZE; i++) 
      { 
       cell[i] = ' '; 
      } 
      label10.Text = ""; 

      //Pick X or O to go first 
      switch (rn.Next(2)) 
      { 
       case 0: firstPlayer = 'O'; secondPlayer = 'X'; break; 
       case 1: firstPlayer = 'X'; secondPlayer = 'O'; break; 
      } 

      //Get five non-repeating numbers from 0 to 8 
      int[] positions = new int[5]; 
      positions[0] = rn.Next(9); 
      for (int i = 1; i < 5; i++) 
      { 
       int temp = rn.Next(9); 
       for (int j = 0; j < i; j++) 
       { 
        if (temp == positions[j]) 
        { 
         i--; 
         break; 
        } 
        else 
        { 
         positions[i] = temp; 
        } 
       } 
      } 

      //Set each position found to have first players letter 
      for (int i = 0; i < 5; i++) 
      { 
       cell[positions[i]] = firstPlayer; 
      } 

      for (int i = 0; i < SIZE; i++) 
      { 
       if (cell[i] != firstPlayer) 
       { 
        cell[i] = secondPlayer; 
       } 
      } 
      //Place cell values into the labels 
      label1.Text = cell[0].ToString(); 
      label2.Text = cell[1].ToString(); 
      label3.Text = cell[2].ToString(); 
      label4.Text = cell[3].ToString(); 
      label5.Text = cell[4].ToString(); 
      label6.Text = cell[5].ToString(); 
      label7.Text = cell[6].ToString(); 
      label8.Text = cell[7].ToString(); 
      label9.Text = cell[8].ToString(); 

      //Check for a winner 
      switch(checkWinner()) 
      { 
       case 'T' : label10.Text = "It's a tie!"; break; 
       case 'O' : label10.Text = "O Wins!"; break; 
       case 'X' : label10.Text = "X Wins!"; break; 
       default: label10.Text = "This will never appear"; break; 
      } 
     } 

     private char checkWinner() 
     { 
      //return either 'T' for tie, 'O' for O wins, and 'X' for X wins 
      char winner = ' '; 
      int winning_line = 0; 
      //check for a row win 
      if(cell[0].Equals(cell[1]) && cell[0].Equals(cell[2])) 
      { 
       winning_line++; 
       winner = cell[0]; 
      } 
      if (cell[3].Equals(cell[4]) && cell[3].Equals(cell[5])) 
      { 
       winning_line++; 
       winner = cell[3]; 
      } 
      if (cell[6].Equals(cell[7]) && cell[6].Equals(cell[8])) 
      { 
       winning_line++; 
       winner = cell[6]; 
      } 

      //check for column wins 
      if (cell[0].Equals(cell[3]) && cell[0].Equals(cell[6])) 
      { 
       winning_line++; 
       winner = cell[0]; 
      } 
      if (cell[1].Equals(cell[4]) && cell[1].Equals(cell[7])) 
      { 
       winning_line++; 
       winner = cell[1]; 
      } 
      if (cell[2].Equals(cell[5]) && cell[2].Equals(cell[8])) 
      { 
       winning_line++; 
       winner = cell[2]; 
      } 
      //check for diagonal winner 
      if (cell[0].Equals(cell[4]) && cell[0].Equals(cell[8])) 
      { 
       winning_line++; 
       winner = cell[0]; 
      } 
      if (cell[2].Equals(cell[4]) && cell[2].Equals(cell[8])) 
      { 
       winning_line++; 
       winner = cell[2]; 
      } 

      if (winning_line == 0 || winning_line > 1) 
      winner = 'T'; 

      return winner; 
     } 

     public int i { get; set; } 
    } 
} 
+3

你的對角線有一個bug,你檢查'0 == == 4 8' ,而且'2 == 4 == 8(而不是6)' – Nolonar 2013-03-07 09:21:17

+2

如果你想鍛鍊,我會考慮嘗試實現你的遊戲邏輯與你的用戶界面分開。你可以爲遊戲本身,玩家,每個獲勝規則等創建類。然後你可以更容易地玩AI和東西。只是一個建議,雖然... – Jobo 2013-03-07 09:34:58

+0

如果我可以的話,我會投JOBOO的評論。如果你創建了一個處理遊戲的類,你可以把它放在不同的UI中,例如一個用於計算機與電腦,另一個用於玩家vs玩家或玩家與電腦。 – SteveP 2013-03-08 09:04:52

回答

3
if (winning_line == 0 || winning_line > 1) 

如果有兩條線,它將r端口連接。如果您想在製作線路時停下來,您需要在每次移動後檢查贏家,而不是在整個板子填滿之後。

+0

是的,同樣如果您每次檢查符號時都檢查,您只需檢查最後放置的符號中的行。 – MrFox 2013-03-07 09:27:17

+0

@SteveP - 我在這方面很新穎,因爲這是我正在閱讀的書中推薦的初級練習。如果你可以進一步幫助我理解,只要檢查每個陳述後,它將不勝感激。我明白你的意思,只是把問題放在一起......謝謝。 – TomandGeriatric 2013-03-08 06:30:58

+0

基本上,爲了模擬一個真實的遊戲,你採取當前的位置,應用一個玩家移動它,然後檢查看看這個移動是否贏得了遊戲。您可以優化獲獎檢查,因爲任何獲勝的行必須包含剛剛完成的移動。 – SteveP 2013-03-08 09:01:58

2

第二斜冠軍支票應該是6,而不是8

您目前正在檢查:
XOO
OXO
OOX

和:
OOX
OXO
OOX

顯然最後一個x應該在左邊。

其他人發佈的附加信息。製作兩條線不應該導致配合。一名球員甚至可以單獨製造兩條線,造成一條領帶。
更改函數以便在找到獲勝的行時立即返回結果,並在每次移動後檢查結果。

+0

這是一個問題。但它不會解決他目前的問題。 – 2013-03-07 09:28:02

1

這工作:你需要擺脫...

如果(winning_line == 0 || winning_line> 1)

替換該行代碼與這三個片的代碼:

if (winnerX == " X ") 
    { 
     theWinner = winnerX; 
    } 
    if (winnerO == " O ") 
    { 
     theWinner = winnerO; 
    } 
    if(winnerX == " X " && winnerO == " O ") 
    { 
     winnerT = " T "; 
     theWinner = winnerT; 
    } 

所以我所做的就是改變一些事情。我沒有使用「winning_line ++」;一點代碼。相反,我爲每個if語句檢查都做了類似的事情。

if (cell[2, 0].Equals(cell[1, 1]) && cell[2, 0].Equals(cell[0, 2])) 
     { 
      if (cell[2, 0] == 0) 
      { 
       winnerX = " X "; 
      } 

      else if (cell[2, 0] == 1) 
      { 
       winnerO = " O "; 
      } 
     } 

所以,我有4個字符串,我使用,一個跟蹤如果X是有一個獲勝線,同爲O.然後我有贏家T字符串跟蹤領帶。它的唯一用來代替舊領帶檢查陳述的地方。

你還需要改變你的switch語句太多,如果你決定使用字符串而不是整數,即

switch (checkWinner()) 
     { 
      case " X ": 
       textBox1.Text = "X Wins!"; 
       break; 
      case " O ": 
       textBox1.Text = "O Wins!"; 
       break; 
      case " T ": 
       textBox1.Text = "It's a tie!"; 
       break; 
     }