利用二维数组表示棋盘
详细代码在附件中,vs2008制作
- 标 题:一个无聊的简易人机对战五子棋
- 作 者:干掉上帝
- 时 间:2011-02-05 18:14:23
- 链 接:http://bbs.pediy.com/showthread.php?t=128963
利用二维数组表示棋盘
详细代码在附件中,vs2008制作
namespace Five
{
[Serializable]
//五子棋实体类
class Five
{
int[,] map = new int[19, 19];//19*19棋盘,值为0时表示无子,1黑子,2白子
int[, ,] grade = new int[19, 19, 2];//判断全脂表
public int[, ,] Grade
{
get { return grade; }
set { grade = value; }
}
public int[,] Map
{
get { return map; }
set { map = value; }
}
int turn;//当为0时;轮到黑旗,为1时轮到白旗,
public int Turn
{
get { return turn; }
set { turn = value; }
}
/// <summary>
/// 初始化棋盘
/// </summary>
public void initMap()
{
for (int i = 0; i < 19; i++)
{
for (int j = 0; j < 19; j++)
map[i, j] = 0;
}
}
//将权值初始化
public void initGrade()
{
for (int i = 0; i < 19; i++)
{
for(int j=0;j<19;j++)
for (int k=0; k < 2; k++)
{
grade[i, j, k] = 0;
}
}
}
public Five()
{
initMap();
initGrade();
Turn = 0;//黑棋先行 mus
}
//落子函数
public void put(int i, int j)
{
if (map[i, j] == 0)//五子棋只有在没有落子处可以下
{
map[i, j] = Turn+1;
//更新权值表
updateGrade(i, j);
Turn = (Turn + 1) % 2;
}
}
//每方共有多少棋子
private int count(int turn)
{
int result = 0;
foreach(int i in Map)
{
if (i == turn + 1)
result++;
}
return result;
}
//更新权值表函数
private void updateGrade(int i,int j)
{
int tempI = i;
int tempJ = j;
int count = 0;
int L =j,R = j;//左右边界
int U=i , D = i;//上下边界
//横
//左
while (L >= 0 && map[i, L] == turn + 1)
{
count++;
L--;
}
count--;
//右
while (R < 19 && map[i, R] == turn + 1)
{
count++;
R++;
}
if (L > 0 && map[i, L ] == 0)
{
grade[i, L , turn] += count;
}
if (R + 1 < 19 && map[i, R + 1] == 0)
{
grade[i, R , turn] += count;
}
L=R=j;//归位
count=0;
//竖向
//上
while (U >= 0 && map[U, j] == turn+1)
{
count++;
U--;
}
count--;
//下
while (D < 19 && map[D, j] == turn+1)
{
count++;
D++;
}
if (U > 0 && map[U , j] == 0)
{
grade[U , j,turn] += count;
}
if (D + 1 < 19 && map[D , j] == 0)
{
grade[D , j, turn] += count;
}
U = D = j;
count = 0;
//左斜
while (U >= 0 && R < 19 && map[U, R] == turn+1)
{
count++;
R++;
U--;
}
count--;
while (D < 19 && L >= 0 && map[D, L] == turn+1)
{
count++;
D++;
L--;
}
if (U > 0 && (R ) < 19 && map[U, R ] == 0)
{
grade[U, R , turn] += count;
}
if(D<19&&L>0&&map[D,L]==0)
{
grade[D,L,turn]+=count;
}
L = R = j;
U = U = i;
count = 0;
//右斜
while (U >=0 && L>=0 && map[U, L] == turn+1)
{
count++;
U--;
L--;
}
count--;
while (D < 19 && R < 19 && map[D, R] == turn+1)
{
count++;
D++;
R++;
}
if (U > 0 && L > 0 && map[U , L] == 0)
{
grade[U , L , turn] += count;
}
if (D < 19 && R < 19 && map[D , R ] == 0)
{
grade[D , R , turn] += count;
}
}
//无障碍链子查询函数
private bool SearchLinkNum(int num,int side,ref int x,ref int y )
{
bool result = false;
int emtry = (side + 1) % 2;
for (int i = 0; i < 19; i++)
{
for (int j = 0; j < 19; j++)
{
if (map[i,j]==0)
{
int tempI = i;
int tempJ = j;
int count = 0;
int L = j-1, R = j+1;//左右边界
int U = i-1, D = i+1;//上下边界
//横向判断
while (L > 0 && map[i, L] == side + 1)
{
count++;
L--;
}
count++;
while (R < 19 && map[i, R] == side + 1)
{
count++;
R++;
}
if (count >= num)
{
x = i;
y = j;
result = true;
goto End;
}
count = 0;
L = j - 1;R=j+1 ;
//竖向
while (U > 0 && map[U, j] == side + 1)
{
count++;
U--;
}
count++;
while (D < 19 && map[D, j] == side + 1)
{
count++;
D++;
}
if (count >= num)
{
x = i;
y = j;
result = true;
goto End;
}
U=i-1; D = i+1;
count = 0;
//右斜
while (L > 0 && U > 0 && map[U, L] == side + 1)
{
count++;
L--;
U--;
}
count++;
while (R < 19 && D < 19 && map[D, R] == side + 1)
{
count++;
R++;
D++;
}
if (count >= num)
{
x = i;
y = j;
result = true;
goto End;
}
L = j - 1; R = j+1;
D = i + 1; U = i-1;
count = 0;
//左斜
while (D < 19 && L > 0 && map[D, L] == side + 1)
{
count++;
D++;
L--;
}
count++;
while (U > 0 && R < 19 && map[U, R] == side + 1)
{
count++;
U--;
R++;
}
if (count >= num)
{
x = i;
y = j;
result = true;
goto End;
}
}
}
}
End:
return result;
}
//胜利子查询函数
private bool doubleThree(int side,ref int x,ref int y)
{
bool result = false;
for (int i = 0; i < 19; i++)
{
for (int j = 0; j < 19; j++)
{
if (map[i, j] == 0)
{
int emtry = (side + 1) % 2;
int num =0;
int tempI = i;
int tempJ = j;
int count = 0;
int L = j-1, R = j+1;//左右边界
int U = i-1, D = i+1;//上下边界
//横向判断
while (L > 0 && map[i, L] == side + 1)
{
count++;
L--;
}
count++;
while (R < 19 && map[i, R] == side + 1)
{
count++;
R++;
}
if (count >= 3)
{
num++;
}
count = 0;
L = j - 1; R = j + 1; ;
//竖向
while (U > 0 && map[U, j] == side + 1)
{
count++;
U--;
}
count++;
while (D < 19 && map[D, j] == side + 1)
{
count++;
D++;
}
if (count >=3)
{
num++;
}
U =i-1; D = i+1;
count = 0;
//右斜
while (L > 0 && U > 0 && map[U, L] == side + 1)
{
count++;
L--;
U--;
}
count++;
while (R < 19 && D < 19 && map[D, R] == side + 1)
{
count++;
R++;
D++;
}
if (count >= num)
{
num++;
}
L=j-1; R = j+1;
D = i + 1; U = i-1;
count = 0;
//左斜
while (D < 19 && L > 0 && map[D, L] == side + 1)
{
count++;
D++;
L--;
}
count++;
while (U > 0 && R < 19 && map[U, R] == side + 1)
{
count++;
U--;
R++;
}
if (count >= num)
{
num++;
}
if (num >= 2)
{
x = i;
y = j;
goto End;
}
}
}
}
End: return result;
}
//双三查询函数
private bool SearchWin(int side, ref int x, ref int y)
{
bool result = false;
for (int i = 0; i < 19; i++)
{
for (int j = 0; j < 19; j++)
{
if (map[i, j] == 0)
{
int emtry=(side+1)%2;
int num = 5;
int tempI = i;
int tempJ = j;
int count = 0;
int L = j-1, R = j+1;//左右边界
int U = i-1, D = i+1;//上下边界
//横向判断
while (L > 0 && map[i, L] == side + 1)
{
count++;
L--;
}
count++;
while (R < 19 && map[i, R] == side + 1)
{
count++;
R++;
}
if (count >= num)
{
x = i;
y = j;
result = true;
goto End;
}
count = 0;
L = j - 1; R = j+1;
//竖向
while (U > 0 && map[U, j] == side + 1)
{
count++;
U--;
}
count++;
while (D < 19 && map[D, j] == side + 1)
{
count++;
D++;
}
if (count >= num)
{
x = i;
y = j;
result = true;
goto End;
}
U = i - 1; D = i+1;
count = 0;
//右斜
while (L > 0 && U > 0 && map[U, L] == side + 1)
{
count++;
L--;
U--;
}
count++;
while (R < 19 && D < 19 && map[D, R] == side + 1)
{
count++;
R++;
D++;
}
if (count >= num)
{
x = i;
y = j;
result = true;
goto End;
}
L = j - 1; R = j+1;
D = i + 1; U = i-1;
count = 0;
//左斜
while (D < 19 && L > 0 && map[D, L] == side + 1)
{
count++;
D++;
L--;
}
count++;
while (U > 0 && R < 19 && map[U, R] == side + 1)
{
count++;
U--;
R++;
}
if (count >= num)
{
x = i;
y = j;
result = true;
goto End;
}
}
}
}
End: return result;
}
//断四函数
private bool killFour(int side, ref int x, ref int y)
{
bool result = false;
for (int i = 0; i < 19; i++)
{
for (int j = 0; j < 19; j++)
{
if (map[i, j] == 0)
{
int tempI = i;
int tempJ = j;
//横向判断
int count = 0;
while ((j < 19) && j >= 0 && Map[i, j] == side + 1)
{
count++;
j++;
}
j = tempJ - 1;
while (j < 19 && j >= 0 && Map[i, j] == side + 1)
{
count++;
j--;
}
if (count >= 4)
{
result = true;
x = i;
y = j;
goto end;
}
j = tempJ;
i = tempI;
//竖向判断
count = 0;
while (i < 19 && i >= 0 && Map[i, j] == side + 1)
{
count++;
i++;
}
i = tempI - 1;
while (i < 19 && i >= 0 && Map[i, j] == side + 1)
{
count++;
i--;
}
if (count >= 4)
{
result = true;
x = i;
y = j;
goto end;
}
//右
count = 0;
i = tempI;
while ((i < 19 && i >= 0) && (j < 19 && j >= 0) && Map[i, j] == side + 1)
{
count++;
i++;
j++;
}
i = tempI - 1;
j = tempJ - 1;
while ((i < 19 && i >= 0) && (j < 19 && j >= 0) && Map[i, j] == side + 1)
{
count++;
i--;
j--;
}
if (count >= 4)
{
result = true;
x = i;
y = j;
goto end;
}
//左
i = tempI;
j = tempJ;
count = 0;
while ((i < 19 && i >= 0) && (j < 19 && j >= 0) && Map[i, j] == side + 1)
{
count++;
i--;
j++;
}
i = tempI + 1;
j = tempJ - 1;
while ((i < 19 && i >= 0) && (j < 19 && j >= 0) && Map[i, j] == side + 1)
{
count++;
i++;
j--;
}
if (count >= 4)
{
result = true;
x = i;
y = j;
goto end;
}
}
}
}
end: return result;
}
//Ai函数
public void AI(ref int X,ref int Y)
{
int x=0,y=0;
int emery = (Turn + 1) % 2;//敌方
if (count(Turn) == 0)
{
if (count(emery) == 0)
{
//如果敌人还没下,就随便下一步
Random rom = new Random();
x = (int)(rom.Next(7, 15));
y = (int)(rom.Next(7, 15));
}
else
{
//如果敌人已经下一子,在敌人权值最大的空行下
getPoint(ref x, ref y, emery);
}
}
else
{
if (SearchWin(turn, ref x, ref y)==true)
{
}
else
{
if(SearchWin(emery,ref x,ref y)==true)
{
}
else
{
if( SearchLinkNum(4,turn,ref x,ref y)==true)
{
}
else
{
if(SearchLinkNum(4,emery,ref x,ref y)==true)
{
}
else
{
if(doubleThree(turn,ref x,ref y)==true)
{
}
else
{
if(doubleThree(emery,ref x,ref y)==true)
{
}
else
{
if( SearchLinkNum(3,turn,ref x,ref y)==true)
{
}
else
{
if (SearchLinkNum(2, turn, ref x, ref y) == true)
{
}
else
{
if (SearchLinkNum(1, turn, ref x, ref y) == false)
{
getPoint(ref x, ref y, turn);
}
goto end;
}
}
}
}
}
}
}
}
}
end : X = x;Y=y;
put(x, y);
}
//获取权值最大的空格坐标
private void getPoint(ref int x,ref int y,int state)
{
int max = 1;
for (int i = 0; i < 19; i++)
{
for (int j = 0; j < 19; j++)
{
if (map[i, j] == 0)
{
if (grade[i, j, state] >= max)
{
x = i;
y = j;
}
}
}
}
}
public bool CheckWined(int i, int j)
{
bool result=false;
int tempI = i;
int tempJ = j;
int flag=Map[i,j];
//横向判断
int count = 0;
while ((j< 19)&&j>=0 && Map[i, j] == flag)
{
count++;
j++;
}
j = tempJ - 1;
while (j< 19&&j>=0 && Map[i, j] == flag)
{
count++;
j--;
}
if (count >= 5)
{
result = true;
goto end;
}
j = tempJ;
i = tempI;
//竖向判断
count = 0;
while(i<19 &&i>=0&& Map[i,j]==flag)
{
count++;
i++;
}
i = tempI-1;
while (i < 19&&i>=0 && Map[i, j] == flag)
{
count++;
i--;
}
if (count >= 5)
{
result = true;
goto end;
}
//右
count = 0;
i = tempI;
while((i<19&&i>=0)&&(j<19&&j>=0)&&Map[i,j]==flag)
{
count++;
i++;
j++;
}
i = tempI - 1;
j = tempJ - 1;
while ((i < 19&&i>=0) && (j < 19&&j>=0) && Map[i, j] == flag)
{
count++;
i--;
j--;
}
if (count >= 5)
{
result = true;
goto end;
}
//左
i = tempI;
j = tempJ;
count = 0;
while ((i < 19&&i>=0) && (j < 19&&j>=0) && Map[i, j] == flag)
{
count++;
i--;
j++;
}
i = tempI + 1;
j = tempJ - 1;
while ((i < 19&&i>=0) && (j < 19&&j>=0) && Map[i, j] == flag)
{
count++;
i++;
j--;
}
if (count >= 5)
{
result = true;
goto end;
}
end: return result;
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace Five
{
public partial class MainForm : Form
{
//时钟变量
int min = 1;
int sec = 30;
PictureBox[,] Map;
Five five = new Five();
Button a;
public MainForm()
{
InitializeComponent();
}
//显示棋钟时间
private void showTime()
{
lblClock.Text = string.Format("{0}:{1}",min,sec);
}
//重置时间
private void resetTime()
{
min = 1;
sec = 30;
}
private void MainForm_Load(object sender, EventArgs e)
{
//初始化five
five = new Five();
Map = new PictureBox[19, 19];
tmrClock.Enabled = true;
//初始化棋盘控件
for (int i = 0; i <19; i++)//列
{
for (int j = 0; j <19; j++)
{
PictureBox pic = new PictureBox ();
pic.BackColor = Color.SteelBlue;
pic.Name = string.Format("pic{0}:{1}", i, j);
pic.Tag = string.Format("{0}:{1}", i, j);
pic.Size = new Size(32,32);
//计算棋子
pic.Text = "";
//确定棋子的位置
pic.Location = new Point(10 + j* 32, 10 + i * 32);
//绑定到一个单击事件
pic.Click +=new EventHandler (put);
Map[i, j] = pic;
//在控件中添加Label
Controls.Add(Map[i,j]);
}
}
updateMap();
}
//更新棋盘
private void updateMap()
{
for (int i = 0; i < 19; i++)
{
for (int j = 0; j < 19; j++)
{
//
switch (five.Map[i, j])
{
case 0:
Map[i, j].Image = Image.FromFile("floor.BMP");
break;
case 1:
Map[i, j].Image = Image.FromFile("black.BMP");
break;
case 2:
Map[i, j].Image = Image.FromFile("white.BMP");
break;
default:
break;
}
}
}
}
//单击棋盘的函数
private void put(object sender,EventArgs e)
{
string temp = ((PictureBox)(sender)).Tag.ToString();
int i = Convert.ToInt32(temp.Substring(0, temp.IndexOf(":")));
int j = Convert.ToInt32(temp.Substring(temp.IndexOf(":")+1));
//存储悔棋
FileStream fs = new FileStream("sm.sav", FileMode.OpenOrCreate);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, five);
fs.Close();
five.put(i, j);
resetTime();
showTime();
//更新棋盘
updateMap();
if (five.CheckWined(i, j) == true)
{
if (five.Turn == 1)
{
tmrClock.Stop();
MessageBox.Show("黑棋获胜");
}
EndGame();
}
else
{
//电脑开始
five.AI(ref i,ref j);
updateMap();
if (five.CheckWined(i, j) == true)
{
if (five.Turn == 0)
{
tmrClock.Stop();
MessageBox.Show("白棋获胜");
}
EndGame();
}
}
}
private void EndGame()
{
for (int i = 0; i < 19; i++)
{
for (int j = 0; j < 19; j++)
{
Map[i, j].Enabled = false;
}
}
tmrClock.Enabled = false;
}
private void BeginGame()
{
for (int i = 0; i < 19; i++)
{
for (int j = 0; j < 19; j++)
{
Map[i, j].Enabled = true;
}
}
tmrClock.Enabled = true;
}
private void btnNewStart_Click(object sender, EventArgs e)
{
five = new Five();
resetTime();
tmrClock.Enabled = true;
BeginGame();
updateMap();
}
private void btnSave_Click(object sender, EventArgs e)
{
//保存游戏
FileStream fs = new FileStream("five.sav",FileMode.OpenOrCreate);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, five);
fs.Close();
}
private void btnLoad_Click(object sender, EventArgs e)
{
//载入游戏
FileStream fs = new FileStream("five.sav", FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
five =(Five) bf.Deserialize(fs);
updateMap();
BeginGame();
fs.Close();
resetTime();
tmrClock.Enabled = true;
}
private void tmtClock_Tick(object sender, EventArgs e)
{
if (min == 0 && sec == 0)
{
tmrClock.Enabled = false;
MessageBox.Show("超时负!!!");
EndGame();
// resetTime();
}
else
{
if (sec != 0)
{
sec -= 1;
}
if (sec == 0)
{
min -= 1;
}
}
showTime();
}
private void btnGoBack_Click(object sender, EventArgs e)
{
//悔棋
FileStream fs = new FileStream("sm.sav", FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
five = (Five)bf.Deserialize(fs);
updateMap();
BeginGame();
fs.Close();
resetTime();
tmrClock.Enabled = true;
}
}
}