Проверка на победителя в TicTacToe? - PullRequest
5 голосов
/ 11 апреля 2009

Каким будет лучший способ увидеть (в игре на двоих) Tic Tac Toe, который выиграл? Прямо сейчас я использую что-то похожее на следующее:

if (btnOne.Text == "X" && btnTwo.Text == "X" && btnThree.Text == "X")
{
    MessageBox.Show("X has won!", "X won!");
    return;
}
else
// I'm not going to write the rest but it's really just a bunch
// if statements.

Так как мне избавиться от кратных, если это?

Ответы [ 3 ]

11 голосов
/ 11 апреля 2009

Что-то стоит:

rowSum == 3 || columnSum == 3 || diagnolSum == 3

..?

3 голосов
/ 11 апреля 2009

Если вы храните свои кнопки в многомерном массиве, вы можете написать несколько методов расширения для получения строк, столбцов и диагоналей.

public static class MultiDimensionalArrayExtensions
{
  public static IEnumerable<T> Row<T>(this T[,] array, int row)
  {
    var columnLower = array.GetLowerBound(1);
    var columnUpper = array.GetUpperBound(1);

    for (int i = columnLower; i <= columnUpper; i++)
    {
      yield return array[row, i];
    }
  }

  public static IEnumerable<T> Column<T>(this T[,] array, int column)
  {
    var rowLower = array.GetLowerBound(0);
    var rowUpper = array.GetUpperBound(0);

    for (int i = rowLower; i <= rowUpper; i++)
    {
      yield return array[i, column];
    }
  }

  public static IEnumerable<T> Diagonal<T>(this T[,] array,
                                           DiagonalDirection direction)
  {
    var rowLower = array.GetLowerBound(0);
    var rowUpper = array.GetUpperBound(0);
    var columnLower = array.GetLowerBound(1);
    var columnUpper = array.GetUpperBound(1);

    for (int row = rowLower, column = columnLower;
         row <= rowUpper && column <= columnUpper;
         row++, column++)
   {
      int realColumn = column;
      if (direction == DiagonalDirection.DownLeft)
        realColumn = columnUpper - columnLower - column;

      yield return array[row, realColumn];
    }
  }

  public enum DiagonalDirection
  {
    DownRight,
    DownLeft
  }
}

И если вы используете TableLayoutPanel с 3 строками и 3 столбцами, вы можете легко создать свои кнопки программным способом и сохранить их в массиве Button[3, 3].

Button[,] gameButtons = new Button[3, 3];

for (int row = 0; column <= 3; row++)
  for (int column = 0; column <= 3; column++)
  {
    Button button = new Button();
    // button...
    gameLayoutPanel.Items.Add(button);
    gameButtons[row, column] = button;
  }

А чтобы проверить победителя:

string player = "X";
Func<Button, bool> playerWin = b => b.Value == player;
gameButtons.Row(0).All(playerWin) ||
// ...
gameButtons.Column(0).All(playerWin) ||
// ...
gameButtons.Diagonal(DiagonalDirection.DownRight).All(playerWin) ||
// ...
2 голосов
/ 11 апреля 2009

Другим простым выходом было бы сохранение выигрышных позиций в виде данных в массиве и использование цикла для проверки всех возможных условий выигрыша вместо нескольких операторов ifs

// winnable positions
var winnables = new[] {
    "012",
    "345",
    "678",
    "036",
    "147",
    "258",
    "048",
    "246"
};

// extracted from btnOne Two Three....
var gameState = new[] { "X", "O", "X", "whatever" };


string winner = null;

// check each winnable positions
foreach (var position in winnables) {

    var pos1 = int.Parse(position[0].ToString());
    var pos2 = int.Parse(position[1].ToString());
    var pos3 = int.Parse(position[2].ToString());

    if (gameState[pos1] == gameState[pos2] &&
        gameState[pos2] == gameState[pos3])
        winner = gameState[pos1];

}

// do we have a winner?
if (!string.IsNullOrEmpty(winner))
    /* we've got a winner */

По сути, не используйте btnOne btnTwo btnThree, используйте правильный массив кнопок или массив, который сохраняет состояние игры в более доступном формате, и его будет легче вычислить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...