这适用于tic tac toe游戏,其中网格可以调整为任意数量(3x3 4x4 8x8等)
当表单加载时,方法读取网格大小并使用一维按钮阵列中的那么多按钮填充表单。该数组称为buttonArray。
只使用1维buttonArray并且不使用LINQ,我如何比较buttonArray中按钮的.Text值,看看它们是CheckWinner()函数的“X”还是“O”。
创建按钮网格后,我有一个按钮点击的事件处理程序:
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的网格,并且我在buttonArray中有25个按钮,那么如何从网格的0索引开始检查每个5,其.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 :(得分: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;
}
}
}
检查优秀和/或横向赢家:
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;
}
}
}
答案 1 :(得分:2)
我会把我的选择放到戒指上,虽然看起来所有其他答案都有效。我的是一个基本的实施。它只是沿着每一行,并检查每行中是否有相同的值。垂直版本就像重新排列我的两个for循环一样简单,对角线也不会太难。
在我看来,这个问题的主要技巧只是展示对阵列行和列的理解,以及如何模拟仅给出1D阵列的2D阵列。
横向:
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 "";
答案 2 :(得分:1)
当然,你可以试一试 - 我会在这里按行进行,副词应该非常相似:
(编辑 - 哈,很明显我看不懂......但对其他人来说可能仍然是一个有用的答案......因为我已经证明我没有注意到OP,让我扩展一下填写垂直/对角线...)
(LINQPad就绪)
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);
}
}