C#在Tic Tac Toe编码领带

use*_*595 1 c# tic-tac-toe

我在C#中开发了一个tic tac toe游戏并设置了胜利条件的功能,但我似乎无法弄清楚如何在网格满时设置条件.当我尝试输入时,领带会随机出现.我想知道是不是我如何设置or和and运算符.这就是我尝试过的.

public bool Ended() 
{
    if (grid[0, 0] == 'X' && grid[0, 1] == 'X' && grid[0, 2] == 'X') {  Console.WriteLine("PLayer 1 Wins"); return true; }
    if (grid[1, 0] == 'X' && grid[1, 1] == 'X' && grid[1, 2] == 'X') {  Console.WriteLine("PLayer 1 Wins"); return true; }
    if (grid[2, 0] == 'X' && grid[2, 1] == 'X' && grid[2, 2] == 'X') {  Console.WriteLine("PLayer 1 Wins"); return true; }

    if (grid[0, 0] == 'X' && grid[1, 0] == 'X' && grid[2, 0] == 'X') {  Console.WriteLine("PLayer 1 Wins"); return true; }
    if (grid[0, 1] == 'X' && grid[1, 1] == 'X' && grid[2, 1] == 'X') {  Console.WriteLine("PLayer 1 Wins"); return true; }
    if (grid[0, 2] == 'X' && grid[1, 2] == 'X' && grid[2, 2] == 'X') {  Console.WriteLine("PLayer 1 Wins"); return true; }

    if (grid[0, 0] == 'X' && grid[1, 1] == 'X' && grid[2, 2] == 'X') {  Console.WriteLine("PLayer 1 Wins"); return true; }
    if (grid[0, 2] == 'X' && grid[1, 1] == 'X' && grid[2, 0] == 'X') {  Console.WriteLine("PLayer 1 Wins"); return true; }

    if (grid[0, 0] == 'O' && grid[0, 1] == 'O' && grid[0, 2] == 'O') { Console.WriteLine("PLayer 2 Wins"); return true; }
    if (grid[1, 0] == 'O' && grid[1, 1] == 'O' && grid[1, 2] == 'O') { Console.WriteLine("PLayer 2 Wins"); return true; }
    if (grid[2, 0] == 'O' && grid[2, 1] == 'O' && grid[2, 2] == 'O') { Console.WriteLine("PLayer 2 Wins"); return true; }

    if (grid[0, 0] == 'O' && grid[1, 0] == 'O' && grid[2, 0] == 'O') { Console.WriteLine("PLayer 2 Wins"); return true; }
    if (grid[0, 1] == 'O' && grid[1, 1] == 'O' && grid[2, 1] == 'O') { Console.WriteLine("PLayer 2 Wins"); return true; }
    if (grid[0, 2] == 'O' && grid[1, 2] == 'O' && grid[2, 2] == 'O') { Console.WriteLine("PLayer 2 Wins"); return true; }

    if (grid[0, 0] == 'O' && grid[1, 1] == 'O' && grid[2, 2] == 'O') { Console.WriteLine("PLayer 2 Wins"); return true; }
    if (grid[0, 2] == 'O' && grid[1, 1] == 'O' && grid[2, 0] == 'O') { Console.WriteLine("PLayer 2 Wins"); return true; }

    else if (grid[0, 0] == 'X' || grid[0, 0] == 'O' &&
        grid[0, 1] == 'X' || grid[0, 1] == 'O' &&
        grid[0, 2] == 'X' || grid[0, 2] == 'O' &&
        grid[1, 0] == 'X' || grid[1, 0] == 'O' &&
        grid[1, 1] == 'X' || grid[1, 1] == 'O' &&
        grid[1, 2] == 'X' || grid[1, 2] == 'O' &&
        grid[2, 0] == 'X' || grid[2, 0] == 'O' &&
        grid[2, 1] == 'X' || grid[2, 1] == 'O' &&
        grid[2, 2] == 'X' || grid[2, 2] == 'O')
    { Console.WriteLine("It's a Tie"); return true; }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

Eri*_*ert 15

根本问题在于程序的缩进与其含义不符.假设我写道:

int x =
   2 + 3 * 
   4 + 5;
Run Code Online (Sandbox Code Playgroud)

很容易认为这应该是5 x 9 = 45,但事实上它是2 + 12 + 5 = 19.

你做了同样的事情.

if (a || b &&
    c || d)
Run Code Online (Sandbox Code Playgroud)

手段

if (a || (b && c) || d)
Run Code Online (Sandbox Code Playgroud)

不是你想要的意思,这是什么意思

if ((a || b) && (c || d))
Run Code Online (Sandbox Code Playgroud)

您可能已经记住乘法优先于加法.您可以记住AND高于OR,因为AND与乘法相同!

true && true == true
true && false == false
false && true == false
false && false == false
Run Code Online (Sandbox Code Playgroud)

如果我们更换1真,假0,并&&*随后我们得到正确的陈述出来:

1 * 1 == 1
1 * 0 == 0
0 * 1 == 0
0 * 0 == 0
Run Code Online (Sandbox Code Playgroud)

现在让我们解决程序中的其他问题.

每当您发现两次或更多次编写相同的代码时,请考虑制作方法.剪切和粘贴是代码中的坏习惯.

if (grid[0, 0] == 'X' && grid[0, 1] == 'X' && grid[0, 2] == 'X') {  Console.WriteLine("PLayer 1 Wins"); return true; }
if (grid[1, 0] == 'X' && grid[1, 1] == 'X' && grid[1, 2] == 'X') {  Console.WriteLine("PLayer 1 Wins"); return true; }
if (grid[2, 0] == 'X' && grid[2, 1] == 'X' && grid[2, 2] == 'X') {  Console.WriteLine("PLayer 1 Wins"); return true; }
Run Code Online (Sandbox Code Playgroud)

我注意到你剪了一个错字!这又是它如此糟糕的另一个原因.

如果你发现你正在切割和粘贴,请制定一个方法:

private bool HasRow(char player, int row)
{
  return grid[row,0] == player && grid[row,1] == player && grid[row,2] == player;
}
Run Code Online (Sandbox Code Playgroud)

现在你可以用这个代码替换

if (HasRow('X', 0) || HasRow('X', 1) || HasRow('X', 2)) { ... }
...
if (HasRow('O', 0) || HasRow('O', 1) || HasRow('O', 2)) { ... }
Run Code Online (Sandbox Code Playgroud)

但是等等,我们再次剪切并粘贴代码.所以解决它!

private bool HasAnyRow(char player) 
{
  return HasRow(player, 0) || HasRow(player, 1) || HasRow(player, 2);
}
Run Code Online (Sandbox Code Playgroud)

现在你的代码变成了

if (HasAnyRow('X')) { ... }
...
if (HasAnyRow('O')) { ... }
...
Run Code Online (Sandbox Code Playgroud)

为列和对角线做同样的事情,你最终得到了

if (HasAnyRow('X') || HasAnyColumn('X') || HasAnyDiagonal('X')) { ... }
if (HasAnyRow('O') || HasAnyColumn('O') || HasAnyDiagonal('O')) { ... }
Run Code Online (Sandbox Code Playgroud)

但是等等,这仍然是太多的复制粘贴.

private bool HasWin(char player) 
{
  return HasAnyRow(player) || HasAnyColumn(player) || HasAnyDiagonal(player);
}
Run Code Online (Sandbox Code Playgroud)

现在代码是:

if (HasWin('X')) { ... }
if (HasWin('O')) { ... }
Run Code Online (Sandbox Code Playgroud)

您的代码将变得更好 - 更容易编写,更易于阅读,更容易调试,更有可能在第一次更正 - 如果您:

  • 通过制作辅助方法而不是复制粘贴代码来消除冗余代码.
  • 制作程序业务领域中的辅助方法.什么是井字游戏的胜利?有行,列或对角线.因此,请创建名为HasRow,HasColumn和HasDiagonal的方法,现在您可以更轻松地推断您的程序,因为它是使用程序业务领域中的概念编写的.