一段程序,搞的我头大!请教高手帮忙注释下!
下面一个黑白棋程序,从网上找的,结果发现写的很乱 ,想找个高手帮忙注释下!不胜感激!#define BLANK ' '
#define P1 '*'//Player1
#define P2 'o'//Player2
#define OP(p) P1+P2-p
#define BORDERSCORE 3
#define max(a,b) (a)>(b)?(a):(b)
char msg[30]; //存储数组
struct B //棋盘类
{
int _r,_c,_s; //row, column, _s是开局的玩家
char** _b; //棋盘,是一个2维数组
void create()
{
_b=new char*[_r];
for(int r=0;r<_r;++r)
{
_b[r]=new char[_c];
for(int c=0;c<_c;++c)_b[r][c]=BLANK;
}
} //行列扫描
void init()
{
int mid_r=_r/2-1;
int mid_c=_c/2-1;
_b[mid_r ][mid_c ]=P1;
_b[mid_r ][mid_c+1]=P2;
_b[mid_r+1][mid_c ]=P2;
_b[mid_r+1][mid_c+1]=P1;
}
//设置开始4个棋子
bool hasNeighbor(int r,int c,char p)
{
if(_b[r][c]!=BLANK)
{
return false;
}
bool tl=false;
bool to=false;
bool tr=false;
bool le=false;
bool ri=false;
bool bl=false;
bool bo=false;
bool br=false;
if(r==0 ){tl=true;to=true;tr=true;}
if(r==_r-1){bl=true;bo=true;br=true;}
if(c==0 ){tl=true;le=true;bl=true;}
if(c==_c-1){tr=true;ri=true;br=true;}
if(!tl)tl=_b[r-1][c-1]==BLANK;
if(!to)to=_b[r-1][c ]==BLANK;
if(!tr)tr=_b[r-1][c+1]==BLANK;
if(!le)le=_b[r ][c-1]==BLANK;
if(!ri)ri=_b[r ][c+1]==BLANK;
if(!bl)bl=_b[r+1][c-1]==BLANK;
if(!bo)bo=_b[r+1][c ]==BLANK;
if(!br)br=_b[r+1][c+1]==BLANK;
bool blank=tl && to && tr && le && ri && bl && bo && br;
if(blank){
return false;
}
return true;
}
//游戏规则判定
explicit B(int row,int col,char start):_r(row),_c(col),_s(start),_b(0)
{
create();
init();
}
B(const B& b)
{
_r=b._r;
_c=b._c;
_s=b._s;
create();
for(int r=0;r<_r;++r)
{ //copy
for(int c=0;c<_c;++c)
{
_b[r][c]=b._b[r][c];
}
}
}
//重新排列棋子
virtual ~B()
{
if(_b)
{
for(int r=0;r<_r;++r) delete [] _b[r];
delete [] _b;
}
_b=0;
}
//删除被覆盖的棋子
bool loop8dirs(int r,int c,char p,bool convert)
{
bool ret=false;
struct search{int x;int y;}; //8个方向的查找表,静态不变
static search direction[8]={ {-1,-1}, {-1,0}, {-1,1}, {0,-1}, {0,1}, {1,-1}, {1,0}, {1,1} };
for(int i=0;i<8;++i)
{ //8 directions of search
search& s=direction[i];
int newr=r+s.x;
int newc=c+s.y;
if(newr>=_r || newr<0 || newc>=_c || newc<0)
{
continue;
}
char& n=_b[newr][newc];
if(n==p||n==BLANK)continue; //该位置是本色棋子或者是空的,该方向就跳过
else{
int rc=newr;
int cc=newc;
while(rc+s.x>=0 && rc+s.x<=_r-1 && cc+s.y>=0 && cc+s.y<=_c-1){
rc+=s.x;
cc+=s.y;
char ch=_b[rc][cc];
if(ch==p){//find path to convert
ret=true;
if(convert){
int count=max(abs(rc-r),abs(cc-c));
for(int path=0;path<=count;++path) _b[r+path*s.x][c+path*s.y]=p;
break;
}else return true;
}else if(ch==BLANK){
break;
}//end if(ch==p)
}//end while
}//end else//
}//if(!ret && convert)print("take converting step failed");
//if(ret)drawB();// print("take converting step!");
return ret;
}
//具体操作过程
int score(char player){
int s=0;
for(int r=0;r<_r;++r){
for(int c=0;c<_c;++c){
if(_b[r][c]==player)++s;
}
}
return s;
}
void drawB(){ // 用stdio来画出整个棋盘
printf(" ");
for(int c=0;c<_c;++c)printf("--");
printf("---\n");
for(int r=0;r<_r;++r){
printf("%2d |",r+1);
for(int c=0;c<_c;++c){
printf(" %c",_b[r][c]);
}
printf(" |\n");
}
printf(" ");
for(int c=0;c<_c;++c)printf("--");
printf("---\n ");
for(int c=0;c<_c;++c)printf("%c ",'a'+c);
printf("\n");
}
bool go(int r,int c,char p){
if(r>_r+1 || r<1 || c>_c+1 || c<1){
printf("go() function got invalid parameter\n");
return false;
}
return aMove(r,c,p);
}
bool aMove(int r,int c,char p)
{
if(!hasNeighbor(r-1,c-1,p)){printf("aMove->hasNeighbor failed\n");return false;}
if(!loop8dirs(r-1,c-1,p,true)){printf("aMove->loop8dirs failed\n");return false;}
return true;
}
bool checkMove(int r,int c,char p){
return hasNeighbor(r-1,c-1,p) && loop8dirs(r-1,c-1,p,false);
}
};
struct playB:public B{ //含有机器人功能的棋盘
struct path{
int r;int c;
inline void set(int row,int col){r=row;c=col;}
}*sp;
path bestpath,curpath;
int si; //stack index
void _init(){ si=0; sp=new path[_r*_c]; }
inline void push(int r,int c){sp[si++].set(r,c);}
bool hasSteps(char player){ //玩家player是否还有下一步棋可走?
si=0;
for(int r=0;r<_r;++r){ //穷举法寻找可能的步骤。
for(int c=0;c<_c;++c){
if(_b[r][c]!=BLANK)continue;
if(checkMove(r+1,c+1,player))push(r,c);//所有可能的步骤入栈
}
} //如需要提高性能,可以对搜索过的结果做统计和操作
if(si==0)return false;
else return true ;
}
playB(int row,int col,char start):B( row,col ,start){_init();}
playB(int scale, char start):B(scale,scale,start){_init();}
playB(const playB& b ):B(b){_init();}
~playB(){if(sp){delete[] sp;sp=0;}}
bool next(char p){ //电脑棋手下一步棋
if(!hasSteps(p))return false;
int Highmark=0;
#define STACK(i) sp[i]
int best=0; //Best step bestition
int bestscore=-1000;
for(int pc=0;pc<si;++pc){
static const int depth=4;
const path& pa=STACK(pc);
curpath=pa;
int s=_eval(p,pa,depth); //广度优先搜索算法
if(s>bestscore){
bestscore=s;
best=pc;
}
}
int row=STACK(best).r;
int col=STACK(best).c;
if(!go(row+1,col+1,p)){printf("fatal error in next()\n");return false;}//Take robot step
printf("电脑: ---------------下棋![%d,%c]-----------------\n",row+1,col+'a');
drawB();
return true;
}
int _eval(char p,const path&pa,int depth){//recursive function
const int& r=pa.r; //pa is a valid step provided by path stack
const int& c=pa.c; //printf("(enter) _eval,p=%c,curp=%c,depth=%d\n",p,wi.curplayer,depth);
playB copy(*this); //steps are already got from hasSteps();
if(!copy.go(r+1,c+1,p)){
printf("fatal error: copy.go should not fail!!!\n");
exit(1);
}
if(depth==0){
int s=copy.score(p)-copy.score(OP(p));
int sadd=BORDERSCORE; //if [r,c] is border or corner(doubled), add to the score of curplayer
if(r==0 || r==_r-1 ||c==0 ||c==_c-1){
s+=sadd;
if( (r==0&&c==0) ||
(r==0&&c==_c-1) ||
(r==_r-1&&c==0) ||
(r==_r-1&&c==_c-1))
s+=10*sadd;
}
return s;//
}else{
if(copy.hasSteps(OP(p))){ //step=2时进入这一步
int lowest=1000;
for(int pc=0;pc<copy.si;++pc){
int s=copy._eval(OP(p),copy.sp[pc],depth-1);//set copy.bestpath,对方eval,选出最小值
if(s<lowest){lowest=s;}//if
}//for
return lowest;
}
return 0;
}
} //_eval()
void robot(){ //test automatic steps
bool r1=false;
bool r2=false;
do{
r1=next(P1);
r2=next(P2);
}while(r1||r2);
}
}; // playB::workinfo playB::wi;
struct Player{
playB* pb;
char p;
bool b;
explicit Player(playB* pBoard,char player,bool bRobot=true){
pb=pBoard;p=player;b=bRobot;
}
bool move(){
playB& rb=*pb;
char op=OP(p);
if(rb.score(p)==0){ //"我"已经Game over了!
if(b==true){sprintf(msg,"电脑玩家%c赢了%d分!\n",op,rb.score(op)-rb.score(p));}
else {sprintf(msg,"人家玩家%c赢了%d分!\n",op,rb.score(op)-rb.score(p));}
exit(0);
}
if(b){
bool ret=rb.next(p);
if(!ret)printf("电脑没有棋了,跳过\n");
return ret;
}
else{ //Human
if(!rb.hasSteps(p)){
printf("人类没有棋了,跳过\n");
return false;
}
int r=0,c='0';
while(1){
printf("人类玩家: ---------------输入参数---------------\n");
printf("输入行值和列值,中间空格或逗号,例如3 e\n");
printf("行值的范围 [%d,%d], 列值的范围 [%c,%c]\n",1,rb._c,'a','a'+rb._c-1);
scanf("%d %c",&r,&c);
if(r<1 || r>rb._r || c<'a' || c>'a'+rb._c-1){printf("输入参数错误!!!!!\n");continue;}
c=c-'a'+1;
printf("r=%d,c=%d\n",r,c);
if(!rb.checkMove(r,c,p)){
printf("行列值检查失败 [%d,%c] 请输入一个有效的位置\n",r,c+'a'-1);
continue;
}
if(rb._b[r-1][c-1]!=BLANK){
printf("不能在已经有棋子的地方下棋!\n");
continue;
}
bool ret=rb.go(r,c,p);
if(ret)rb.drawB();
return ret;
}//while
}//end else
}//end move()
};//Player
void f(){
printf("%s\n",msg);
system("PAUSE");
}
int main(void){
//atexit(f);
playB b(8,P1);
b.drawB();
Player p1(&b,P1,false);
Player p2(&b,P2,true);
bool r1=true;
bool r2=true;
do{
r1=p1.move();
if(! (r1||r2))break;
r2=p2.move();
}while(r1||r2);
int s=b.score(P1)-b.score(P2);
if(s==0){printf("平局!\n");}
else if(s>0){sprintf(msg,"玩家P1(%c)赢了%d分!\n",P1,b.score(P1)-b.score(P2));}
else {sprintf(msg,"玩家P2(%c)赢了%d分!\n",P2,b.score(P2)-b.score(P1));}
return 0;
}
注:头文件已经被去掉!