Создание методов кнопок для игры SUPER TIC TAC TOE

Я делаю игру Super Tac Toe (в основном это сетка 3x3 досок для крестиков-ноликов)

где доска состоит из блока кнопок 3х3 со следующим методом нажатия

    private void buttonI_Click(object sender, EventArgs e)
{
    if(jar == true)
    {
        buttonI.Text = "X";
    }
    if(jar == false)
    {
        buttonI.text = "O";
    }
    jar = !(jar)
}

где jar — это логическая переменная, которая используется для отслеживания хода каждого игрока. Я использовал скрипт Python для массового производства кода для 1 <= I <= 81, но... только мои кнопки 1-9 имеют правильную функциональность. Эти кнопки были созданы вручную с помощью Visual Studio IDE (я просто дважды щелкнул их, чтобы создать метод нажатия кнопки), но я не вижу абсолютно никакой разницы в синтаксисе между этими кнопками и кнопками, для которых я массово создавал код.

Некоторая помощь и четкое объяснение были бы потрясающими!


person frogeyedpeas    schedule 06.01.2014    source источник
comment
Я предполагаю, что вы на самом деле не подключали код к самим кнопкам. Я считаю, что самый простой способ создать проводку - дважды щелкнуть кнопку в IDE и позволить VS создать соединение для вас.   -  person sous2817    schedule 06.01.2014
comment
Так как именно работает эта проводка? Есть ли способ сделать это без двойного нажатия всех кнопок?   -  person frogeyedpeas    schedule 06.01.2014
comment
Конечно, вы должны прикрепить свой метод к событию, что-то вроде button1.Clicked += YourMethodName;. Просто взгляните на класс Designer.cs, и вы увидите, как VS их подключает.   -  person Pierre-Luc Pineault    schedule 06.01.2014
comment
каким будет аргумент методов? Будет ли это имя указанной кнопки и каким будет аргумент для actionEvent?   -  person frogeyedpeas    schedule 06.01.2014
comment
Как найти класс Designer.cs?   -  person frogeyedpeas    schedule 06.01.2014
comment
Не обращайте внимания на этот последний комментарий, я не могу найти код для проводки в классе дизайнера. Где именно мне нужно посмотреть?   -  person frogeyedpeas    schedule 06.01.2014


Ответы (2)


Избегайте "массового кода"... Если позже вам нужно будет изменить функциональность, вам придется изменить ее для 81 метода. Это не ремонтопригодно.

Итак, что делать?

Во-первых, я бы даже вручную не опускал каждую кнопку в окно. Я бы добавил свой код для каждой кнопки. Так вот, вы не сказали, делаете ли вы WinForms или WPF. Итак, я возьму WPF, потому что он новее и, на мой взгляд, намного лучше.

Программное добавление кнопок

Создайте Window с Grid по имени gMain. Затем привяжите к событию Initialize окна:

private void handleWindowInitialized(object sender, EventArgs e)
{
  // Add 3 rows and 3 columns.
  for (int i = 0; i < 3; i++)
  {
    gMain.ColumnDefinitions.Add(new ColumnDefinition());
    gMain.RowDefinitions.Add(new RowDefinition());
  }

  // Add button to each cell.
  for(int row=0; row<3; row++)
    for (int column = 0; column < 3; column++)
      createButton(row, column);
}

Итак, теперь, когда мы настроили gMain, давайте посмотрим на метод createButton().

Создание кнопки

private void createButton(int row, int column)
{
  var button = new Button();

  // Add to gMain
  gMain.Children.Add(button);

  // Place the button in the correct cell.
  Grid.SetRow(button, row);
  Grid.SetColumn(button, column);

  // Tie to the click event.
  button.Click += handleButtonClick;
}

Достаточно просто? Мы просто создаем Button, добавляем его к gMain, помещаем в правильную ячейку, а затем привязываем к событию Click. Теперь давайте посмотрим на обработчик события.

Обработчик событий

void handleButtonClick(object sender, RoutedEventArgs e)
{
  var button = (Button)sender;
  int row = Grid.GetRow(button);
  int column = Grid.GetColumn(button);

  // Do what ever you would like to do...
}

Обратите внимание, что мы можем указать столбец и строку... из этого вы сможете сделать любую логику, которая вам нужна. Это здорово, потому что тогда вам не понадобится куча разных методов.

person poy    schedule 06.01.2014

Вау.. хорошо. Основное правило № 1: Вы ОБЪЕКТНО ОРИЕНТИРОВАНЫ. НЕ МОДУЛЬНЫЙ. Зачем дублировать функцию?

Вместо этого вы можете УСТАНОВИТЬ идентификатор для кнопки и иметь одно и то же событие onClick для всех кнопок.

Определите 9 кнопок, каждая кнопка с идентификатором 0..8 Таким образом, каждая кнопка будет вызывать

private void anyButton_Click(object sender, EventArgs e)
{
    // sender is your button! you can use it's .id or anything alike
    if(jar == true)
    {
        buttonI.Text = "X";
    }
    if(jar == false)
    {
        buttonI.text = "O";
    }
    jar = !(jar)
}
person Shai    schedule 06.01.2014
comment
поэтому мне нужно сделать 81 строку private void button_kClick(etc...) { anyButton_Click(sender, e); }? - person frogeyedpeas; 06.01.2014
comment
Нет, только один! Сделайте так, чтобы все кнопки переходили к одному и тому же методу onClick. Вы можете легко определить, какая кнопка была нажата, используя параметр ID кнопки (или имя, или что-то еще) - person Shai; 06.01.2014
comment
Можете ли вы объяснить это дальше? Является ли метод, который вы дали, точно так же, как он способен работать со всеми кнопками, или здесь нужно сделать больше? - person frogeyedpeas; 06.01.2014