x01.Weiqi.8: 一点改进

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

1.关于显示

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

 1 void Init()
 2         {
 3             // 线
 4             for (int i = 0; i < 19; i++) {
 5                 m_LinesH[i] = new Line();
 6                 m_LinesH[i].Stroke = Brushes.Black;
 7                 m_Canvas.Children.Add(m_LinesH[i]);
 8
 9                 m_LinesV[i] = new Line();
10                 m_LinesV[i].Stroke = Brushes.Black;
11                 m_Canvas.Children.Add(m_LinesV[i]);
12             }
13
14             // 星
15             for (int j = 0; j < 3; j++) {
16                 for (int i = 0; i < 3; i++) {
17                     m_Stars[i, j] = new Ellipse();
18                     m_Stars[i, j].Fill = Brushes.Black;
19                     m_Canvas.Children.Add(m_Stars[i, j]);
20                 }
21             }
22
23             for (int i = 0; i < 19; i++) {
24                 for (int j = 0; j < 19; j++) {
25                     m_Stones[i, j] = new Ellipse();
26                     m_Stones[i, j].Visibility = Visibility.Hidden;
27                     m_Canvas.Children.Add(m_Stones[i, j]);
28
29                     m_Numbers[i, j] = new TextBlock();
30                     m_Numbers[i, j].Background = Brushes.Transparent;
31                     m_Numbers[i, j].Visibility = Visibility.Hidden;
32                     m_Canvas.Children.Add(m_Numbers[i, j]);
33
34                     m_Steps[i, j] = new Step();
35                     m_Steps[i, j].Row = i;
36                     m_Steps[i, j].Col = j;
37                     m_EmptySteps.Add(m_Steps[i, j]);
38                     m_AllSteps.Add(m_Steps[i, j]);
39                 }
40             }
41
42             // 当前标志
43             m_CurrentRect.Visibility = System.Windows.Visibility.Hidden;
44             m_CurrentRect.Fill = Brushes.Red;
45             m_Canvas.Children.Add(m_CurrentRect);
46
47             for (int i = 0; i < 19; i++) {
48                 for (int j = 0; j < 19; j++) {
49                     Rectangle rect = new Rectangle();
50                     rect.Visibility = System.Windows.Visibility.Hidden;
51                     m_EmptyRects[i, j] = rect;
52                     m_Canvas.Children.Add(m_EmptyRects[i,j]);
53
54                 }
55             }
56         }

Init()

  1 public void Redraw()
  2         {
  3             // 画线
  4             for (int i = 0; i < 19; i++) {
  5                 Line l = m_LinesH[i];
  6                 int y = i * StoneSize + StoneSize / 2;
  7                 l.X1 = StoneSize / 2;
  8                 l.Y1 = y;
  9                 l.X2 = 19 * StoneSize - StoneSize / 2;
 10                 l.Y2 = y;
 11
 12                 l = m_LinesV[i];
 13                 int x = i * StoneSize + StoneSize / 2;
 14                 l.X1 = x;
 15                 l.Y1 = StoneSize / 2;
 16                 l.X2 = x;
 17                 l.Y2 = 19 * StoneSize - StoneSize / 2;
 18             }
 19
 20             // 画星
 21             for (int j = 0; j < 3; j++) {
 22                 for (int i = 0; i < 3; i++) {
 23                     Ellipse e = m_Stars[i, j];
 24                     e.Width = e.Height = StoneSize / 3;
 25                     double left = 4 * StoneSize + j * 6 * StoneSize - StoneSize / 2 - e.Width / 2;
 26                     double top = 4 * StoneSize + i * 6 * StoneSize - StoneSize / 2 - e.Height / 2;
 27                     Canvas.SetLeft(e, left);
 28                     Canvas.SetTop(e, top);
 29                 }
 30             }
 31
 32             // Stones and Numbers
 33             for (int i = 0; i < 19; i++) {
 34                 for (int j = 0; j < 19; j++) {
 35                     var stone = m_Stones[i, j];
 36                     stone.Width = stone.Height = StoneSize;
 37                     Canvas.SetLeft(stone, j * StoneSize);
 38                     Canvas.SetTop(stone, i * StoneSize);
 39
 40                     ShowNumber(i, j, m_Steps[i, j].StepCount);
 41                 }
 42             }
 43
 44             // 点目标志
 45             if (IsShowMesh)
 46                 for (int i = 0; i < 19; i++) {
 47                     for (int j = 0; j < 19; j++) {
 48                         var rect = m_EmptyRects[i, j];
 49                         rect.Width = rect.Height = m_CurrentRect.Width;
 50                         double offset = (StoneSize - rect.Width) / 2.0;
 51                         Canvas.SetLeft(rect, j * StoneSize + offset);
 52                         Canvas.SetTop(rect, i * StoneSize + offset);
 53                     }
 54                 }
 55         }
 56
 57         public bool NextOne(int row, int col)
 58         {
 59             if (m_Steps[row, col].StoneColor != StoneColor.Empty)
 60                 return false;
 61             if (m_BanOnce.Row == row && m_BanOnce.Col == col) {
 62                 return false;
 63             }
 64             m_BanOnce.Row = m_BanOnce.Col = -1;
 65
 66             DrawStep(row, col);
 67             bool isBlack;
 68             if (m_Steps[row, col].StoneColor == StoneColor.Black) {
 69                 m_BlackSteps.Add(m_Steps[row, col]);
 70                 isBlack = true;
 71             } else {
 72                 m_WhiteSteps.Add(m_Steps[row, col]);
 73                 isBlack = false;
 74             }
 75             m_EmptySteps.Remove(m_Steps[row, col]);
 76
 77             UpdateBlackBlocks();
 78             UpdateWhiteBlocks();
 79             if (isBlack) {
 80                 if (!UpdateDeadBlocks(m_WhiteBlocks))
 81                     UpdateDeadBlocks(m_BlackBlocks);
 82             } else {
 83                 if (!UpdateDeadBlocks(m_BlackBlocks))
 84                     UpdateDeadBlocks(m_WhiteBlocks);
 85             }
 86
 87             MoveCurrentRect();
 88
 89             m_StepCount++;
 90
 91             StoneColor selfColor = isBlack ? StoneColor.Black : StoneColor.White;
 92             bool isKillSelf = m_DeadBlocks.ContainsKey(m_StepCount - 1)
 93                     && m_DeadBlocks[m_StepCount - 1].Steps.Count == 1
 94                     && m_DeadBlocks[m_StepCount - 1].Steps[0].StoneColor == selfColor;
 95             if (isKillSelf) {
 96                 m_DeadBlocks.Remove(m_StepCount - 1);
 97                 BackOne();
 98                 return false;
 99             }
100
101             return true;
102         }

Redraw()

2.关于提子

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

 1 //   +
 2         // + + +    与 step 相连的棋子,包含自身
 3         //   +        根据 color 参数决定是所有,同色,黑色,白色,还是空色。
 4         List<Step> LinkSteps(Step step, StoneColor color = StoneColor.Empty)
 5         {
 6             List<Step> links = new List<Step>();
 7             for (int i = -1; i < 2; i++) {
 8                 for (int j = -1; j < 2; j++) {
 9                     if (i == j || i == -j) {
10                         continue;
11                     }
12                     if (InRange(step.Row + i, step.Col + j)) {
13                         links.Add(m_Steps[step.Row + i, step.Col + j]);
14                     }
15                 }
16             }
17             links.Add(step);
18             if (color == StoneColor.All) {
19                 return links;
20             } else {
21                 links.RemoveAll(l => l.StoneColor != color);
22                 return links;
23             }
24         }

LinkSteps()

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

时间: 2024-10-11 12:19:21

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

x01.Weiqi.12: 定式布局

定式 下一步当将定式保存到数据库中,如布局中的代码所示,但其初始的代码更有利于理解.以小飞挂为例: // 0 // + 0 0 // + // // + List<Pos> P_LuStar_UpFlyOne { get { var temp = new List<Pos>(); temp.Add(new Pos(3, 3)); // 第一步:左上星 temp.Add(new Pos(2, 5)); // 第二步:小飞挂 temp.Add(new Pos(5, 2)); // 第三

x01.Weiqi.7: 调整重绘

GitHub 谁方便谁拍,谁重要拍谁.在这个砖头满天飞的时代,一个好的生态显得尤为重要.  红颜小头发,要的很简单. 也许成绝唱,只因鱼心火. 姚贝福娃的离去,除感叹人生无常外,活着做点有意义的事情,同样显得尤为重要. 数年前为学习人工智能,写了围棋程序,却发现其难度超出了我的想象.特将其放到 GitHub 上,希望有人斧正.注意,是斧正,而非小修小改. 调整重绘 窗口大小改变时,棋盘也要作相应的重绘.这个比较简单,我的方法是把 BoardBase 类中的 m_sbSteps 字段改成 publ

x01.Weiqi.9: 点目功能

添加点目功能,虽不中,不远也.还是先看看截图吧. 确保其可行,再看一张: 其点目结果,还是比较令人满意的.这主要得益于多遍扫描,如编译器.如下代码可证: 1 private void InitMeshes() 2 { 3 UpdateMeshes1(); 4 5 if (StepCount < 120) return; 6 7 UpdateMeshes2(); 8 UpdateMeshes3(); 9 UpdateMeshes4(5); 10 UpdateMeshes4(8); // 二次扫描有

iScroll-5拉动刷新(pull-to-refresh)功能实现与iScroll-4上拉刷新的一点改进

近来在学习移动设备的应用开发,接触了jQuery mobile,在网上查阅相关资料时发现一个叫”iScroll“的小插件.其实这个iScroll插件跟jQuery mobile没有多大关系,并不是基于jQuery mobile类库开发的js插件,是一个独立的js插件,使用它时不必预先引用jquery或jquery mobile类库.关于iScroll的详细介绍可以去它的官网了解或者去GitHub(https://github.com/cubiq/iscroll/)下载它的源码学习.iScroll

x01.Weiqi.10: 死活问题

估计得不错,点目后,仅一个方法:UpdateMeshes5() 就完美解决了梅花六.刀把五.斗笠四.盘角曲四等死活问题.先来看看效果图: 其代码如下: 1 void UpdateMeshes5(bool isFirst = true) 2 { 3 UpdateAllMeshBlocks(); 4 5 m_BlackMeshBlocks.ForEach(block => { 6 var poses = block.Poses.ToList(); 7 block.Poses.ForEach(p =>

关于Spring JDBC RowMapper的一点改进思路

[注]通常我们使用RowMapper(比如ParameterizedRowMapper),都需要定义好查询字段,如果使用别名就没办法了.还要比如加入group,或者联合查询,也不能够使用,除非不想要非主体Bean之外的字段,那么只能用Map接收返回结果了,或者直接实现RowMapper.基于这一点,提出一个稍微通用的解决思路:所有的Bean都继承一个基类Bean,里面放一个Map(就是存放那些Bean没有指定的字段了,比如sum.count.avg - 各种查询字段或者别名),参考BeanPro

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

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 原文在: http://oleb.net/blog/2010/12/animating-drawing-of-cgpath-with-cashapelayer/ 原理说明在: http://www.codeproject.com/Articles/109729/Low-level-text-rendering 文章写得非常棒!推荐大家阅读. 不过其源代码运行有

x01.Weiqi.13: 鼎力推荐

鼎力推荐 : 点击后即可观看,小伙子讲的很有深度. 说到深度,自然离不了深度学习.AlphaGo 的横空出世,似乎很有学习的必要. MuGo: 点击下载后,发现是 python,自然免不了一番学习,好在不求深入,倒也花不了多少时间. 运行步骤如下: 1. ubuntu 中 python3 已安装,所以只需安装 pip3 即可: sudo  apt  install python3-pip 2. 安装 tensorflow: sudo pip3 install tensorflow 我安装时,似乎

x01.Weiqi.11: 神来之笔

在围棋中,一子两用,可谓妙手,而一子三用,则可称之为神来之笔.在解决征子问题时,一不小心,也来了个神来之笔,其代码如下: // 征子判断,p1, p2 为气,p2 为前进方向,p 为逃跑之子. bool CanLevy(Pos p1, Pos p2, Pos p, bool isBlack = true) { if (!IsCusp(p1, p2)) return true; if (p == m_InvalidPos) return true; List<Pos> selfPoses = i