【问题标题】:Tic-Tac-Toe Determine winner [duplicate]井字游戏确定获胜者[重复]
【发布时间】:2013-02-11 00:36:31
【问题描述】:
     public void CheckWin()
  {
     if (spillebræt[0, 0] == 'X' && spillebræt[1, 0] == 'X' && spillebræt[2, 0] == 'X')
     {
        Console.WriteLine("Player 1 wins!\nPress ENTER to end game");
        Console.ReadLine();
        Environment.Exit(0);
     }
  } 

Spillebræt = 游戏板。我正在尝试创建一种方法来确定基于控制台的简单井字游戏的获胜者。对于游戏板,我有一个二维字符数组,最初用“+”符号填充。玩家等级在 2 个玩家轮次之间切换,每次检查是否找到了获胜者。我想我可以使用很多 if 语句来确定获胜者,因为有 8 种可能的解决方案,但我正在寻找一种使用更少行空间的方法。上面的代码显示了我的初始方法(通过 if 语句检查每个可能的解决方案)。

【问题讨论】:

  • 虽然有 16 种可能的解决方案采用这种格式,但您也需要考虑 'O'
  • 您必须使用 if 语句设置所有可能的获胜组合
  • @Shaharyar 我不这么认为。还有其他选择。
  • @AndrewMao 我会说这确实是重复的。
  • @OscarMederos 我的意思是他必须定义所有组合,他不必使用 if 语句。

标签: c# arrays console char


【解决方案1】:

您可以有一个包含所有获胜案例的矩阵,并检查当前状态是否为获胜状态:

        // Example
        var matrix = new[,] { { "O", "+", "+" }, { "O", "+", "+" }, { "O", "+", "+" } };

        var wins = new List<string> {
             "100100100", // 1st column vertical
             "010010010", // 2nd column vertical
             "001001001", // 3rd column vertical
             "111000000", // 1st row horizontal
             "000111000", // 2nd row horizontal
             "000000111", // 3rd row horizontal
             "100010001", // top-left bottom-right diagonal
             "001010100"  // top-right bottom-left diagonal
            };

        // Crosses (X)
        var check = new List<string> {"0", "0", "0", "0", "0", "0", "0", "0", "0"};
        for (var i = 0; i < 3; i++)
            for (var j = 0; j < 3; j++)
                if (matrix[i, j] == "X") check[i*3 + j] = "1";
        if (wins.Contains(string.Join("", check))) { /* crosses win */ }

        // Circles (O)
        check = new List<string> { "0", "0", "0", "0", "0", "0", "0", "0", "0" };
        for (var i = 0; i < 3; i++)
            for (var j = 0; j < 3; j++)
                if (matrix[i, j] == "O") check[i * 3 + j] = "1";
        if (wins.Contains(string.Join("", check))) { /* circles win */ }

【讨论】:

    【解决方案2】:

    您总是可以编写所有不同的案例,但它很麻烦,并且无法扩展(如果您想扩展板怎么办?)。

    所以我会建议一个更复杂的实现作为练习。

    您创建了一个Line 类,具有起点和终点。您还可以在Line 上实现一个移动到下一行 运算符,它会旋转它。然后,您可以通过按照简单的规则移动起点和终点来简单地循环遍历所有行。

    然后,你在你的棋盘上创建一个运算符,让你应用一条线到棋盘,如果这条线的路径上的每个棋盘格都具有相同的符号,则返回 true。 p>

    这样,您可以通过以下方式简单地检查棋盘位置是否为获胜位置:

    for (Line l = new Line() ; l.Valid() ; l.MoveToNextLine())
    {
        if (board.WinningLine(l))
            return true;
    }
    return false;
    

    当然,您可以根据需要进行自定义,例如将MoveToNextLine 替换为operator ++ 等。您的线路上应该有一个end 状态,这样您就可以跳出循环而不是一遍又一遍地继续。

    MoveToNextLine 将只是根据您决定的顺序在您的起点和终点移动。

    现在您可以看到,如果您想在n x n 板上扩展您的游戏,这将非常容易:您只需更新MoveToNextLine

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多