当前位置: 代码迷 >> C# >> x01.Weiqi.8: 1点改进
  详细解决方案

x01.Weiqi.8: 1点改进

热度:122   发布时间:2016-05-05 03:43:41.0
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()是构成集合的基础。从集合的观点,研究围棋,相信比其他方法更为可行。