围棋里面死活的算法

fvfrto 2008-07-13 06:08:10
谁能做一个围棋死活的算法.
也就是说,每落一子,要知道这子相对应的四周棋是死是活.
...全文
460 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
bbksoft 2008-11-26
  • 打赏
  • 举报
回复
其实,这个问题反过来想一想就可以了。

我们只要棋盘上的所有活棋剃掉,剩下的就都是死棋了。
有个JAVA 的算法,以前写的,你可以参考一下。



int goXCount;
int goYCount;

final byte GO_WHITE = 2;
final byte GO_BLACK = 1;
final byte GO_NULL = 0;
final byte GO_DIE = 3;

boolean isBlackFirst;
boolean leftB, topB, rightB, bottomB;
static byte data[] = new byte[19*19];
static byte dataEx[] = new byte[9];

static final int MAX_STEP = 25;

int stepCount;
static byte dataStep[][] = new byte[MAX_STEP][];
static byte dataResult[] = new byte[19*19];

static byte tempDataResult[] = new byte[19*19];

int drawUnitX;
int drawUnitY;
int drawUnitWidth;

final static int MAX_X_COUNT = 14;

int drawLEFT;
int drawTOP;
int drawWidth;
int drawHeight;

int handX, handY;

boolean s_showResult;
int s_showLevel;


boolean IsNullChess ( byte[] data, int x, int y )
{
if ( x < 0 ) return false;
if ( y < 0 ) return false;
if ( x > goXCount-1 ) return false;
if ( y > goYCount-1 ) return false;



return ( data[x+y*goXCount] == GO_NULL );
}


boolean IsLiveChess( byte[] data, int x, int y )
{
if ( x <= 0 )
{
if ( !leftB ) return true;
}

if ( x >= goXCount-1 )
{
if ( !rightB ) return true;
}

if ( y <= 0 )
{
if ( !topB ) return true;
}

if ( y >= goYCount-1 )
{
if ( !bottomB ) return true;
}


if ( IsNullChess(data, x+1,y) ) return true;
if ( IsNullChess(data,x,y+1) ) return true;
if ( IsNullChess(data,x,y-1) ) return true;
if ( IsNullChess(data,x-1,y) ) return true;

return false;
}

void PutChess( int x, int y )
{
if ( stepCount > 0 )
{
int stepX = dataStep[stepCount-1][0];
int stepY = dataStep[stepCount-1][1];

if ( dataResult[x+y*goXCount] != GO_NULL )
{
stepCount--;



byte chess = GO_BLACK;
byte dieChess = GO_WHITE;

if ( ((stepCount % 2) == 0 ) != isBlackFirst )
{
chess = GO_WHITE;
dieChess = GO_BLACK;
}

dataResult[ stepX + stepY*goXCount] = GO_NULL;

for ( int i=2; i<dataStep[stepCount].length; i+= 2)
{
stepX = dataStep[stepCount][i];
stepY = dataStep[stepCount][i+1];
dataResult[ stepX + stepY*goXCount] = dieChess;
}

return;
}
}

if ( stepCount >= MAX_STEP) return;
if ( dataResult[x+y*goXCount] != GO_NULL ) return ;


byte chess = GO_BLACK;
byte dieChess = GO_WHITE;

if ( ((stepCount % 2) == 0 ) != isBlackFirst )
{
chess = GO_WHITE;
dieChess = GO_BLACK;
}

dataResult[ x + y*goXCount] = chess;

System.arraycopy( dataResult, 0, tempDataResult, 0, goYCount * goXCount);

boolean foundData = true;
do {

foundData = false;
for ( int i=0; i<goXCount; i++ )
{
for ( int j=0; j<goYCount; j++ )
{
if ( tempDataResult[i+goXCount*j] != dieChess ) continue;

if ( IsLiveChess( tempDataResult, i, j ) )
{
tempDataResult[i+goXCount*j] = GO_NULL;
foundData = true;
}
}
}

}while ( foundData );

int dieCount = 0;
for ( int i=0; i<goXCount; i++ )
{
for ( int j=0; j<goYCount; j++ )
{
if ( tempDataResult[i+goXCount*j] == dieChess )
{
dieCount++;
}
}
}

dataStep[stepCount] = new byte[(dieCount+1)*2];

int index = 0;
dataStep[stepCount][index++] = (byte)x;
dataStep[stepCount][index++] = (byte)y;

for ( int i=0; i<goXCount; i++ )
{
for ( int j=0; j<goYCount; j++ )
{
if ( tempDataResult[i+goXCount*j] == dieChess )
{
dataStep[stepCount][index++] = (byte)i;
dataStep[stepCount][index++] = (byte)j;

dataResult[ i + j*goXCount] = GO_NULL;
}
}
}


if ( dieCount <= 0 )
{
System.arraycopy( dataResult, 0, tempDataResult, 0, goYCount * goXCount);

foundData = true;
do {

foundData = false;
for ( int i=0; i<goXCount; i++ )
{
for ( int j=0; j<goYCount; j++ )
{
if ( tempDataResult[i+goXCount*j] != chess ) continue;

if ( IsLiveChess( tempDataResult, i, j ) )
{
tempDataResult[i+goXCount*j] = GO_NULL;
foundData = true;
}
}
}

}while ( foundData );

dieCount = 0;
for ( int i=0; i<goXCount; i++ )
{
for ( int j=0; j<goYCount; j++ )
{
if ( tempDataResult[i+goXCount*j] == chess )
{
dieCount++;
}
}
}

if ( dieCount > 0 ) {
dataResult[x+goXCount*y] = GO_NULL;
dataStep[stepCount] = null;
return;
}
}

stepCount++;
}
YancyZeng 2008-10-26
  • 打赏
  • 举报
回复
写得这么SX的算法,还好意思贴出来, 连围棋规则都没弄清就装专家.
happy_sea 2008-07-24
  • 打赏
  • 举报
回复
楼主这样倒分不好吧?
zhufenghappy 2008-07-16
  • 打赏
  • 举报
回复
呵呵,真是不简单啊
yuelin586 2008-07-15
  • 打赏
  • 举报
回复
关注,关注!
祝愿楼主~~
呵呵
  • 打赏
  • 举报
回复
太难了~~
Tiger_Zhao 2008-07-14
  • 打赏
  • 举报
回复
用类似画图的颜色填充算法,判断一片棋子的死活(伪码)
function IsAlive(ByVal 颜色,byval 起始位置, byref 已检查() as boolean) As Boolean
dim 待判断队列, 判断点, 周边点

redim 已检查(18,18) as boolean
待判断队列.add 起始位置
已检查(起始位置.x, 起始位置.y) = true
while 待判断队列.非空()
判断点 = 待判断队列.Get()
循环 判断点 的 周边点
if not 已检查(周边点.x, 周边点.y) then
if 周边点.棋子颜色 = 没有 then
IsAlive = True
Exit function
elseif 周边点.棋子颜色 = 颜色 then
待判断队列.add 周边点
end if
已检查(周边点.x, 周边点.y) = true
end if
wend
'没气了,已检查(x,y) = true 并且 棋盘(x,y).棋子颜色 = 颜色 的子都要提掉
IsAlive = False
end function

>问题1
直接判断 棋盘(x,y).棋子颜色 = 没有
>问题2
对A周边的黑子调用 IsAlive()
>问题3
对A调用IsAlive()

注意要全部的 IsAlive() 都执行完后再提子
熊孩子开学喽 2008-07-14
  • 打赏
  • 举报
回复
因为其中会涉及到棋眼的计算,并不是说你落下的子周围是否有气,而是要判断和这个子相联的这一块棋的死活.
这就有点象区域填充颜色的算法了,
fvfrto 2008-07-14
  • 打赏
  • 举报
回复
大家都下过围棋吧!
我在做一个网络下围棋的程序.

现在有二个玩家.A与B 一个执白.一个执黑.
棋盘是19X19的,这个不用说了吧.

现在设定 A执白,要落子.

好现在的问题是:

对点A落下那粒子的位置进行判断
1.这个位置是否可以落子
2.当A落子后,是否能吃掉部分黑棋.让黑棋提掉.(要提掉那些子)
3.当A落子后,没有想到黑棋没有提掉,倒形成了自提.(如果自提,要提掉那些子)
fvflove 2008-07-14
  • 打赏
  • 举报
回复
[CODE=VB]
'***************************
'ChessData(18,18) 保存每个坐标点的数据
' 0 表示是空
' 1 表示是白棋
' 2 表示是黑棋
'**************************
Private ChessData(18, 18) As Byte

'***************************
'blChessCheck(18, 18) 保存在进行编历的时候,此坐标点是否编历过
' True 已经编历过
' False 未编历过
'**************************
Private blChessCheck(18, 18) As Boolean


'***************************
'setblChessCheck 重新设置blChessCheck(18,18)的值
'因为每次落子后都要重新编历一次
'**************************

Private Function setblChessCheck()
For i = 0 To 18
For j = 0 To 18
blChessCheck(i, j) = False
Next
Next
End Function


'*************************
'判断是否有气
'如果返回Ture 表示是活棋
'如果返回False 表示是死棋
'*************************


Private Function CheckChess(ByVal X As Byte, ByVal Y As Byte) As Boolean
CheckChess = False
blChessCheck(X, Y) = True '表示此坐标点已经编历过

If X > 0 Then
If ChessData(X, Y) = 0 Then '如果旁边有空,即气则结束
CheckChess = True
Exit Function
End If
If ChessData(X, Y) = CheckChess(X - 1, Y) Then '如果旁边的子与当前的子相同,则进行编历
CheckChess = CheckChess(X - 1, Y)
End If
End If

If X < 18 Then
If ChessData(X, Y) = 0 Then '如果旁边有空,即气则结束
CheckChess = True
Exit Function
End If

If ChessData(X, Y) = CheckChess(X + 1, Y) Then '如果旁边的子与当前的子相同,则进行编历
CheckChess = CheckChess(X + 1, Y)
End If

End If

If Y < 18 Then
If ChessData(X, Y) = 0 Then '如果旁边有空,即气则结束
CheckChess = True
Exit Function
End If

If ChessData(X, Y) = CheckChess(X, Y + 1) Then '如果旁边的子与当前的子相同,则进行编历
CheckChess = CheckChess(X, Y + 1)
End If

End If

If Y > 0 Then
If ChessData(X, Y) = 0 Then '如果旁边有空,即气则结束
CheckChess = True
Exit Function
End If

If ChessData(X, Y) = CheckChess(X, Y - 1) Then '如果旁边的子与当前的子相同,则进行编历
CheckChess = CheckChess(X, Y - 1)
End If
End If
End Function



'*******************
'调用示例
'********************


Private Function Check()
Dim IsDie As Boolean
setblChessCheck '先设置blChessCheck
IsDie = CheckChess(X, Y) '以坐标点X,Y进行计算

If IsDie = False Then '如果是死棋
For i = 0 To 18
For j = 0 To 18
If blChessCheck(i, j) = True Then
'如果是True 表示刚才编历过的,这里就可以提子了。
End If
Next
Next
End If
End Function
[/CODE]
junminsun2000 2008-07-13
  • 打赏
  • 举报
回复
楼主提的问题太高端了,我也很关注,不过我下围棋十几年了,还是没搞清楚你说的意思。。。。。
熊孩子开学喽 2008-07-13
  • 打赏
  • 举报
回复
楼主还是先去搞本围棋入门的书好好看看吧.
一时半会和真说不明白

7,759

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧