2013-03-07 41 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; 
     }