关于博弈

killer1984 2004-04-11 01:13:13
我写的黑白棋有时会出现莫名其妙的问题,在一次搜索之后电脑会同时在两个地方落子(注意,是一次搜索后,不涉及PASS的问题),我找了很久都没找出问题在哪里,从理论上这也是不可能的,因为搜索遍历的时候一定是一个格子一个格子搜下去,不可能两个格子(有时相距很远,但都有一个特点,就是其位置估值一般都比较高,也就是说都是电脑很想走的地方)同时走到。请问出现这种问题的原因最可能是什么?该从什么地方解决?
...全文
98 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
killer1984 2004-04-14
  • 打赏
  • 举报
回复
谢谢大家,特别感谢ZhangYv(Deadlock)和shines(郭子),我决定再仔细检查我的程序。
现在结贴。
shines77 2004-04-12
  • 打赏
  • 举报
回复
Alpha-Beta剪枝只会返回一个最好的走法的估值和棋子位置,

你的问题不是搜索的问题,是逻辑上的错误

最后建议使用Nega-Scout算法,我写过黑白棋,象棋

你的问题到底是搜索的过程中会走2个地方,还是搜索完了返回的走法有2个?
如果只有一个,请检查下子部分的函数。都应该是逻辑上的问题
ZhangYv 2004-04-12
  • 打赏
  • 举报
回复
我不会下黑白棋所以不懂走法产生方法。你检查一下对AddMove()的调用是否有误,只允许评价值最高的走法加入到一次搜索的走法队列中。
programer23 2004-04-12
  • 打赏
  • 举报
回复
哦。
Killer19840227 2004-04-11
  • 打赏
  • 举报
回复
// movegenerator.cpp: implementation of the CMoveGenerator class.
//走法产生器实现部分
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "baw.h"
#include "MoveGenerator.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CMoveGenerator::CMoveGenerator()
{

}

CMoveGenerator::~CMoveGenerator()
{

}

//在sm_MoveList中插入一个走法
//iply为此走法所在层
void CMoveGenerator::AddMove(int iSide,int iTox,int iToy,int iPly)
{
sm_MoveList[iPly][iMoveCount].stpos.x=iTox;
sm_MoveList[iPly][iMoveCount].stpos.y=iToy;
sm_MoveList[iPly][iMoveCount].iside=iSide;
iMoveCount++;

}

//产生局面position中所有可能的走法
int CMoveGenerator::CreatePossibleMove(BYTE position[][8],int iPly,int iSide)
{
iMoveCount=0;
for(int i=0;i<8;i++)
for(int j=0;j<8;j++)
if(position[i][j]==(BYTE)NOSTONE&&(IsVapos(position,iSide,j,i)))
AddMove(iSide,j,i,iPly);
return iMoveCount;
}

//检验当前走步是否合法
bool CMoveGenerator::IsVapos(BYTE position[][8],int iSide,int iTox,int iToy)
{
if(iTox<0||iTox>=8||iToy<0||iToy>=8) return false;

//向左检验
int x=iTox-1;
int y=iToy;
if(x>=0&&(position[y][x]!=iSide)&&(position[y][x]!=(BYTE)NOSTONE))
while(true)
{
x--;
if(x<0) break;
if(position[y][x]==(BYTE)NOSTONE) break;
if(position[y][x]==(BYTE)iSide)
return true;
}

//向左上检验
x=iTox-1;
y=iToy-1;
if(x>=0&&y>=0&&(position[y][x]!=iSide)&&(position[y][x]!=(BYTE)NOSTONE))
while(true)
{
x--;
y--;
if(x<0||y<0) break;
if(position[y][x]==(BYTE)NOSTONE) break;
if(position[y][x]==(BYTE)iSide)
return true;
}

//向上检验
x=iTox;
y=iToy-1;
if(y>=0&&(position[y][x]!=iSide)&&(position[y][x]!=(BYTE)NOSTONE))
while(true)
{
y--;
if(y<0) break;
if(position[y][x]==(BYTE)NOSTONE) break;
if(position[y][x]==(BYTE)iSide)
return true;
}

//向右上检验
x=iTox+1;
y=iToy-1;
if(x<8&&y>=0&&(position[y][x]!=iSide)&&(position[y][x]!=(BYTE)NOSTONE))
while(true)
{
x++;
y--;
if(x>=8||y<0) break;
if(position[y][x]==(BYTE)NOSTONE) break;
if(position[y][x]==(BYTE)iSide)
return true;
}

//向右检验
x=iTox+1;
y=iToy;
if(x<8&&(position[y][x]!=iSide)&&(position[y][x]!=(BYTE)NOSTONE))
while(true)
{
x++;
if(x>=8) break;
if(position[y][x]==(BYTE)NOSTONE) break;
if(position[y][x]==(BYTE)iSide)
return true;
}

//向右下检验
x=iTox+1;
y=iToy+1;
if(x<8&&y<8&&(position[y][x]!=iSide)&&(position[y][x]!=(BYTE)NOSTONE))
while(true)
{
x++;
y++;
if(x>=8||y>=8) break;
if(position[y][x]==(BYTE)NOSTONE) break;
if(position[y][x]==(BYTE)iSide)
return true;
}

//向下检验
x=iTox;
y=iToy+1;
if(y<8&&(position[y][x]!=iSide)&&(position[y][x]!=(BYTE)NOSTONE))
while(true)
{
y++;
if(y>=8) break;
if(position[y][x]==(BYTE)NOSTONE) break;
if(position[y][x]==(BYTE)iSide)
return true;
}

//向左下检验
x=iTox-1;
y=iToy+1;
if(x>=0&&y<8&&(position[y][x]!=iSide)&&(position[y][x]!=(BYTE)NOSTONE))
while(true)
{
x--;
y++;
if(x<0||y>=8) break;
if(position[y][x]==(BYTE)NOSTONE) break;
if(position[y][x]==(BYTE)iSide)
return true;
}

return false;//均不行,返回不可走
}///:~
killer1984 2004-04-11
  • 打赏
  • 举报
回复
// stmovegenerator.h: interface for the stmovegenerator class.
//走法产生器类声明
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_MOVEGENERATOR_H__69E9FFBA_2EB9_474B_B24A_C7AB8B50AC7E__INCLUDED_)
#define AFX_MOVEGENERATOR_H__69E9FFBA_2EB9_474B_B24A_C7AB8B50AC7E__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CMoveGenerator //走法产生器类
{
protected:
int iMoveCount; //记录走法总数
void AddMove(int iSide,int iTox,int iToy,int iPly); //向走法数组中添加走法
public:
CMoveGenerator();
virtual ~CMoveGenerator();

int CreatePossibleMove(BYTE position[][8],int iPly,int iSide);//产生给定局面下一步所有合法走法
STMOVE sm_MoveList[60][20];//存放产生的走法队列
static bool IsVapos(BYTE position[][8],int iSide,int iTox,int iToy);
//检查一个走法是否合法
};

#endif // !defined(AFX_MOVEGENERATOR_H__69E9FFBA_2EB9_474B_B24A_C7AB8B50AC7E__INCLUDED_)///:~
killer1984 2004-04-11
  • 打赏
  • 举报
回复
to:ZhangYv(Deadlock)
我不知道应该贴哪些部分出来。先贴出走法产生器的两个文件,因为我估计多半错在这里,如果还需要其他部分的话请告诉我。
killer1984 2004-04-11
  • 打赏
  • 举报
回复
补充几点:
在仅仅使用负极大值搜索算法的时候几乎没有问题(我没遇到过),但是优化之后(分别使用ALPHA-BETA搜索,极小窗口搜索,渴望搜索)随着进一步优化,问题出现的几率也越大,因为使用的是C++,用的模块化的设计,并且参考了王小春(hidebug,hidebug@hotmail.com)的象棋和五子棋源码,通过逐层检查,基本排除搜索算法上的问题。所以问题一定是出在其他地方的。
我不是想让大家帮我解决问题,只是希望大家告诉我查找错误的大致方向,也就是说我想知道出这种错可能性较大的是哪里的问题。
ZhangYv 2004-04-11
  • 打赏
  • 举报
回复
把程序贴出来看看吧,不是博弈部分的毛病,而是其他地方的问题。

你去GOOGLE可以看到很多源程序,可以先研究一下先
wlpwind 2004-04-11
  • 打赏
  • 举报
回复
先不说搜索算法的问题,
可能程序本身也有问题。
FmzHxj 2004-04-11
  • 打赏
  • 举报
回复
跟一下程序不就知道了。
PS:楼主真的知道博弈是什么吗?

8,304

社区成员

发帖
与我相关
我的任务
社区描述
游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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