C# 什么';这项简单的技巧练习的最佳方法是什么?

C# 什么';这项简单的技巧练习的最佳方法是什么?,c#,tic-tac-toe,C#,Tic Tac Toe,到目前为止一切都正常,我只需要创建一个方法来检查是否有人赢了 有没有关于如何有效解决这个问题的建议 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace TresE

到目前为止一切都正常,我只需要创建一个方法来检查是否有人赢了

有没有关于如何有效解决这个问题的建议

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TresEnRaya
{
    public partial class Form1 : Form
    {
        string[,] tablero;
        bool jugador = true;

        public Form1()
        {
            InitializeComponent();
            AsignarTags();
            tablero = new string[3, 3];

            button1.Click += clickHandler;
            button2.Click += clickHandler;
            button3.Click += clickHandler;
            button4.Click += clickHandler;
            button5.Click += clickHandler;
            button6.Click += clickHandler;
            button7.Click += clickHandler;
            button8.Click += clickHandler;
            button9.Click += clickHandler;
        }

        private void AsignarTags()
        {
            button1.Tag = new Posicion() { X = 0, Y = 0 };
            button2.Tag = new Posicion() { X = 0, Y = 1 };
            button3.Tag = new Posicion() { X = 0, Y = 2 };
            button4.Tag = new Posicion() { X = 1, Y = 0 };
            button5.Tag = new Posicion() { X = 1, Y = 1 };
            button6.Tag = new Posicion() { X = 1, Y = 2 };
            button7.Tag = new Posicion() { X = 2, Y = 0 };
            button8.Tag = new Posicion() { X = 2, Y = 1 };
            button9.Tag = new Posicion() { X = 2, Y = 2 };
        }

        private void CambiarSimbolo(Button button)
        {
            Posicion objPosicion = (Posicion)button.Tag;

            if (jugador == true)
            {
                tablero[objPosicion.X, objPosicion.Y] = "X";
                button.Text = "X";
                button.Enabled = false;
                jugador = false;
            }
            else
            {
                tablero[objPosicion.X, objPosicion.Y] = "Y";
                button.Text = "Y";
                button.Enabled = false;
                jugador = true;
            }

            VerificarGanador();
        }

        private void VerificarGanador()
        {
            //THE MAGIC GOES HERE. WINGARDIUM LEVIO-Sah
        }

        private void clickHandler(object sender, EventArgs e)
        {
            Button myButton = (Button)sender;
            switch (myButton.Name)
            {
                case "button1":
                    CambiarSimbolo(myButton);                    
                    break;

                case "button2":
                    CambiarSimbolo(myButton);
                    break;

                case "button3":
                    CambiarSimbolo(myButton);
                    break;

                case "button4":
                    CambiarSimbolo(myButton);
                    break;

                case "button5":
                    CambiarSimbolo(myButton);
                    break;

                case "button6":
                    CambiarSimbolo(myButton);
                    break;

                case "button7":
                    CambiarSimbolo(myButton);
                    break;

                case "button8":
                    CambiarSimbolo(myButton);
                    break;

                case "button9":
                    CambiarSimbolo(myButton);
                    break;
            }
        }        
    }
}

感谢您的帮助。

好吧,只有8种可能的获胜组合,您只需对照代表获胜位置的一组模板检查每种组合

回想起来,我实际上会将您的数据结构修改为一个由数字而不是字符串组成的MD数组,其中包括:

0=>空白单元格
1=>玩家A(X)
-1=>玩家B(O)


然后,您可以查看任何行、列或对角线上的总和是否等于+3或-3。

好吧,只有8种可能的获胜组合,您只需对照代表获胜位置的一组模板检查它们中的每一种

回想起来,我实际上会将您的数据结构修改为一个由数字而不是字符串组成的MD数组,其中包括:

0=>空白单元格
1=>玩家A(X)
-1=>玩家B(O)


然后,您可以查看任何行、列或对角线上的总和是否等于+3或-3。

对于3x3,我将强制它。肯定会有更好的答案,但只有8个获胜条件(vert1、vert2、vert3、horiz1、horiz2、horiz3、左上交叉、左下交叉)


对于3x3,我会使用蛮力。肯定会有更好的答案,但只有8个获胜条件(vert1、vert2、vert3、horiz1、horiz2、horiz3、左上交叉、左下交叉)

这个怎么样

Button[][] matrix = new[]
{
    new []{ button1, button2, button3 },
    new []{ button4, button5, button6 },
    new []{ button7, button8, button9 },
    new []{ button1, button5, button9 },
    new []{ button3, button5, button7 },
    new []{ button1, button4, button7 },
    new []{ button2, button5, button8 },
    new []{ button3, button6, button9 }
};
var result = matrix.FirstOrDefault(set => 
    set.All(button => button.Text == "X") || 
    set.All(button => button.Text == "Y"));
if(result != null)
{
    string winner = result.First().Text;
}
else
{
    // tie
}
这个怎么样

Button[][] matrix = new[]
{
    new []{ button1, button2, button3 },
    new []{ button4, button5, button6 },
    new []{ button7, button8, button9 },
    new []{ button1, button5, button9 },
    new []{ button3, button5, button7 },
    new []{ button1, button4, button7 },
    new []{ button2, button5, button8 },
    new []{ button3, button6, button9 }
};
var result = matrix.FirstOrDefault(set => 
    set.All(button => button.Text == "X") || 
    set.All(button => button.Text == "Y"));
if(result != null)
{
    string winner = result.First().Text;
}
else
{
    // tie
}

最有效的方法是知道板上最后一个X或O的位置,并只检查包含该位置的方向。这样,你就不会用蛮力来判断一个玩家是否赢了。

最有效的方法是知道棋盘上最后一个X或O的位置,并且只检查包含该位置的方向。这样,你就不会用蛮力来判断一个玩家是否赢了。

正如其他人所说,蛮力是好的

然而,我更喜欢列出节点,而不是像@Kendrick那样循环它们

例如:

TicTacVector winVectors[] = 
{
    {"Top Row",    {0,0}, {0,1}, {0,2}},
    {"Middle Row", {1,0}, {1,1}, {1,2}},
    [...]
    {"Diagonal 1", {0,2}, {1,1}, {2,0}}
};   
(注意:伪代码。实际上不会编译!)


手工编码的强度更高一些,但我认为它也更容易看到发生了什么。

正如其他人所说,暴力是好的

然而,我更喜欢列出节点,而不是像@Kendrick那样循环它们

例如:

TicTacVector winVectors[] = 
{
    {"Top Row",    {0,0}, {0,1}, {0,2}},
    {"Middle Row", {1,0}, {1,1}, {1,2}},
    [...]
    {"Diagonal 1", {0,2}, {1,1}, {2,0}}
};   
(注意:伪代码。实际上不会编译!)


手动编码的强度更高一些,但我认为也更容易看到发生了什么。

穷举搜索。

穷举搜索。

我曾经看到一种技术,它保留了8个不同的计数器,每个中奖方向一个

将计数器初始化为零。
放置X时,在该行、列和对角线的计数器中添加1。
放置O时,从行、列和对角线的计数器中减去1

如果任何计数器达到3或-3,您就知道您有赢家。
+3表示X获胜。
-3表示O获胜。


哪个计数器达到+/-3表示哪个行/列/对角线获胜。

我曾经看到一种技术,它保留了8个不同的计数器,每个获胜方向一个计数器

将计数器初始化为零。
放置X时,在该行、列和对角线的计数器中添加1。
放置O时,从行、列和对角线的计数器中减去1

如果任何计数器达到3或-3,您就知道您有赢家。
+3表示X获胜。
-3表示O获胜。


哪个计数器达到+/-3表示哪一行/列/对角线赢。

是的,我想我应该用蛮力来对付它,嗯?是的,我想我应该用蛮力对付它,嗯?我必须承认我不太理解你的问题。你说有效是什么意思?速度最高还是代码最少?此外,为什么这在这里都很重要?Tictatcoe场有8条线,可以作为胜利条件,因此,是什么阻止了您一个接一个地检查所有线(如果您愿意,可以使用for循环处理水平和垂直情况)。对于这样简单的情况,性能或(从发布的代码判断)代码复杂性并不重要。另一个注意事项:为什么clickHandler中有一个开关对所有情况都执行相同的操作?你完全正确!哈哈哈,昨晚没怎么睡不是真的;正如我所说的,我可以粗暴地对待这些事情,但我很好奇有更多经验的人会如何处理它。我只是在开玩笑——主要是在开玩笑=D你必须承认,这将是一个体面的家庭作业。我必须承认我并不真正理解你的问题。你说有效是什么意思?速度最高还是代码最少?此外,为什么这在这里都很重要?Tictatcoe场有8条线,可以作为胜利条件,因此,是什么阻止了您一个接一个地检查所有线(如果您愿意,可以使用for循环处理水平和垂直情况)。对于这样简单的情况,性能或(从发布的代码判断)代码复杂性并不重要。另一个注意事项:为什么clickHandler中有一个开关对所有情况都执行相同的操作?你完全正确!哈哈哈,昨晚没怎么睡不是真的;正如我所说的,我可以粗暴地对待这些事情,但我很好奇有更多经验的人会如何处理它。我只是在开玩笑——主要是在开玩笑=D你必须承认,这将是一个不错的家庭作业。我确信至少有一种语言,你的代码是合法的,可以编译。我确信至少有一种语言,你的代码是合法的,可以编译。这一点很好。如果你知道一个点,那么你可以减少水平和垂直方向