这是一个tic tac toe发电机。仅限计算机与计算机,与通常的播放器与计算机略有不同。我为此编写了大部分代码,但我遇到的问题有时是在我生成游戏时,整个电路板都会填满,并且会出现一行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; }
}
}
答案 0 :(得分:3)
if (winning_line == 0 || winning_line > 1)
如果有两条线路,它将会拉开一条平局。如果你想在一条线路上停下来,你需要在每次搬家后检查一个胜利者,而不是在整个董事会被填满之后。
答案 1 :(得分:2)
第二个对角线获胜者检查应该是6而不是8。
您目前正在检查:
X O O
O X O
O O X
和:
O O X
O X O
O O X
显然最后的x应该在左边。
正如其他人发布的那样。制作两行不应该导致平局。一个玩家甚至可以单独制作两条线,造成平局 更改函数以在找到获胜行时立即返回结果,并在每次移动后检查它。
答案 2 :(得分:1)
这有效:你需要摆脱......
if(winning_line == 0 || winner_line&gt; 1)
用这三段代码替换那行代码:
if (winnerX == " X ")
{
theWinner = winnerX;
}
if (winnerO == " O ")
{
theWinner = winnerO;
}
if(winnerX == " X " && winnerO == " O ")
{
winnerT = " T ";
theWinner = winnerT;
}
所以我所做的就是改变一些事情。我没有使用“winner_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.然后我有winT字符串用于跟踪领带。它仅用于代替你的旧领带检查if语句的位置。
如果您决定使用字符串而不是整数,那么您还需要更改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;
}
答案 3 :(得分:0)
你认为你应该有一个给出一个网格的功能,一个新的棋子告诉你游戏是否结束了。 然后,如果游戏结束,你知道胜利者是最后一个玩家。
我认为Marthyi的开源项目MikMak有一个完美的实现,见
bool IsFinished(Grid currentState, Pawn newPawn)
在:
https://github.com/Marthyi/MikMak/blob/master/MikMakSolution/Morpion/MorpionManager.cs
祝你好运!