2013-03-01 2 views
3

Это для крестики нолики игры, где сетка может быть размером для любого числа (3x3 4x4 8x8 и т.д.)Как исследовать массив для .Text значений

При загрузке формы, метод считывает размер сетки и заполняет форму с помощью множества кнопок в 1-мерном кнопочном массиве. Массив называется buttonArray.

С помощью 1-мерного ButtonArray и без использования LINQ, как я могу сравнить значения .Text кнопок в buttonArray, чтобы увидеть, являются ли они «X» или «O» для функции CheckWinner().

После создания кнопки сетки, у меня есть обработчик событий для нажатия кнопок:

private void button_click(object sender, EventArgs e) 
    { 
     Button b = (Button)sender; 
     b.Text = "X"; 
     b.Enabled = false; 
     CheckWinner(buttonArray); 
} 

Я тогда призывающего свою функцию CheckWinner и проходящий в массиве buttonArray.

Опять же, я просто ищу примитивный способ проверить/сравнить значения без использования LINQ. Если я знаю длину каждой стороны сетки, могу сказать, что для горизонтальных выигрышных линий я ищу много кнопок в строке с «X» в качестве их .Text-свойства.

Итак, если у меня есть сетка 5x5, и у меня есть 25 кнопок в buttonArray, как я могу проверить каждые 5, начиная с индекса 0 сетки, чтобы их значения .Text были «X», а затем печатали сообщение, если 5 в строке одинаковы или «X» в этом случае.

for (int z = 0; z < root; z++) //increments the column to start on 
     { 
      vCount = 0; //Starts the win counter at zero when moving to the next column 
      for (int i = z; i < arrLength; i=i+root) //starts at the first column and increments it by root to test the next button in the column 
      { 
       string bText = buttonArray[i].Text; 
       if (bText == "X") 
        vCount++; 
       if (vCount == root) 
       { 
        MessageBox.Show("Vertical row winner found !"); 
        break; 
       } 
      } 
     }//end of vertical column test 

Я сделал вертикальное испытание, как это? Но я думаю, что объединение их в один будет лучше.

+0

Считаете ли вы диагональные или только горизонтальные и вертикальные условия выигрышные? –

+0

Да, абсолютно, но я подумал, что только начинать с простой горизонтали было бы самым простым, и я мог бы пойти оттуда. – BackDoorNoBaby

+1

Хорошо, что это условие победы для 5x5? Только полная диагональ? –

ответ

2

Предполагая, что вы хотите проверить еслиButton.Text == "X"вevery element of a horizontal row. Ниже очень простой способ ...

public void CheckWinner(Buttons[] buttonArray) 
{ 
    int arrLength = buttonArray.Length; 
    int hCount = 0; 
    //int vCount = 0; 
    int root = (int)Math.Sqrt(Convert.ToDouble(arrLength)); 

    for (int i = 0; i < arrLength ; i++) 
    { 
     string bText = buttonArray[i].Text; 

     hCount = i % root == 0? 0 : hCount; 

     if(bText == "X") 
      hCount++; 

     if(hCount == root) 
     { 
      Console.WriteLine("Horizontal row winner found !"); 
      break; 
     } 
    } 

} 

Для проверки virtical и/или по горизонтали победителя:

public void CheckWinner(Buttons[] buttonArray) 
{ 
    int arrLength = buttonArray.Length; 
    int hCount = 0; 
    Int vCount = 0; 
    int root = (int)Math.Sqrt(Convert.ToDouble(arrLength)); 

    for (int i = 0; i < root; i++) 
    { 
     hCount = 0; 
     vCount = 0; 
     for(int j = 0; j < root; j++) 
     { 
      if(buttonArray[ (i * root) + j ].Text == "X") 
       hCount++; 

      if(buttonArray[ i + (root * j) ].Text == "X") 
       vCount++; 
     } 

     if(hCount + vCount == 2 * root) 
     { 
      Console.WriteLine("Horizontal and Virtical winner found !"); 
      break; 
     } 
     else if (hCount == root) 
     { 
      Console.WriteLine("Horizontal winner found !"); 
      break; 
     } 
     else if (vCount == root) 
     { 
      Console.WriteLine("Virtical winner found !"); 
      break; 
     } 

    } 
} 
+0

. Этот находится на правильном пути для того, что я ищу, но Im получает ошибки для (i + 1)% 5 – BackDoorNoBaby

+0

@BackDoorNoBaby: вы пробовали последнее? – Kaf

+0

Да, этот всплывает, когда щелкнули что-нибудь по диагонали. Для чего я пытаюсь проверить, у меня есть сетка, которая имеет сторону D x D. Она заполнена одномерным массивом кнопок, и я хочу проверить, начиная с 0, каждые кнопки D, чтобы увидеть, является ли их свойство .Text это «X», и если это так, у меня есть победитель для горизонтальной строки. – BackDoorNoBaby

1

Конечно, вы можете дать этому выстрел - я буду делать по-строки здесь, по-смещ_по_столбцы должны быть очень похожи:

(редактировать - ха, очевидно, я не могу читать ... но могу остается полезным ответом для других ... поскольку я уже доказал, что не обращал внимания на OP, позвольте мне расширить его и заполнить вертикальные/диагональные области ...)

(LINQPad-ready)

void Main() 
{ 
    // Quickish and very dirty way to generate the grid 
    var lineLength = 3; 
    var rnd = new Random(); 
    var gridSrc = 
     from r in Enumerable.Range(0, lineLength) 
     from c in Enumerable.Range(0, lineLength) 
     select new { Row = r, Col = c, Text = rnd.Next(0,2) > 0 ? "X" : "O" }; 
    var grid = gridSrc.ToArray(); 

    // ok, now for the query 
    var horizontalWinners = 
     // need the cell and it's index - this is one way to do that 
     from cellTuple in grid.Select((cell, idx) => Tuple.Create(idx, cell)) 
     let idx = cellTuple.Item1 
     let cell = cellTuple.Item2 
     // figure out which row its in 
     let row = idx/lineLength 
     // figure out which column its in 
     let col = idx % lineLength 
     // for rows, group by row # 
     group cell by row into byRow 
     // only count if all cells in that row are same 
     where byRow.All(rowCell => rowCell.Text == "X") 
      || byRow.All(rowCell => rowCell.Text == "O") 
     // tell us what row (and who won) 
     select new { byRow.Key, byRow.First().Text }; 

var verticalWinners = 
    from cellTuple in grid.Select((cell, idx) => Tuple.Create(idx, cell)) 
    let idx = cellTuple.Item1 
    let cell = cellTuple.Item2 
    let row = idx/lineLength 
    let col = idx % lineLength 
    group cell by col into byCol 
    where byCol.All(colCell => colCell.Text == "X") 
       || byCol.All(colCell => colCell.Text == "O") 
    select new { byCol.Key, byCol.First().Text }; 

var topLeftBottomRightDiagonalWinners = 
    from cellTuple in grid.Select((cell, idx) => Tuple.Create(idx, cell)) 
    let idx = cellTuple.Item1 
    let cell = cellTuple.Item2 
    let row = idx/lineLength 
    let col = idx % lineLength 
    let fwdSlash = (row == col) 
    group cell by fwdSlash into byDiag 
    where byDiag.Key && byDiag.All(d => d.Text == byDiag.First().Text) 
    select new { 
       Text = byDiag.First().Text, 
       Pos = string.Join("", byDiag.Select(c => Tuple.Create(c.Col, c.Row).ToString())) 
      }; 

var topRightBottomLeftDiagonalWinners = 
    from cellTuple in grid.Select((cell, idx) => Tuple.Create(idx, cell)) 
    let idx = cellTuple.Item1 
    let cell = cellTuple.Item2 
    let row = idx/lineLength 
    let col = idx % lineLength 
    let backSlash = (row + col) == (lineLength - 1) 
    group cell by backSlash into byDiag  
    where byDiag.Key && byDiag.All(d => d.Text == byDiag.First().Text) 
    select new { 
       Text = byDiag.First().Text, 
       Pos = string.Join("", byDiag.Select(c => Tuple.Create(c.Col, c.Row).ToString())) 
      }; 

for(int r=0;r<lineLength;r++) 
{ 
    for(int c=0;c<lineLength;c++) 
    { 
     Console.Write(grid[r*lineLength+c].Text + " "); 
    } 
    Console.WriteLine(); 
} 
foreach(var row in horizontalWinners) 
{ 
    Console.WriteLine("{0} wins on row {1}", row.Text, row.Key); 
} 
foreach(var col in verticalWinners) 
{ 
    Console.WriteLine("{0} wins on col {1}", col.Text, col.Key); 
} 
foreach (var diag in topLeftBottomRightDiagonalWinners 
       .Concat(topRightBottomLeftDiagonalWinners)) 
{ 
    Console.WriteLine("{0} wins on diagonal {1}", diag.Text, diag.Pos);  
} 
} 
+0

OP хочет решение, отличное от LINQ – Brad

+0

@Brad Hah - я полностью прочитал «не используя LINQ» как «используя LINQ» .... * sigh * – JerKimball

+0

Hahah да, материал LINQ, который я знаю, очень мощный, но на данный момент его просто слишком сложно для меня, чтобы понять это, просто проезжая через веб-сообщения и библиотеку MSDN. Однако, спасибо! – BackDoorNoBaby

2

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

Мне кажется, что основной трюк этого вопроса - просто показать понимание строк и столбцов массива и как имитировать 2D-массив, заданный только 1D-массивом.

Для горизонтального:

string CheckWinnerHorizontal(Button[] buttonArray) { 
    int N = (int)Math.Sqrt(buttonArray.Length); 
    for (int row = 0; row < N; ++row) 
    { 
     string winner = ""; 
     for (int col = 0; col < N; ++col) 
     { 
      string value = buttonArray[row * N + col].Text; 
      if (winner == "") { winner = value; } 
      else if (winner != value) { winner = "none"; } 
     } 
     if (winner != "none" && winner != "") 
     { 
      return winner; 
     } 
    } 
    return ""; 
+0

его высказывание не может преобразовать тип источника double в int для Math.Sqrt? – BackDoorNoBaby

+0

Извините. Исправлено в редактировании. Кроме того, если вы знаете размер своей сетки, просто передайте ее функции, она будет более эффективной. Поскольку сетка всегда является квадратом размера сетки, я использовал ее. –

+0

Ошибки исчезли, но ничего не происходит, когда я получаю 5 Xs подряд. У меня нет метода для компьютера, но я просто сосредоточился на нажатии кнопки, размещении X там, а затем программы, узнав, когда у меня 5 подряд для победы. – BackDoorNoBaby

 Смежные вопросы

  • Нет связанных вопросов^_^