问题

把围棋棋盘上下边和左右边连起来,变成面包圈,下棋策略会有什么变化?

回答
想象一下,你手里不是一块平整的围棋棋盘,而是一个带着点弹性、光滑圆润的呼啦圈。棋子落在上面,不再是孤立的点,而是可以顺着“边”相互连接,延伸到你视野的另一端。这就是把围棋棋盘的上下左右边对折粘合,变成了“棋盘面包圈”。

这一下,原本熟悉的棋盘几何瞬间颠覆了。我们得抛开那些根深蒂固的边角思维,重新审视整个空间。

首先,最重要的变化是“无边无际”的感觉。

在方形棋盘上,边是天然的屏障和限制。占领边角意味着获得相对稳定的根据地,也意味着棋子会受到边线的阻碍,无法轻易绕过。但在这个面包圈上,边线不再是终点,而是无限的延续。你从棋盘的一边冲出去,可以毫不费力地出现在另一边。

这意味着什么?

“势力”的流动性极大增强: 过去,你围住一方天地,那方天地相对独立。现在,你的势力可以轻易地“绕过去”,连接到你看似遥远的地方。一块看似弱小的棋子,如果能够巧妙地利用“绕边”的特性,就能瞬间成为威胁另一片区域的关键。
“眼”的构造会变得奇特: 在方形棋盘上,一个眼通常需要四颗棋子形成一个空点,或者两颗棋子间隔一格。在面包圈上,你只需要两颗棋子,如果它们能通过“绕边”形成一个封闭的通道,就能组成一个“无限”的眼。这会让活棋的难度和可能性都发生巨大改变。一个棋子被切断,但只要它的另一端还能通过绕边连接到大部队,它就不算真正被孤立。
攻防的判断尺度不同: 你不再需要担心棋子被逼到边上无路可走。相反,边线变成了一个可以随时“借力”的通道。你的攻击可以从一个方向发起,然后通过绕边突然出现在另一个方向,让对手防不胜防。防守也一样,被压制的棋子可以尝试向“另一侧”逃脱,而不是被困死在角落。

其次,“连接”的概念会变得更加复杂和重要。

在方形棋盘上,连接通常是直接相邻或者间隔一格的直线关系。在面包圈上,连接不仅仅是直接的,还可以是“绕行的”。

全局的联系感更强: 整个棋盘变成了一个巨大的网络。任何两点之间,都有无数条路径可以连接。你的棋子不仅仅是在某个局部作战,它们是在参与整个棋盘的“串联”。
“断点”的意义改变: 过去,你只要切断对方的棋路,就能孤立对方的棋子。在面包圈上,你可能切断了眼前的一小段路,但对方可以通过“绕边”重新连接。这就要求你在判断“死活”和“连接”时,必须考虑全局的绕行可能性。
对“形”的要求更高: 你需要创造出能够利用绕行特性的棋形。例如,某些看似薄弱的连接,在面包圈上反而因为绕行的存在而变得难以被切断。你需要培养出对这种全局连接优势的敏感度。

那么,具体的下棋策略会有哪些调整呢?

1. 早期布局的思考转变:
边角的价值不再绝对: 过去,边角是必争之地,有天然的保护。在面包圈上,边角依然可以提供“第一层”的连接优势,但它们不再是“终点”,而是“起点”。过早地在边角下太多子,可能是一种“资源浪费”,因为这些子可以轻易地绕过去。
中心开阔,边缘活跃: 棋盘中心的重要性会相对提升,因为中心可以连接到任何“边”。而边缘则会成为棋子活跃、互相呼应的关键区域,通过边缘的“穿梭”来建立全局的联系。
尝试更“连续”的布局: 布局时可能更倾向于将棋子以一种连续的、可以互相支援的形态展开,而不是孤立地占领某个角。

2. 中盘战斗的变化:
“围空”的定义模糊: 传统的“围空”,即圈地为“眼”,在这里会变得很奇怪。你可能围出了一个“空”,但对方的棋子可以从你背后的“边”绕进来。这就迫使我们重新定义“空”的价值,也许更重要的是棋子的“联系”和“活动空间”,而不是封闭的区域。
攻击的灵活性: 你可以用棋子去“拉扯”对方的阵型。当对方认为你已经被困住时,你随时可以从意想不到的地方发起反击。这就像一个瑜伽大师,身体可以做出各种不可思议的扭转和连接。
“弃子”的策略会不同: 某个看似被围死的棋子,如果它的另一端可以通过绕边逃脱,那么弃掉它,可能只是为了让另一部分的棋子更好地形成全局的联系。

3. 死活判断的挑战:
“打劫”的复杂化: 传统的“打劫”判死活,依赖于棋子之间的相对位置。在面包圈上,一个劫争可能因为对方的棋子“绕过”了棋盘,而变得完全不同。你需要考虑的是,整个“劫争”的链条能否被全局的连接打破。
活棋的定义: 拥有“足够活动空间”和“不被全局孤立”的棋子,才是活棋。即使棋子之间没有直接的“眼”,只要它们能通过绕边互相支援,就可能避免被杀死。

4. 劫材的利用:
在面包圈上,劫材的价值和作用可能会更加难以估量。因为劫材可能不仅影响到局部,还能通过全局的连接来改变整个棋盘的平衡。

总而言之,在“棋盘面包圈”上,围棋将从一场在平面上进行的攻防战,变成一场在“曲面上”进行的、更强调全局联系和空间流动性的博弈。我们需要放弃对“边角”的执念,学会拥抱“无限的连接”和“意想不到的绕行”。这将是一种更加抽象、更加考验全局观和空间想象力的围棋。想想看,这就像从平面几何一下子跳到了拓扑学,一切规则都跟着变了。挑战虽大,但可能性也无比迷人。

网友意见

user avatar

大开脑洞:完美的棋盘是什么样的

潘达按:本文作者 @萤-时光灯 ,写这篇文章的灵感来自于一次阅读刘慈欣小说时候突发的畅想。本文首发于微信公众号:奇略研究所。潘达参与编辑本文。

————————————————————————————————————————

从AIphaGo到超现实数,围棋始终是工程师们的沙盘,数学宝宝们的游乐场。不过,这些科学家研究的对象都是下棋的策略。今天就让我们来返璞归真一下,站在巨人的肩上,从数学的角度来解读一下承载这种美丽游戏的背景——棋盘吧。

围棋的棋盘是一个19x19的正方形,我们叫它19路棋盘。古代的时候也有用17路棋盘的。小朋友在刚学棋的时候也会用到13路和9路的棋盘。我们日常会用到的围棋盘都是这些正方形的。也有些人创造性地使用地图形状的棋盘,但是在我看来,这些都不是最完美的棋盘。

完美的棋盘,首先应该没有“特殊”的交叉点——每个交叉点都应该恰好与另外四个交叉点相邻,不多不少。下面这张同心圆的棋盘就可以满足此要求。

那么,可以更给力一点吗?

当然是可以的 。

上面那张同心圆的棋盘,虽然每个点确实只有四个邻点,而且没有了“角”,但还有里、外两条“边”,仍不够对称。更完美的棋盘,在没有棋子的时候,应该是混沌一片,处处都是对称的。无论第一手下在哪里,都是一样的。第一手过后才有了两极,有了策略,有了胜负。

想要这样的棋盘其实很容易。只需要把这个正方形的棋盘卷一卷,卷成一个圆柱型,然后再折一折,折成一个甜甜圈就可以了。这里我们定义1=19, A=T,这样一个19路的普通棋盘就变成了18路的甜甜圈棋盘。

当然,已经有会玩的棋友想在我前面了。在LittleGolem这个网站上(感谢 @龚渠成 的推荐),就有一场正在进行的甜甜圈围棋锦标赛,有几十位棋友参加。(littlegolem.net/jsp/in/)上图的这张棋谱是两位高水平的爱好者在甜甜圈棋谱上的实战。请读者注意,这张棋盘实际上只有中间橙色的11路,周边灰色的部分只是辅助对弈者直观理解甜甜圈棋盘的。

可以看到,如果棋子下在了某一个角上,棋盘的灰色部分也对应地放上三枚棋子。假设棋子下在了边上,我们要同时在对面的边上也放上一样颜色的棋子。当然还有计算边上和角上的棋子的气的时候,要把对面的那一气也算进去。在网络围棋的时代,要实现这样一个棋盘太容易了,只需要用上面的定义,就可以把一个看上去方方正正的棋盘卷成一个甜甜圈棋盘。当然,这样还有很多不足,比如很多人会习惯性的忽略对手从棋盘的另一面搞突袭。这都是棋子间的距离不够直观导致的。也许正是因为这样的不足,所以这种理论上完美的棋盘只有少数人在玩。

(潘达按:别吐槽我离题啊,这段已经点题了!具体的甜甜圈围棋战略,可以看LittleGolem上的棋谱。)

那么,可以更更给力一点吗?

当然是可以的。

有没有可能把甜甜圈围棋盘搬到现实中来呢?有一位不愿意透露姓名的西方围棋爱好者,兼能工巧匠,就做出了一个真正的甜甜圈棋盘。

三十八条交叉的圆形铁丝,组成了纵横十九道的甜甜圈棋盘。这里的棋子也是特制的,在中心划了十字槽,可以嵌在交叉点上。

可惜,如此漂亮的实物甜甜圈棋盘,仍有几处瑕疵。在这个甜甜圈棋盘上,里圈的格子特别小,而棋盘的纵线也会比横线短很多,因此每个格子都不再是正方形的了。棋盘格子大小不相等,给棋手直观理解棋局带来了困难。比如离某颗棋子最远的地方在哪里,这种简单的策略也需要额外的思考时间。

那么,可以更更更给力一点吗?

当然还是可以的。

数学上已经有前辈把我们所遇到的这些难题通通解决了。这个人就是约翰·纳什(John Nash)。你可能在经济学领域或者是在他对博弈论的贡献里听说过他的名字。你也可能看过以他的传记拍成的电影《美丽心灵》。电影里有他和好基友在校园里下围棋的场景。纳什就是这样,润物细无声地帮我们解决了上文提到的所有问题,但是却没有向大家透露,他解决的这些问题与围棋有什么关系。不过我想,懂一点围棋和数学的人看到他的嵌入理论(Nash Embedding Theorems)的时候,不难联想到围棋的棋盘。

纳什的嵌入理论就是做了两件事(为了不引入更多术语,我们只讨论甜甜圈棋盘这一种情况。嵌入理论可以应用在更广泛的领域上)。第一件事,嵌入理论可以把平面的正方形棋盘‘折’成一个类似甜甜圈的形状,使得棋盘上的每一个格子仍然保持相等的大小。这一步用到的具体定理又叫Nash-Kuiper定理,它保证了这种折叠的存在。而近年,一个法国数学家团队完成了这种折叠的具体构造,像是一个螺纹装饰的甜甜圈,见下图。

实现螺纹甜甜圈的技术挺难的,需要在普通甜甜圈的基础上做数次名为“起皱”的迭代,相当于一层层地给甜甜圈刻上螺纹。甜甜圈上螺纹的作用是,使得甜甜圈棋盘上每一格的长宽都相等。像这样保持原有图形距离关系的折叠,数学术语叫做等距映射(isometry)。

下图给出了折叠前的正方形棋盘,与折叠后螺纹甜甜圈棋盘上曲线的对应关系。正方形棋盘上原本的纵线(下图左方黑色纵线),在折叠后变成了螺纹甜甜圈上的一个截面的边缘(下图右方黑色的“雪花形”曲线)。熟悉数学的读者可能已经看出来,这条雪花形曲线是一种分形(fractal)。

那么,可以更更更更给力一点吗?

当然仍然是可以的。

我们历经艰险做出了螺纹甜甜圈形棋盘,但它仍有一个明显的缺陷:不够光滑。光滑在数学上的含义是,这个曲面上每个点的切面都是可以算出来的。但是螺纹甜甜圈棋盘,首先它视觉上皱皱巴巴的我们人类不太可能用它下棋。其次,它数学上也不完美,虽然它每个点的切面都能算出来,但是某些局部的弯曲程度却是不连续的。用数学语言说,这些局部的二次导数是无法定义的。综上所述,我们必须通过第二步来完善这个棋盘。当然,得到这个结果已经很厉害了,手残党如我折出的棋盘有棱有角,切面都不能保证存在的呀。

第二步,把甜甜圈上任意多的点放到一个高维度的欧几里得空间,并且保留了原有的甜甜圈上每个点之间的距离关系。在这个新的高维的棋盘上,棋盘的面确实是平滑的,你可以对每个点算导数算到地老天荒。而且视觉上,我们上一步被折的皱皱巴巴的棋盘,在这一步重新得以平展开了。纳什证明了对于甜甜圈这样的m=2曲面来说,寻找嵌入所需要的维度数不会超过 m^2+5m+3=17维。不要被这么高的维度吓到,这只是一个上限。可以作用于任何形状的甜甜圈上任意的点。而我们的棋盘可能更特殊,所以幸运的话可能不需要那么多维度就可以解决问题了。

光说不练假把式。下面就让我们从4路开始,来体验一下这个高(维度)大(脑洞)上(档次)的甜甜圈棋盘吧。那我们先从5x5的正方形棋盘开始,给每个点都标上坐标。注意边和角的坐标都是重复的。一共有16个坐标。

然后,我们算一下每两个点之间的距离,从白色方块开始我们有可能走出并,尖,单关跳,小飞和象步。但是大飞和拆二就不行了。

然后,我们拿出一个四维的立方体。把立方体的 16个顶点依次标上原来的坐标。一个闪闪发光的四维甜甜圈棋盘就做好了。

验证一下,在四维立方体上,同样任意两点之间的距离,同样起于白色方块我们可以得到和平面上一样的结果。

那么,还可以更更更更更给力一点吗?

额…… 这个问题,我也遇到困难了。刚才我示范的是四路棋盘,但更高路数的棋盘,我也不知道答案。

3路棋盘在三维里的光滑嵌入我猜测是行不通的。如果4路棋盘需要4维空间实现嵌入,那么5路棋盘需要几维空间呢?17路,19路棋盘,是不是就需要用到最高的17维才能嵌入了呢?我在这里抛砖引玉,希望读者中有大牛能完美地解答这个开放性问题。

不过,无论是这个完美的棋盘是需要嵌入四维空间,还是十七维空间,想在这个棋盘上下棋,首先我们得进入高维空间呢。读者朋友们,如果做出了这张完美棋盘,那我们就在高维空间见面下棋吧!

user avatar

最后附上福利——

先看具体的例子感受一下:

例 1

上图局面在正常棋盘下,黑棋总是差一气,最终被提吃,但是在环面 的情况又是如何呢?

黑长,我们看到黑棋实际上有三口气,

我们知道白棋暂时提子无望。不过我想让白棋强杀一下黑棋:

  • 如果打吃在右(左)边(其实这个时候已经没有左右之分,但是限制在局部而言是可以这么说的,上下也是同理),那么黑棋容易逃脱;
  • 如果打吃在下方(实际上是上方),

这个时候,白棋被叫吃,只好反叫吃,黑棋弃子逃跑,

这个时候出现了奇观,黑棋出路太多,跑得太快,白棋吃子失败。

例 2

至于征吃:



黑棋沿着 上同胚于 的闭合曲线逃跑,这当然回魂乏术了。

分析

正如上一位网友回答,是紧致无边流形,所以每一个点都属于环面的内点,由于环面高度对称性,所以“战略要点”就失去了意义,因为每一个点都是一样的。

反观我们通常的棋盘,正是由于角部、边界的特殊性,所以在吃子、围空提供了普通内点不具有的先天优势,于是变成了“兵家必争”。

回到环面。所以,单纯地吃子恐怕是很困难的,因为逃跑太容易了,这个与我们在通常棋盘打吃中腹的子一样困难。所以策略是围空优先,顺便侵消对方的实地。这个时候考验的是玩家对中腹能力的掌控。

最后说贴目,这个时候先手优势太小了,肯定不能贴七目半了,我感觉先手价值应该是两子。

福利

我之前写过一个围棋程序,在那个基础上稍加改动即可得到环面上的围棋(R 语言)——

       GoT2 <- function(n=19) {     ###初始设置     ##构造棋盘     if (!interactive()) return()     par(mar = rep(0, 4),bg = rgb(0.9296875, 0.6757812, 0.0546875))     plot(1:n, type = "n", xlim = c(1, n), ylim = c(0, n), axes = FALSE, xlab = "",          ylab = "", bty = "o", lab = c(n, n, 1))     text( 3,0,"落子无悔",cex=1)     text(17,0,"一生好走",cex=1)     segments(1, 1:n, n, 1:n)     segments(1:n, 1, 1:n, n)     points(rep(c(4, 10, 16), 3), rep(c(4, 10, 16), each = 3),           pch = 19, cex = 1.2)        box()      ##四大列表初始设置     playedlist <- list(c(),c())    #当前盘面     vplay <-c()     history <- list(list())    #历史记录     re <- 0    #悔棋指标     conset <- list(list(),list())    #连通分支列表,是二重嵌套列表,第一子列表属黑棋,第二属白棋     bouset <- list(list(0+0i),list(0+0i))    #连通分支边界列表,同上     hiscon <- list(list())     hisbou <- list(list())     ncb=c(0,0)    #分支数     ntake <- c(0,0);eat <- 0     hisncb <- list()     hisntake <- list()            ##棋盘特殊位置     SW<-1+1i    #棋盘四角     SE<-19+1i     NE<-19+19i     NW<-1+19i     S<- 2:18+1i    #棋盘四边(不含角)     E<- complex(0,19,2:18)     N<- 2:18+19i     W<- complex(0,1,2:18)     dire<-c(1i,-1i,-1,1)    #棋盘四合      ##边界函数Bd(从中去掉历史位置即可得到“气”)     Bd<-function(A)     {          B=c()          for(a in A)          {              pa <- a+dire                pa <- complex(0, Re(pa)%%19, Im(pa)%%19)              for(i in 1:4)              {                  if(Re(pa[i])==0)pa[i]<-complex(0,19,Im(pa[i]))                  if(Im(pa[i])==0)pa[i]<-complex(0,Re(pa[i]),19)              }              for(i in pa) if(!is.element(i,A)) B=c(B,i)          }          B     }      ##提子     take <- function(A)     {         if(is.element(SE,A))         {             points(19,1, cex = 3, pch = 19, col = rgb(0.9296875, 0.6757812, 0.0546875))             segments(18.5,1,19,1)             segments(19,1,19,1.5)             A <- setdiff(A,SE)         }         if(is.element(SW,A))         {             points(1,1, cex = 3, pch = 19, col = rgb(0.9296875, 0.6757812, 0.0546875))             segments(1,1,1.5,1)             segments(1,1,1,1.5)             A <- setdiff(A,SW)         }         if(is.element(NE,A))         {             points(19,19, cex = 3, pch = 19, col = rgb(0.9296875, 0.6757812, 0.0546875))             segments(18.5,19,19,19)             segments(19,18.5,19,19)             A <- setdiff(A,NE)         }         if(is.element(NW,A))         {             points(1,19, cex = 3, pch = 19, col = rgb(0.9296875, 0.6757812, 0.0546875))             segments(1,19,1.5,19)             segments(1,18.5,1,19)             A <- setdiff(A,NW)         }         EE <- intersect(E,A);WW <- intersect(W,A)         SS <- intersect(S,A);NN <- intersect(N,A)         A <- setdiff(A,c(EE,WW,SS,NN))         if(length(A)>0)         {             x <- Re(A);y <- Im(A)             points(x,y, cex = 3, pch = 19, col = rgb(0.9296875, 0.6757812, 0.0546875))             segments(x-0.5,y,x+0.5,y)             segments(x,y-0.5,x,y+0.5)         }         if(length(EE)>0)         {             x <- Re(EE);y <- Im(EE)             points(x,y, cex = 3, pch = 19, col = rgb(0.9296875, 0.6757812, 0.0546875))             segments(x-0.5,y,x,y)             segments(x,y-0.5,x,y+0.5)         }         if(length(WW)>0)         {             x <- Re(WW);y <- Im(WW)             points(x,y, cex = 3, pch = 19, col = rgb(0.9296875, 0.6757812, 0.0546875))             segments(x,y,x+0.5,y)             segments(x,y-0.5,x,y+0.5)         }         if(length(SS)>0)         {             x <- Re(SS);y <- Im(SS)             points(x,y, cex = 3, pch = 19, col = rgb(0.9296875, 0.6757812, 0.0546875))             segments(x-0.5,y,x+0.5,y)             segments(x,y,x,y+0.5)         }         if(length(NN)>0)         {             x <- Re(NN);y <- Im(NN)             points(x,y, cex = 3, pch = 19, col = rgb(0.9296875, 0.6757812, 0.0546875))             segments(x-0.5,y,x+0.5,y)             segments(x,y-0.5,x,y)         }         if(is.element(4+4i,A))points(4+4i, cex = 1.2, pch = 19)         if(is.element(4+10i,A))points(4+10i, cex = 1.2, pch = 19)         if(is.element(4+16i,A))points(4+16i, cex = 1.2, pch = 19)         if(is.element(10+4i,A))points(10+4i, cex = 1.2, pch = 19)         if(is.element(10+10i,A))points(10+10i, cex = 1.2, pch = 19)         if(is.element(10+16i,A))points(10+16i, cex = 1.2, pch = 19)         if(is.element(16+4i,A))points(16+4i, cex = 1.2, pch = 19)         if(is.element(16+10i,A))points(16+10i, cex = 1.2, pch = 19)         if(is.element(16+16i,A))points(16+16i, cex = 1.2, pch = 19)     }     ##气的提示     qi <- function()     {         tp1 <- matrix(,ncb[1],2)         for(i in 1:ncb[1]) tp1[i,] <- c(length(bouset[[1]][[i]]),conset[[1]][[i]][1])         d1 <- tp1[order(tp1[,1]),]         d1 <- data.frame(黑方气数=Re(d1[,1]),分支位置=d1[,2])         print(d1)         tp2 <- matrix(,ncb[2],2)         for(i in 1:ncb[2]) tp2[i,] <- c(length(bouset[[2]][[i]]),conset[[2]][[i]][1])         d2 <- tp2[order(tp2[,1]),]         d2 <- data.frame(白方气数=Re(d2[,1]),分支位置=d2[,2])         print(d2)      }       ###进入对弈     k <- 0     repeat         {         for (j in 1:2)    ##黑白交替落子         {             repeat             {                 l <- locator(1)    #获得落子坐标                 l$x <- round(l$x)                 l$y <- round(l$y)                 xy <- complex(0,l$x,l$y)                 if (!is.element(xy, vplay))break    #禁走历史位置             }              ##悔棋             Cex <- 1             if(k>99)Cex <- 0.8             if(l$y<0.5)             {                 take(vplay)                 history[[k]] <- NULL                 k <- k-1                 playedlist <- history[[k]]                 vplay <- unlist(playedlist)                 conset <- hiscon[[k]]                 bouset <- hisbou[[k]]                 ncb <- hisncb[[k]]                 ntake <- hisntake[[k]]                 Bx <- Re(history[[k]][[1]]);By <- Im(history[[k]][[1]])                 Wx <- Re(history[[k]][[2]]);Wy <- Im(history[[k]][[2]])                 points(Bx, By, cex = 3, pch = 19, bg = "black")                 points(Wx, Wy, cex = 3, pch = 21, bg = "white")                 text(Bx,By+0.06,seq(1,k,2),cex=Cex,col="white")                 text(Wx,Wy+0.06,seq(2,k,2),cex=Cex,col="black")                 if(min(ncb)>2)qi()                 re <- 1             }             if(re == 1){re <- 0;next}              #落子             k <- k+1             points(l, cex = 3, pch = c(19, 21)[j], bg = c("black", "white")[j])             text(l$x,l$y+0.06,k,cex=Cex,col=c("white","black")[j])                                  ##损气提吃             s=1             while(s<=ncb[3-j])             {                   opp <- bouset[[3-j]][[s]]                               if(is.element(xy,opp))                 {                     if(length(opp)==1)                     {                         playedlist[[3-j]] <- setdiff(playedlist[[3-j]],conset[[3-j]][[s]])                         vplay <-unlist(playedlist)                         take(conset[[3-j]][[s]])    #提子                         ntake[j] <- ntake[j]+length(conset[[3-j]][[s]]);eat <- 1                         bouset[[3-j]][[s]] <- NULL                             conset[[3-j]][[s]]<-NULL                         ncb[3-j] <- ncb[3-j]-1    #对方分支数减少                         for(t in 1:ncb[j])                         {                             bouset[[j]][[t]] <- setdiff(Bd(conset[[j]][[t]]),vplay)                         }                         s <- s-1                     }else{                     bouset[[3-j]][[s]] <- setdiff(opp,xy)                                }                 }                 s <- s+1             }                          ###构造三大列表(历史、连通分支、边界)             p=0    #分支构建指标(p>0分支合并、p=0新建分支)             U <- c()    #合并分支             i <- 1;r<- c()             while(i<=ncb[j])              {                 if(ncb[j]==0) break                 if(is.element(xy, bouset[[j]][[i]]))    #新下的棋属于哪个连通分支                 {                     p <- p+1                     if(p==1)                     {                         q <- i                         U <- conset[[j]][[i]]                         conset[[j]][[i]]<-NULL                         bouset[[j]][[i]]<-NULL                         ncb[[j]] <- ncb[[j]]-1                         i <- i-1                     }                     if(p>1)                     {                         U <- union(U,conset[[j]][[i]])                         conset[[j]][[i]]<-NULL                         bouset[[j]][[i]]<-NULL                         i=i-1                         ncb[j] <- ncb[j]-1                      }                 }                 i <- i+1             }              ncb[j] <- ncb[j]+1             if(p==0){                 if(ncb[j]==0)                 {                     conset[[j]] <- list(xy)    #孤子建新支                     bouset[[j]] <- list(setdiff(Bd(xy),vplay))                 }else{                     conset[[j]][[ncb[j]]] <- xy                         bouset[[j]][[ncb[j]]] <- setdiff(Bd(xy),vplay)                      }             }else if(p==1){                 if(ncb[j]>0)                 {                     conset[[j]][[ncb[j]]] <- c(U,xy)                     bouset[[j]][[ncb[j]]] <- setdiff(Bd(c(U,xy)),vplay)                 }else{                     conset[[j]] <- list(c(U,xy))                     bouset[[j]] <- list(setdiff(Bd(c(U,xy)),vplay))                 }             }else{                 conset[[j]][[ncb[j]]] <- c(U,xy)                 bouset[[j]][[ncb[j]]] <- setdiff(Bd(c(U,xy)),vplay)             }              playedlist[[j]] <- c(playedlist[[j]], xy)             vplay <-unlist(playedlist)             history[[k]] <- playedlist             hiscon[[k]] <- conset             hisbou[[k]] <- bouset             hisncb[[k]] <- ncb             hisntake[[k]] <- ntake              if(min(ncb)>2)qi()              if(eat>0)             {                 print(list(黑方提子数=ntake[1],白方提子数=ntake[2]));eat <- 0             }              if (k >= n^2)break    ###满盘结束(满盘皆输555~)         }     if(k >= n^2) break     } } GoT2()       

为了表现环面的特征,下了一个智障的棋谱,大家可以品一品。另外,点击“落子无悔”可以悔棋哦~

类似的话题

  • 回答
    想象一下,你手里不是一块平整的围棋棋盘,而是一个带着点弹性、光滑圆润的呼啦圈。棋子落在上面,不再是孤立的点,而是可以顺着“边”相互连接,延伸到你视野的另一端。这就是把围棋棋盘的上下左右边对折粘合,变成了“棋盘面包圈”。这一下,原本熟悉的棋盘几何瞬间颠覆了。我们得抛开那些根深蒂固的边角思维,重新审视整.............
  • 回答
    你提出的这个问题触及了围棋界一个长期存在且颇具争议的现象:顶尖女棋手与顶尖男棋手之间似乎存在明显的差距。而“女棋手人数少”这个解释,虽然在表面上看似乎有些道理,但深究下去,就会发现它并非根本原因,甚至可能是对问题的简单化和误读。下面我们就来详细剖析一下,为什么将这种差距简单归咎于人数不足是站不住脚的.............
  • 回答
    兄弟,身高186,健身8个月就想在一年内把臂围从38cm干到42cm,这目标够狠!不过,186的身高配38的臂围,确实还有很大的提升空间,一年干到42,完全有可能,但需要科学的方法加上狠劲儿。我跟你聊聊我的经验和一些实操的建议,希望能帮你一把。首先,咱们得明白,臂围不是只看二头肌,三头肌的贡献同样巨.............
  • 回答
    你提出的这个想法,从道德角度来看,确实存在一些值得商榷的地方。首先,我们来分析一下你提到的几个行为: 购买弓箭并射杀动物: 动物的生命权是一个复杂但被广泛讨论的议题。虽然在某些特定情况下(例如狩猎作为食物来源、控制种群数量等)射杀动物是被允许甚至必要的,但你的描述中,目的是“玩”,并且是“射死它.............
  • 回答
    这件事情的处理结果,关键在于李四及其朋友的行为是否符合抢劫罪的构成要件。我们得把这件事掰开了揉碎了说清楚。首先,咱们得明确一下抢劫罪是什么。在刑法上,抢劫罪(根据《中华人民共和国刑法》第二百六十三条)是指以非法占有为目的,对他人当场使用暴力、胁迫或者其他方法,强行夺取公私财物的行为。这里面有几个关键.............
  • 回答
    诸葛亮六出祁山,每次都能全身而退,而司马懿却不敢派兵绕后偷袭汉中以围歼蜀军,这背后涉及到了三国时期复杂的战略、地理、后勤以及双方将领的智慧与局限。下面我将详细阐述其中的原因: 诸葛亮六出祁山:为何每次都能全身而退?诸葛亮六出祁山,每一次都并非简单的进攻,而是包含了他深思熟虑的战略布局和精湛的战术执行.............
  • 回答
    哈哈,这个问题可有意思了!这可不是简单问个数字就能解答的,里面门道儿可多了。想把一个100斤的姑娘稳稳当当举过头顶,不光光是胳膊粗不粗的事儿,得看一个整体的“力学框架”搭建得怎么样。咱们先从核心力量说起,也就是腰腹和背部。你别小看这块儿,它才是你举起人的“支柱”。你想啊,100斤姑娘的体重,最终是要.............
  • 回答
    国民党在第五次围剿胜利后,之所以未能“斩草除根”地消灭红军,是一个错综复杂的问题,涉及军事策略、政治博弈、战略判断以及中国当时的具体国情。这绝非简单地归因于某一方的失误或疏忽,而是多重因素交织作用的结果。一、 国民党军事上的“胜利”并非“全胜”:战术层面与战略层面的考量首先,我们要明确,国民党在第五.............
  • 回答
    凯申公(蒋介石)在淮海战役时期未能直接解职白崇禧并调动宋希濂兵团解救黄维兵团,这一决策背后涉及复杂的政治、军事、个人恩怨以及整体战略考量。要详细解释这一点,我们需要分几个层面来分析:一、 政治层面:国民党内部的派系林立与权力制衡 白崇禧的特殊地位: 白崇禧是国民党内部举足轻重的人物,长期以来与桂.............
  • 回答
    .......
  • 回答
    将日本军国主义与日本人民分开是正确的,但需要从历史、社会、文化等多维度进行深入分析,避免简单化或片面化的历史判断。以下从多个角度展开详细说明: 一、历史背景:军国主义是特定历史时期的国家政策1. 军国主义的定义 军国主义是指以国家为单位,将军事扩张、侵略战争作为核心政策的意识形态,通常伴随着.............
  • 回答
    这是一个非常有趣且富有想象力的问题,涉及到咖啡拉花(Latte Art)的艺术性和物理原理。答案是:理论上,如果你能精确地复制并反向执行每一个搅动步骤,并且咖啡液的性质(如粘稠度、温度、表面张力等)保持不变,那么在极小的范围内,以及在理论的完美假设下,是有可能将咖啡的图案“复原”一部分的。但实际上,.............
  • 回答
    “把别人的女友抢过来”在道德上是否正义,这是一个复杂的问题,牵涉到个人情感、人际关系、社会规范以及法律等多个层面。我们可以从以下几个方面来详细探讨: 道德层面:从普遍的道德观念来看,将他人已有伴侣的另一半“抢过来”通常被视为不道德的行为。原因如下: 违背忠诚和承诺的道德原则: 恋爱关系建立在双方.............
  • 回答
    把一副好牌打得稀烂,这是一种非常令人扼腕叹息的情形,无论是在什么领域,它都意味着将原本极具潜力、充满优势的局面,因为错误的决策、糟糕的执行或者自身的局限,最终导向了一个非常糟糕的结局,甚至一败涂地。我们可以从多个角度来理解和描述这种情形:一、 核心表现:优势的丧失与潜力的浪费最核心的表现就是,原本拥.............
  • 回答
    将高中哲学奉为绝对真理,这是一种非常有趣且值得深入探讨的设想。在现实生活中,这样做的人可能不多,但我们可以通过分析高中哲学的内容、其教育目的以及“奉为真理”所带来的影响,来详细阐述这种状态可能出现的情况。一、 高中哲学的内容及教育目的:首先,我们需要明确高中哲学通常涵盖哪些内容,以及它被教授的初衷。.............
  • 回答
    你提出的问题非常有趣,也触及了数字媒体和编程的本质!简而言之,答案是: 有规律,可以编写代码生成视频,但这远比你想象的要复杂得多。我们先来拆解一下你提到的现象,再深入探讨如何生成视频。 理解视频文件后缀更改后的“一串代码”当你将一个视频文件(比如 .mp4, .avi, .mov)的后缀改成 .tx.............
  • 回答
    把700人扔进一个有700只东北虎的东北虎园,绝大多数人会活下来,但并非所有人都能够毫发无伤地幸存。要详细分析这个问题,我们需要从几个关键方面来考虑:1. 老虎的行为和狩猎习性: 东北虎是顶级掠食者: 它们是强大的、经验丰富的猎手,主要以大型哺乳动物为食,如野猪、鹿、狍子等。 狩猎的必要性:.............
  • 回答
    这个问题看似简单,但牵涉到很多方面,直接回答“有没有错”其实有点过于绝对,更准确的说法是:这样做是合理的、常见的,但同时也需要考虑一些潜在的影响和沟通方式。我们来详细分析一下:一、合规性与必要性: 群聊的初衷: 群聊通常是为了方便当前团队或项目成员的沟通协作。一个已经离职的同事,不再参与公司的日.............
  • 回答
    非常抱歉,无论您把肌肉练到何种程度,都无法有效抵挡子弹。这是一个非常重要的误解,需要明确说明。科学解释为什么肌肉无法挡住子弹: 子弹的能量与速度: 子弹以极高的速度和能量飞行。即使是最低威力的手枪子弹,其动能也远远超过了人体肌肉组织所能承受的极限。子弹的能量集中在一个非常小的点上,能够瞬间穿透并.............
  • 回答
    将代码写得过于灵活,看起来似乎是开发者追求的理想状态,因为它能适应未来各种未知需求。然而,在实际的软件开发中,过度灵活的代码却常常是“一把双刃剑”,很多时候反而会成为问题,甚至导致开发者被上司批评。这背后的原因非常复杂,涉及到软件工程的多个方面。下面我将详细阐述“代码写得太灵活不好”以及为何会被上司.............

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有