围棋提子算法
主题词:图,数据结构,递归,分支结构,堆栈,入口坐标恢复,遍历路径
最近用c#语言做围棋打谱软件,想做一个比较全面的围棋提子函数。以前做的是单侧的围棋提子函数,很简明,分左上右下四个方向调用四次围棋提子函数,就可以解决围棋提子问题。如今,自我感觉编程水平提高了,就想调用 一次围棋提子函数就解决围棋提子问题。综合的围棋提子函数主要就是在递归算法里加入分支判断。
围棋盘是图结构,可以映射成数组或者线性链表。围棋提子问题可以抽象为对图的深度优先遍历问题。我采用递归调用进行深度优先遍历,再用分支结构解决围棋提子判断。
围棋提子判断的主要问题集中在:
1,添加分支标记和判断。因为一颗棋子要进行左上右下四个分支的判断和递归调用。
2,递归调用时入口坐标的保存和恢复。多层递归调用会出现棋子坐标的转移。需要保存和恢复每次调用时的入口棋子坐标。用堆栈的方法处理入口棋子坐标很简明有效。
当然,一个完整无错的围棋提子函数,还要解决边界判断,禁入点,打劫等问题。一般用穷举法就可以解决,比如将所有边界的类型都罗列出来,然后逐一判断解决就可以了。
将代码块封装为函数,一般要求该函数的功能尽量单一化,如此也有利于代码复用。一个函数里复合了多个功能,这个函数的用途就很有限了。
我把所有四个方向的围棋提子判断放在一个函数里解决,无非是测试一下自己的编码水平,这并不是好的解决方案。这样做,编码的错误率高了很多,调试排错也很浪费时间。现在还在调试排错进行中......无语。不过,如
果成功,对于提高思维的缜密程度,是一次很好的练习。
周末集中上围棋课,没有时间写代码。周一上午重新调试围棋提子算法,主要是功能和逻辑错误,错误原因是对分支标记的处理有疏漏之处。得到的经验是:标志位的赋值,遍历用的暂时链表的更新,最好放在递归调用的前
后及时处理。围棋提子判断之后,要将棋盘链表初始化。否则,会影响下一次提子判断。
小结:
1、有四个分支的递归函数,if_else嵌套常常达到5层以上,代码结构复杂,逻辑关系复杂,编码时很容易出错。代码的调试和维护也很困难。
2、实用的代码应该是:函数功能单一,代码结构简明,逻辑关系清晰,易于维护和调试。
3、编写成功有分支结构的围棋提子函数,对自己的复杂逻辑思维和调试代码的耐心是一次很好的锻炼。