/// <summary>
/// 试走一步,返回能杀死的敌子数组(不更新统计数据)
/// </summary>
/// <param name="color"></param>
/// <param name="row"></param>
/// <param name="col"></param>
/// <returns></returns>
// (这个功能好多地方会使用, 亦可在以后发展成为评估一步棋价值的标准之一)
public ArrayList FindEnemiesCanKill(int color, int row, int col)
{
if (this.stones[row, col] != Board.Empty)
return null;
this.stones[row, col] = color; ArrayList stonesDead = new ArrayList(); // 死子集合
ArrayList stonesVisited = new ArrayList(); // 访问过的点的集合 // 开始判断能够提取的敌方死子
int newx, newy;
for (int i = 0; i < 4; i++)
{
newx = row + offsets[i, 0];
newy = col + offsets[i, 1]; if (newx >= 0 && newx < 19 && newy >= 0 && newy < 19)
{
if (this.stones[newx, newy] == (- color))
{
// 如果目前位置已经在前面某个方向的探索过程中找到, 则不用判断了。
// 因为不同方向的棋子可能是属于同一个串的
if (! stonesVisited.Contains(new Point(newx, newy)))
{
// 寻找包含该位置的串
ArrayList chuan = this.FindChuan(newx, newy);
// 算串的气
int chuanGas = this.CountChuanGas(chuan);
// 加到已访问的列表
stonesVisited.AddRange(chuan); if (chuanGas == 0)
stonesDead.AddRange(chuan);
}
}
}
} // 恢复试落的位置原先的状态
this.stones[row, col] = Board.Empty;
return stonesDead;
} /// <summary>
/// 算气
/// </summary>
/// <param name="row"></param>
/// <param name="col"></param>
/// <returns></returns>
public int CountGas(int row, int col)
{
int gas = 0;
int newx, newy;
for (int i = 0; i < 4; i++)
{
newx = row + Board.offsets[i, 0];
newy = col + Board.offsets[i, 1]; if (newx >= 0 && newx < 19 && newy >= 0 && newy < 19)
{
if (this.stones[newx, newy] == Board.Empty)
gas++;
}
}
return gas;
}
/// <summary>
/// 寻找包含该位置的棋子串
/// </summary>
/// <备注>
/// 该算法的核心思想是广度优先的遍历算法,
/// 粗看循环层次是比较多, 似乎十分繁琐; 细看则条理十分清晰, 逻辑简单
/// 由于定义了每次搜索的点的范围(begin ~ end), 只搜索那些没搜索过的, 所以几乎没有任何冗余的尝试
/// 基本上我认为算法已经最优了.
/// </备注>
/// <param name="row">起始点的 X 坐标</param>
/// <param name="col">起始点的 Y 坐标</param>
/// <returns>搜索到的棋子串(没找到则返回 null)</returns>
public ArrayList FindChuan(int row, int col)
{
ArrayList chuan = null;
int color = this.stones[row, col]; // 当前的颜色 if (this.stones[row, col] == color)
{
chuan = new ArrayList();
// 加入当前点
chuan.Add(new Point(row, col));
// 定义两个游标
int begin = 0;
int end = 0;
int findCount; // 发现的邻居数目, 用于循环结束的判断条件
do
{
findCount = 0;
// begin 到 end 之间的一些点表示没有探索过四周的那些点
for (int i = begin; i <= end; i++)
{
// 对左右上下四个方向进行探索
for (int j = 0; j < 4; j++)
{
int newx = ((Point) chuan[i]).X + offsets[j, 0];
int newy = ((Point) chuan[i]).Y + offsets[j, 1];
// 如果该点在棋盘内, 且颜色相同, 且现有的串中没有, 则加入串
if (newx >= 0 && newx < 19 && newy >= 0 && newy < 19
&& this.stones[newx, newy] == color
&& ! chuan.Contains(new Point(newx, newy)))
{
chuan.Add(new Point(newx, newy));
// 寻找到的邻居计数器加 1
findCount += 1;
}
}
}
// 设定下一个循环要列举的开始和结束游标
begin = end + 1;
end = end + findCount;
}
// 如果本轮搜索的所有点都没有邻居了, 也就表示串搜索结束了, 跳出循环
while (findCount > 0);
}
return chuan;
} /// <summary>
/// 算串的气
/// </summary>
/// <param name="chuan"></param>
/// <returns></returns>
public int CountChuanGas(ArrayList chuan)
{
if (chuan == null)
return 0;
int gas = 0;
for (int i = 0; i < chuan.Count; i++)
{
gas += this.CountGas(((Point) chuan[i]).X, ((Point) chuan[i]).Y);
}
return gas;
}
}
}
/// 试走一步,返回能杀死的敌子数组(不更新统计数据)
/// </summary>
/// <param name="color"></param>
/// <param name="row"></param>
/// <param name="col"></param>
/// <returns></returns>
// (这个功能好多地方会使用, 亦可在以后发展成为评估一步棋价值的标准之一)
public ArrayList FindEnemiesCanKill(int color, int row, int col)
{
if (this.stones[row, col] != Board.Empty)
return null;
this.stones[row, col] = color; ArrayList stonesDead = new ArrayList(); // 死子集合
ArrayList stonesVisited = new ArrayList(); // 访问过的点的集合 // 开始判断能够提取的敌方死子
int newx, newy;
for (int i = 0; i < 4; i++)
{
newx = row + offsets[i, 0];
newy = col + offsets[i, 1]; if (newx >= 0 && newx < 19 && newy >= 0 && newy < 19)
{
if (this.stones[newx, newy] == (- color))
{
// 如果目前位置已经在前面某个方向的探索过程中找到, 则不用判断了。
// 因为不同方向的棋子可能是属于同一个串的
if (! stonesVisited.Contains(new Point(newx, newy)))
{
// 寻找包含该位置的串
ArrayList chuan = this.FindChuan(newx, newy);
// 算串的气
int chuanGas = this.CountChuanGas(chuan);
// 加到已访问的列表
stonesVisited.AddRange(chuan); if (chuanGas == 0)
stonesDead.AddRange(chuan);
}
}
}
} // 恢复试落的位置原先的状态
this.stones[row, col] = Board.Empty;
return stonesDead;
} /// <summary>
/// 算气
/// </summary>
/// <param name="row"></param>
/// <param name="col"></param>
/// <returns></returns>
public int CountGas(int row, int col)
{
int gas = 0;
int newx, newy;
for (int i = 0; i < 4; i++)
{
newx = row + Board.offsets[i, 0];
newy = col + Board.offsets[i, 1]; if (newx >= 0 && newx < 19 && newy >= 0 && newy < 19)
{
if (this.stones[newx, newy] == Board.Empty)
gas++;
}
}
return gas;
}
/// <summary>
/// 寻找包含该位置的棋子串
/// </summary>
/// <备注>
/// 该算法的核心思想是广度优先的遍历算法,
/// 粗看循环层次是比较多, 似乎十分繁琐; 细看则条理十分清晰, 逻辑简单
/// 由于定义了每次搜索的点的范围(begin ~ end), 只搜索那些没搜索过的, 所以几乎没有任何冗余的尝试
/// 基本上我认为算法已经最优了.
/// </备注>
/// <param name="row">起始点的 X 坐标</param>
/// <param name="col">起始点的 Y 坐标</param>
/// <returns>搜索到的棋子串(没找到则返回 null)</returns>
public ArrayList FindChuan(int row, int col)
{
ArrayList chuan = null;
int color = this.stones[row, col]; // 当前的颜色 if (this.stones[row, col] == color)
{
chuan = new ArrayList();
// 加入当前点
chuan.Add(new Point(row, col));
// 定义两个游标
int begin = 0;
int end = 0;
int findCount; // 发现的邻居数目, 用于循环结束的判断条件
do
{
findCount = 0;
// begin 到 end 之间的一些点表示没有探索过四周的那些点
for (int i = begin; i <= end; i++)
{
// 对左右上下四个方向进行探索
for (int j = 0; j < 4; j++)
{
int newx = ((Point) chuan[i]).X + offsets[j, 0];
int newy = ((Point) chuan[i]).Y + offsets[j, 1];
// 如果该点在棋盘内, 且颜色相同, 且现有的串中没有, 则加入串
if (newx >= 0 && newx < 19 && newy >= 0 && newy < 19
&& this.stones[newx, newy] == color
&& ! chuan.Contains(new Point(newx, newy)))
{
chuan.Add(new Point(newx, newy));
// 寻找到的邻居计数器加 1
findCount += 1;
}
}
}
// 设定下一个循环要列举的开始和结束游标
begin = end + 1;
end = end + findCount;
}
// 如果本轮搜索的所有点都没有邻居了, 也就表示串搜索结束了, 跳出循环
while (findCount > 0);
}
return chuan;
} /// <summary>
/// 算串的气
/// </summary>
/// <param name="chuan"></param>
/// <returns></returns>
public int CountChuanGas(ArrayList chuan)
{
if (chuan == null)
return 0;
int gas = 0;
for (int i = 0; i < chuan.Count; i++)
{
gas += this.CountGas(((Point) chuan[i]).X, ((Point) chuan[i]).Y);
}
return gas;
}
}
}
解决方案 »
- 事件问题,委托在哪里,求高人解答!
- 怎样通过DataGridView实现数据库的按条件搜索
- log4net 设置级别的节点是什么啊? 在线等
- 在VS2008的MVC模式下如果实现页面的直接跳转
- 请问var frm = document.forms["frmMain"];可以拿到一个什么样的值
- 小弟用C#作webform的毕业设计时遇到一个问题。
- c#,提示当前上下文不存在“jieguo”
- C# UDP通讯 我想我需要被指点一下
- 请问这个问题怎么解决呀!(急)
- 文档的写操作 没分了
- webForm下,DataGrid 中添加了一个模板(CheckBox控件)怎么在这个控件中写代码?
- 如何执行脚本文件
另外...围棋可以翻译成I-go,如果不喜欢这个从小日本过来的音译,翻译成HandTalk也不错
提子不要用kill,血淋淋的...难受...,建议改用take...
enemy 改成 opponent...
这个...
http://member.netease.com/~luwentao/wswq/shuyu.html
围棋术语中英文对照
关于这方面的研究也在进行...
但目前恐怕还没有什么好的结果...
即使是手谈这样强的...还是可以让它9子以上获胜...
实在没有看到比较好的研究围棋算法的网站...
如果楼主想找资料,自己用google搜索好了...