Tac*_*cit 5 .net c# algorithm winforms
这是游戏板,只是为了让你了解它的外观(这块板将扩展到7x6)
我想要做的就是在连续两种颜色的情况下检测胜利者,类似于考虑对角线组合的游戏"conmect four".但是我想在没有使用暴力枚举的情况下这样做.
这个程序背后的代码我已经让我不是要求解决方案我只需要一些有效算法的帮助
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private Button[] btns;
private Button[] btns2;
public Form1()
{
InitializeComponent();
btns = new Button[] { button2, button3 };
btns2 = new Button[] { button4, button5 };
}
private void Form1_Load(object sender, EventArgs e)
{
foreach (var btn in btns)
{
btn.Enabled = false;
btn.BackColor = Color.LightCyan;
}
foreach (var btn in btns2)
{
btn.Enabled = false;
btn.BackColor = Color.LightCyan;
}
}
public int state;
int cc = 0;
private void button1_Click(object sender, EventArgs e)
{
foreach (var btn in btns)
{
{
if (!btn.Enabled)
{
btn.Enabled = true;
if (cc == 0)
{
cc = 1;
btn.BackColor = Color.Red;
}
else
{
cc = 0;
btn.BackColor = Color.Yellow;
}
return;
}
}
}
}
private void button6_Click(object sender, EventArgs e)
{
foreach (var btn in btns2)
{
if (!btn.Enabled)
{
btn.Enabled = true;
if (cc == 0)
{
cc = 1;
btn.BackColor = Color.Red;
}
else
{
cc = 0;
btn.BackColor = Color.Yellow;
}
return;
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
Mat*_*and 10
首先,为了提高效率和理智,我将我的电路板状态保持在2D阵列中.
其次,为了检测胜利状态,假设你用一个(大概)空板开始游戏,你只能在按钮改变状态时进入获胜状态.如果按钮更改状态使您进入获胜状态,则该按钮必须参与该获胜状态(即它必须是您的一部分).
所以......你不需要暴力强迫整个董事会.您只需确定刚刚更改状态的按钮是否为行的一部分.换句话说,只查看上方,下方,左侧和右侧的按钮(可能是对角线,如果您包括对角线,则问题不明确),看它们是否与您更改的颜色相同.如果其中任何一个是,那么这是一个胜利状态.这是使用2D阵列将使您的生活更轻松的地方.如果(x,y)处的按钮改变了,那么你只需要检查(x-1,y),(x + 1,y),(x,y-1)和(x,y + 1)当然,确保进行适当的边界检查,(和可能是对角线).
将其扩展到连续3,4或更多并不困难,除非您需要记住您可能在一行中间而不是一端或另一端.
连续2个未经优化的伪代码(注意,我已切换到指南针点以避免左上,右上等因为我觉得它有点笨拙):
// cell is the cell that last changes, it has an x and y property and a color property
// board is a member variable, a 2D array of cells. Note [0,0] is the upper-left (NW) corner of the board.
// boardHeight and boardWidth are member variable with the dimensions of the board
// board[boardWidth-1, boardHeight-1] is the lower-right (SE) corner of the board
// returns true for a win, false otherwise
function checkWin(cell) returns bool {
// check west
if (cell.x > 0 && board[cell.x - 1, cell.y].color == cell.color)
return true;
// check northwest
if (cell.x > 0 && cell.y > 0 && board[cell.x-1, cell.y-1].color == cell.color)
return true;
// check north
if (cell.y > 0 && board[cell.x, cell.y-1].color == cell.color)
return true;
// check northeast
if (cell.y > 0 && cell.x < boardWidth && board[cell.x+1, cell.y-1].color == cell.color)
return true;
// checking the other directions is left as an exercise for the reader, hopefully you get the point
return false;
}
Run Code Online (Sandbox Code Playgroud)
如果你做的超过2,我会考虑一个递归函数来计算左,右,上,下和诊断的匹配单元格的数量
// k is the number of cells in a row for a win
function checkWin(cell) returns bool {
// check west / east
int count = checkWest(cell);
if (count > k)
return true;
count += checkEast(cell);
if (count > k)
return true;
// check nw / se
count = checkNW(cell);
if (count > k)
return true;
count += checkSE(cell);
if (count > k)
return true;
// and so on, checking N/S and NE/SW
return false;
}
function checkWest(cell) returns int {
// base case, check the boundaries!
if (cell.x == 0)
return 0;
// base case, the cell next to this one doesn't match
if (board[cell.x-1,cell.y].color != cell.color)
return 0;
// recursion, check the next cell in the line
return 1 + checkWest(board[cell.x-1,cell.y]);
}
Run Code Online (Sandbox Code Playgroud)