原来的代码全部删除,进行了深层次重构,得其意而忘其言。得意之处有二:

1.关于显示

以 StoneSize 属性为依托,在 set 中加了一句:Width = Height = m_StoneSize * 19;以此来控制棋盘大小。所有的对象在 Init() 方法中创建,而具体的渲染在 Redraw() 方法中完成。这种创建与重绘相分开的办法,使调整大小时进行重绘更简单易行。这两个方法的代码如下:

 void Init()
{
// 线
for (int i = ; i < ; i++) {
m_LinesH[i] = new Line();
m_LinesH[i].Stroke = Brushes.Black;
m_Canvas.Children.Add(m_LinesH[i]); m_LinesV[i] = new Line();
m_LinesV[i].Stroke = Brushes.Black;
m_Canvas.Children.Add(m_LinesV[i]);
} // 星
for (int j = ; j < ; j++) {
for (int i = ; i < ; i++) {
m_Stars[i, j] = new Ellipse();
m_Stars[i, j].Fill = Brushes.Black;
m_Canvas.Children.Add(m_Stars[i, j]);
}
} for (int i = ; i < ; i++) {
for (int j = ; j < ; j++) {
m_Stones[i, j] = new Ellipse();
m_Stones[i, j].Visibility = Visibility.Hidden;
m_Canvas.Children.Add(m_Stones[i, j]); m_Numbers[i, j] = new TextBlock();
m_Numbers[i, j].Background = Brushes.Transparent;
m_Numbers[i, j].Visibility = Visibility.Hidden;
m_Canvas.Children.Add(m_Numbers[i, j]); m_Steps[i, j] = new Step();
m_Steps[i, j].Row = i;
m_Steps[i, j].Col = j;
m_EmptySteps.Add(m_Steps[i, j]);
m_AllSteps.Add(m_Steps[i, j]);
}
} // 当前标志
m_CurrentRect.Visibility = System.Windows.Visibility.Hidden;
m_CurrentRect.Fill = Brushes.Red;
m_Canvas.Children.Add(m_CurrentRect); for (int i = ; i < ; i++) {
for (int j = ; j < ; j++) {
Rectangle rect = new Rectangle();
rect.Visibility = System.Windows.Visibility.Hidden;
m_EmptyRects[i, j] = rect;
m_Canvas.Children.Add(m_EmptyRects[i,j]); }
}
}

Init()

 public void Redraw()
{
// 画线
for (int i = ; i < ; i++) {
Line l = m_LinesH[i];
int y = i * StoneSize + StoneSize / ;
l.X1 = StoneSize / ;
l.Y1 = y;
l.X2 = * StoneSize - StoneSize / ;
l.Y2 = y; l = m_LinesV[i];
int x = i * StoneSize + StoneSize / ;
l.X1 = x;
l.Y1 = StoneSize / ;
l.X2 = x;
l.Y2 = * StoneSize - StoneSize / ;
} // 画星
for (int j = ; j < ; j++) {
for (int i = ; i < ; i++) {
Ellipse e = m_Stars[i, j];
e.Width = e.Height = StoneSize / ;
double left = * StoneSize + j * * StoneSize - StoneSize / - e.Width / ;
double top = * StoneSize + i * * StoneSize - StoneSize / - e.Height / ;
Canvas.SetLeft(e, left);
Canvas.SetTop(e, top);
}
} // Stones and Numbers
for (int i = ; i < ; i++) {
for (int j = ; j < ; j++) {
var stone = m_Stones[i, j];
stone.Width = stone.Height = StoneSize;
Canvas.SetLeft(stone, j * StoneSize);
Canvas.SetTop(stone, i * StoneSize); ShowNumber(i, j, m_Steps[i, j].StepCount);
}
} // 点目标志
if (IsShowMesh)
for (int i = ; i < ; i++) {
for (int j = ; j < ; j++) {
var rect = m_EmptyRects[i, j];
rect.Width = rect.Height = m_CurrentRect.Width;
double offset = (StoneSize - rect.Width) / 2.0;
Canvas.SetLeft(rect, j * StoneSize + offset);
Canvas.SetTop(rect, i * StoneSize + offset);
}
}
} public bool NextOne(int row, int col)
{
if (m_Steps[row, col].StoneColor != StoneColor.Empty)
return false;
if (m_BanOnce.Row == row && m_BanOnce.Col == col) {
return false;
}
m_BanOnce.Row = m_BanOnce.Col = -; DrawStep(row, col);
bool isBlack;
if (m_Steps[row, col].StoneColor == StoneColor.Black) {
m_BlackSteps.Add(m_Steps[row, col]);
isBlack = true;
} else {
m_WhiteSteps.Add(m_Steps[row, col]);
isBlack = false;
}
m_EmptySteps.Remove(m_Steps[row, col]); UpdateBlackBlocks();
UpdateWhiteBlocks();
if (isBlack) {
if (!UpdateDeadBlocks(m_WhiteBlocks))
UpdateDeadBlocks(m_BlackBlocks);
} else {
if (!UpdateDeadBlocks(m_BlackBlocks))
UpdateDeadBlocks(m_WhiteBlocks);
} MoveCurrentRect(); m_StepCount++; StoneColor selfColor = isBlack ? StoneColor.Black : StoneColor.White;
bool isKillSelf = m_DeadBlocks.ContainsKey(m_StepCount - )
&& m_DeadBlocks[m_StepCount - ].Steps.Count ==
&& m_DeadBlocks[m_StepCount - ].Steps[].StoneColor == selfColor;
if (isKillSelf) {
m_DeadBlocks.Remove(m_StepCount - );
BackOne();
return false;
} return true;
}

Redraw()

2.关于提子

以 LinkSteps()方法为依托,提子不再是上下左右一通乱吃了,而是采用集合的办法,只需看看一块棋有没有气即可。其代码如下:

 //   +
// + + + 与 step 相连的棋子,包含自身
// + 根据 color 参数决定是所有,同色,黑色,白色,还是空色。
List<Step> LinkSteps(Step step, StoneColor color = StoneColor.Empty)
{
List<Step> links = new List<Step>();
for (int i = -; i < ; i++) {
for (int j = -; j < ; j++) {
if (i == j || i == -j) {
continue;
}
if (InRange(step.Row + i, step.Col + j)) {
links.Add(m_Steps[step.Row + i, step.Col + j]);
}
}
}
links.Add(step);
if (color == StoneColor.All) {
return links;
} else {
links.RemoveAll(l => l.StoneColor != color);
return links;
}
}

LinkSteps()

当然,关于劫争,关于悔棋,非深入代码,不能明白。但 LinkSteps()是构成集合的基础。从集合的观点,研究围棋,相信比其他方法更为可行。

x01.Weiqi.8: 一点改进的更多相关文章

  1. x01.Weiqi.12: 定式布局

    定式 下一步当将定式保存到数据库中,如布局中的代码所示,但其初始的代码更有利于理解.以小飞挂为例: // 0 // + 0 0 // + // // + List<Pos> P_LuSta ...

  2. x01.Weiqi.10: 死活问题

    估计得不错,点目后,仅一个方法:UpdateMeshes5() 就完美解决了梅花六.刀把五.斗笠四.盘角曲四等死活问题.先来看看效果图: 其代码如下: void UpdateMeshes5(bool ...

  3. x01.Weiqi.9: 点目功能

    添加点目功能,虽不中,不远也.还是先看看截图吧. 确保其可行,再看一张: 其点目结果,还是比较令人满意的.这主要得益于多遍扫描,如编译器的词法分析阶段,下面的代码可以证明: private void ...

  4. x01.Weiqi.7: 调整重绘

    GitHub 谁方便谁拍,谁重要拍谁.在这个砖头满天飞的时代,一个好的生态显得尤为重要.  红颜小头发,要的很简单. 也许成绝唱,只因鱼断肠. 姚贝福娃的离去,除感叹人生无常外,活着做点有意义的事情, ...

  5. iScroll-5拉动刷新功能实现与iScroll-4上拉刷新的一点改进

    近来在学习移动设备的应用开发,接触了jQuery mobile,在网上查阅相关资料时发现一个叫”iScroll“的小插件.其实这个iScroll插件跟jQuery mobile没有多大关系,并不是基于 ...

  6. x01.Weiqi.11: 神来之笔

    在围棋中,一子两用,可谓妙手,而一子三用,则可称之为神来之笔.在解决征子问题时,一不小心,也来了个神来之笔,其代码如下: // 征子判断,p1, p2 为气,p2 为前进方向,p 为逃跑之子. boo ...

  7. Winform(C#.NET)自动更新组件的使用及部分功能实现(一点改进功能)

    接前两篇继续: Winform(C#.NET)自动更新组件的使用及部分功能实现 Winform(C#.NET)自动更新组件的使用及部分功能实现(续) 借鉴文章:http://www.cnblogs.c ...

  8. x01.Weiqi.13: 鼎力推荐

    鼎力推荐 : 点击后即可观看,小伙子讲的很有深度. 说到深度,自然离不了深度学习.AlphaGo 的横空出世,似乎很有学习的必要. MuGo: 点击下载后,发现是 python,自然免不了一番学习,好 ...

  9. CoreText精彩文字轮廓绘制动画的一点改进

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 原文在: http://oleb.net/blog/2010/ ...

随机推荐

  1. VS2013预览版安装 体验截图

    支持与msdn帐号链接: 不一样的团队管理: 新建项目:

  2. Bootstrap Navbar应用及源码解析

    目的: 用Bootstrap Navbar component 实现一个响应式导航 理解Bootstrap Navbar component是如何工作的(不包括collepse.js) 清楚自己添加一 ...

  3. let与const的区别

    let与const都是只在声明所在的块级作用域内有效. let声明的变量可以改变,值和类型都可以改变,没有限制. const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不 ...

  4. Rafy 领域实体框架示例(1) - 转换传统三层应用程序

    Rafy 领域实体框架发布后,虽然有帮助文档,许多朋友还是反映学习起来比较复杂,希望能开发一个示例程序,展示如何使用 Rafy 领域实体框架所以,本文通过使用 Rafy 领域实体框架来改造一个传统的三 ...

  5. compilation与编译

    关于本配置节的内容不算多,但关于ASP.NET编译的内容还是有一点的,鄙人认为只是了解一下即可,主要影响到部署. 在 App_Code 文件夹中使用多种编程语言 因为 App_Code 文件夹中的源代 ...

  6. 【C#进阶系列】28 基元线程同步构造

    多个线程同时访问共享数据时,线程同步能防止数据损坏.之所以要强调同时,是因为线程同步问题实际上就是计时问题. 不需要线程同步是最理想的情况,因为线程同步一般很繁琐,涉及到线程同步锁的获取和释放,容易遗 ...

  7. struts2+spring的两种整合方式

    也许有些人会因为学习了struts1,会以为struts2.struts1与spring的整合也是一样的,其实这两者相差甚远.下面就来讲解一下struts2与spring的整合两种方案.(部分转载,里 ...

  8. slidedoor滑动门特效

    slidedoor滑动门特效 exportWidth:暴露门的宽度 width imagesWidth:单张图片的宽度width 每道门每次偏移量 translate=imagesWidth-expo ...

  9. html5视频播放插件

    对于HTML5提供的新特性,给前端开发者带来了巨大的激情与动力,减轻了开发者的代码累赘,大大提高了网站性能以及网页的渲染效果.对于低版本的浏览器,由于生产厂商的原因,许多PC端低版本的浏览器还不兼容H ...

  10. arcgis地图数据集合

    一.全国的ArcGIS地图SHP格式数据,覆盖的图层信息量基本齐全,除了ArcGIS之外,其他GIS软件(superMap和MapGIS.MapInfo等等)也是用之,适合为GIS开发提供数据素材. ...