接近这个简单的TicTacToe练习的最佳方法是什么?

时间:2010-09-28 16:06:01

标签: 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 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;
            }
        }        
    }
}

感谢您的帮助。

7 个答案:

答案 0 :(得分:3)

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

将计数器初始化为零 放置 X 时,将1加到该行,列和对角线的计数器上 当放置 O 时,从行,列和对角线的计数器中减去1.

如果任何计数器达到3或-3,你知道你有一个胜利者 +3表示 X 赢了。
-3表示 O 赢了。

哪个计数器达到+/- 3会告诉你哪一行/列/对角线赢了。

答案 1 :(得分:1)

嗯,只有8种可能的获胜组合,你可以根据一组代表获胜位置的模板来检查它们。

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

  

0 =>空白单元
  1 =>球员A(X)
  -1 =>球员B(O)

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

答案 2 :(得分:1)

最有效的方法是知道放置在电路板上的最后一个X或O的位置,并仅检查包含此位置的方向。这样,您就不会使用蛮力来确定玩家是否赢了。

答案 3 :(得分:1)

像其他人所说的那样,蛮力是好的。

但是,我更愿意列出节点,而不是像@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}}
};   

(注意:伪代码。实际上不会编译!)

手动编码更加密集,但我认为它也更容易看到发生了什么。

答案 4 :(得分:1)

详尽的搜索。

答案 5 :(得分:0)

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

for x = 0 to 2
   If pos(x,0)==pos(x,1)==pos(X,2)
        return pos(x,0)
for y = 0 to 2
    If pos(0,y)==pos(1,y)==pos(2,y)
        return pos(0,y)
if(pos(0,0)==pos(1,1)==Pos(2,2) || pos(0,2)==pos(1,1)==pos(2,0))
    return pos(1,1)
else
    return null

答案 6 :(得分:0)

这个怎么样?

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
}