工程材料报验规范:怎样实现用黑白棋编一个程序

来源:百度文库 编辑:查人人中国名人网 时间:2024/05/09 18:04:32
.黑白子交换
有三个白子和三个黑子如下图布置:
○ ○ ○ . ● ● ●
游戏的目的是用最少的步数将上图中白子和黑子的位置进行交换:
● ● ● . ○ ○ ○
游戏的规则是:(1)一次只能移动一个棋子; (2)棋子可以向空格中移动,也可以跳过一个对方的棋子进入空格,但不能向后跳,也不能跳过两个子。请用计算机实现上述游戏。
*问题分析与算法设计
计算机解决胜这类问题的关键是要找出问题的规律,或者说是要制定一套计算机行动的规则。分析本题,先用人来解决问题,可总结出以下规则:
(1) 黑子向左跳过白子落入空格,转(5)
(2) 白子向右跳过黑子落入空格,转(5)
(3) 黑子向左移动一格落入空格(但不应产生棋子阻塞现象),转(5)
(4) 白子向右移动一格落入空格(但不应产生棋子阻塞现萌),转(5)
(5) 判断游戏是否结束,若没有结束,则转(1)继续。
所谓的“阻塞”现象就是:在移动棋子的过程中,两个尚未到位的同色棋子连接在一起,使棋盘中的其它棋子无法继续移动。

#include

#define MAX 10000

enum Color {WHITE=-1,BLANK,BLACK};

struct Choice
{
int posX;
int posY;
int score;
};

struct Chessman
{
enum Color color;
unsigned stable; /* 棋子的稳定性(0~8),若棋子为BLANK则表示该位置落子后可翻过的棋子个数. */
};

struct Chessboard
{
struct Chessman cell[8][8];
unsigned whiteNum;
unsigned blackNum;
};

/*
* 初始化棋盘.
*/
void initChessboard(struct Chessboard *board)
{
int i,j;
board->whiteNum=2;
board->blackNum=2;
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
board->cell[i][j].color=BLANK;
board->cell[i][j].stable=0;
}
}
board->cell[3][3].color=board->cell[4][4].color=BLACK;
board->cell[3][4].color=board->cell[4][3].color=WHITE;
}

/*
* 复制棋盘.
*/
void clone(struct Chessboard *boardDest,const struct Chessboard *boardSource)
{
int i,j;
boardDest->whiteNum=boardSource->whiteNum;
boardDest->blackNum=boardSource->blackNum;
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
boardDest->cell[i][j].color=boardSource->cell[i][j].color;
boardDest->cell[i][j].stable=boardSource->cell[i][j].stable;
}
}
}

/*
* 显示棋盘.
*/
void view(struct Chessboard *board)
{
int i,j;
printf("\n-----");
for(i=0;i<8;i++)
{
printf("%d---",i+1);
}
printf("\n ————————————————\n");
for(i=0;i<8;i++)
{
printf("%d--│",i+1);
for(j=0;j<8;j++)
{
switch(board->cell[i][j].color)
{
case BLACK:
printf("●│");
break;
case WHITE:
printf("○│");
break;
case BLANK:
if(board->cell[i][j].stable)
{
printf("╳│");
}
else
{
printf(" │");
}
break;
default: /* 棋子颜色错误 */
printf("* │");
}
}
printf("\n ————————————————\n");
}
printf("\n白棋(○)个数为:%d",board->whiteNum);
printf("\t黑棋(●)个数为:%d\n\n",board->blackNum);
}

/*
*计算可落子的位置个数,及该位置落子后翻过的棋子的个数(board->cell[i][j].stable)
*/
int judge(struct Chessboard *board,enum Color player)
{
int i,j;
unsigned num=0;
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
if(board->cell[i][j].color==BLANK)
{
int x,y;
board->cell[i][j].stable=0;
for(x=-1;x<=1;x++)
{
for(y=-1;y<=1;y++)
{
if(x||y) /* 8个方向 */
{
int i2,j2;
unsigned num2=0;
for(i2=i+x,j2=j+y;i2>=0 && i2<=7 && j2>=0 && j2<=7;i2+=x,j2+=y)
{
if(board->cell[i2][j2].color==(enum Color)-player)
{
num2++;
}
else if(board->cell[i2][j2].color==player)
{
board->cell[i][j].stable+=player*num2;
break;
}
else if(board->cell[i2][j2].color==BLANK)
{
break;
}
}
}
}
}

if(board->cell[i][j].stable)
{
num++;
}
}
}
}

return num;
}

/*
* 落子,翻子.
*/
int putChess(struct Chessboard *board,struct Choice *choice,enum Color player)
{
int i=choice->posX,j=choice->posY;
int x,y;

if(board->cell[i][j].color!=BLANK || board->cell[i][j].stable==0 || player==BLANK)
{
return -1;
}

board->cell[i][j].color=player;
board->cell[i][j].stable=0;
if(player==WHITE)
{
board->whiteNum++;
}
else if(player==BLACK)
{
board->blackNum++;
}

for(x=-1;x<=1;x++)
{
for(y=-1;y<=1;y++)
{
if(x||y) /* 8个方向 */
{
int i2,j2;
unsigned num=0;
for(i2=i+x,j2=j+y;i2>=0 && i2<=7 && j2>=0 && j2<=7;i2+=x,j2+=y)
{
if(board->cell[i2][j2].color==(enum Color)-player)
{
num++;
}
else if(board->cell[i2][j2].color==player)
{
board->whiteNum+=(player*WHITE)*num;
board->blackNum+=(player*BLACK)*num;

for(i2-=x,j2-=y;num>0;num--,i2-=x,j2-=y)
{
board->cell[i2][j2].color=player;
board->cell[i2][j2].stable=0;
}
break;
}
else if(board->cell[i2][j2].color==BLANK)
{
break;
}
}
}
}
}

return 0;
}

/*
* 设置棋子的稳定性(计算得分的依据),空白处除外.
*/
void setStable(struct Chessboard *board)
{
int i,j;
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
if(board->cell[i][j].color!=BLANK)
{
int x,y;
board->cell[i][j].stable=1;

for(x=-1;x<=1;x++)
{
for(y=-1;y<=1;y++)
{
/* 4个方向 */
if(x==0 && y==0)
{
x=2;
y=2;
}
else
{
int i2,j2,flag=2;
for(i2=i+x,j2=j+y;i2>=0 && i2<=7 && j2>=0 && j2<=7;i2+=x,j2+=y)
{
if(board->cell[i2][j2].color!=board->cell[i][j].color)
{
flag--;
break;
}
}

for(i2=i-x,j2=j-y;i2>=0 && i2<=7 && j2>=0 && j2<=7;i2-=x,j2-=y)
{
if(board->cell[i2][j2].color!=board->cell[i][j].color)
{
flag--;
break;
}
}

if(flag) /* 在某一条线上稳定 */
{
board->cell[i][j].stable++;
}
}
}
}
}
}
}
}

/*
* 评价棋手得分.
*/
int evaluate(struct Chessboard *board,enum Color player)
{
int value=0;
int i,j;
setStable(board);
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
value+=(board->cell[i][j].color)*(board->cell[i][j].stable);
}
}

value+=64*board->cell[0][0].color;
value+=64*board->cell[0][7].color;
value+=64*board->cell[7][0].color;
value+=64*board->cell[7][7].color;
value-=32*board->cell[1][1].color;
value-=32*board->cell[1][6].color;
value-=32*board->cell[6][1].color;
value-=32*board->cell[6][6].color;

return value*player;
}

/*
*考虑step步,选择最优方案.采用最大最小博弈和α-β剪裁算法
*/
struct Choice * maximin(struct Chessboard *board,enum Color player,int step,int min,int max,struct Choice *choice)
{
int i,j,k,num;
struct Choice *allChoices;
choice->score=-MAX;
choice->posX=-1;
choice->posY=-1;

num=judge(board,player);
if(num==0) /* 无处落子 */
{
if(judge(board,(enum Color)-player)) /* 对方可以落子,让对方下.*/
{
struct Chessboard tempBoard;
struct Choice nextChoice;
struct Choice *pNextChoice=&nextChoice;
clone(&tempBoard,board);
pNextChoice=maximin(&tempBoard,(enum Color)-player,step-1,-max,-min,pNextChoice);
choice->score=-pNextChoice->score;
choice->posX=-1;
choice->posY=-1;
return choice;
}
else /* 对方也无处落子,游戏结束. */
{
int value=WHITE*(board->whiteNum) + BLACK*(board->blackNum);
if(player*value>0)
{
choice->score=MAX-1;
}
else if(player*value<0)
{
choice->score=-MAX+1;
}
else
{
choice->score=0;
}

return choice;
}
}

if(step<=0) /* 已经考虑到step步,直接返回得分 */
{
choice->score=evaluate(board,player);
return choice;
}

allChoices=(struct Choice *)malloc(sizeof(struct Choice)*num);
k=0;
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
if(i==0 || i==7 || j==0 || j==7)
{
if(board->cell[i][j].color==BLANK && board->cell[i][j].stable)
{
allChoices[k].score=-MAX;
allChoices[k].posX=i;
allChoices[k].posY=j;
k++;
}
}
}
}

for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
if((i==2 || i==5 || j==2 || j==5) && (i>=2 && i<=5 && j>=2 && j<=5))
{
if(board->cell[i][j].color==BLANK && board->cell[i][j].stable)
{
allChoices[k].score=-MAX;
allChoices[k].posX=i;
allChoices[k].posY=j;
k++;
}
}
}
}

for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
if((i==1 || i==6 || j==1 || j==6) && (i>=1 && i<=6 && j>=1 && j<=6))
{
if(board->cell[i][j].color==BLANK && board->cell[i][j].stable)
{
allChoices[k].score=-MAX;
allChoices[k].posX=i;
allChoices[k].posY=j;
k++;
}
}
}
}

for(k=0;k {
struct Chessboard tempBoard;
struct Choice thisChoice,nextChoice;
struct Choice *pNextChoice=&nextChoice;
thisChoice=allChoices[k];
clone(&tempBoard,board);
putChess(&tempBoard,&thisChoice,player);
pNextChoice=maximin(&tempBoard,(enum Color)-player,step-1,-max,-min,pNextChoice);
thisChoice.score=-pNextChoice->score;

if(thisChoice.score>min && thisChoice.score {
min=thisChoice.score;
choice->score=thisChoice.score;
choice->posX=thisChoice.posX;
choice->posY=thisChoice.posY;
}
else if(thisChoice.score>=max) /* 好的超乎预计 */
{
choice->score=thisChoice.score;
choice->posX=thisChoice.posX;
choice->posY=thisChoice.posY;
break;
}
/* 不如已知最优值 */
}

free(allChoices);
return choice;
}

int main(void)
{
struct Chessboard board;
struct Chessboard *pBoard=&board;
enum Color player=BLANK,nowPlayer=BLACK;
struct Choice choice;
struct Choice *pChoice=&choice;
int dif=-1,step=4,success=0;
char restart=' ';

start:
player=BLANK;
nowPlayer=BLACK;
dif=-1;
step=4;
restart=' ';

while(dif<1 || dif>60)
{
printf("请选择难度(1~60):\n");
scanf("%d",&dif);
if(dif<1 || dif>60)
{
printf("难度设置错误.\n");
}
}

while(player!=WHITE && player!=BLACK)
{
printf("\n请选择执黑棋(●)(1),或执白棋(○)(-1)\t执黑棋先下:\n");
scanf("%d",&player);
if(player!=WHITE && player!=BLACK)
{
printf("黑白设置错误.\n");
}
}

initChessboard(pBoard);

while(step<64) /* 棋盘上未下满64子 */
{
char *nowPlayerName="";
if(nowPlayer==BLACK)
{
nowPlayerName="黑棋(●)";
}else if(nowPlayer==WHITE)
{
nowPlayerName="白棋(○)";
}

if(judge(pBoard,nowPlayer)==0)
{
if(judge(pBoard,(enum Color)-nowPlayer)==0)
{
break; /* 双方都不能落子,游戏结束 */
}

printf("\n%s无子可下.\n",nowPlayerName);

}
else
{
int i,j;

view(pBoard);

if(nowPlayer==player) /* 轮到人下 */
{
while(1)
{
printf("\n%s,请输入棋子坐标(i,j):\n",nowPlayerName);
printf("i=");
scanf("%d",&i);
i--;
printf("j=");
scanf("%d",&j);
j--;
pChoice->posX=i;
pChoice->posY=j;

if(i<0 || i>7 || j<0 || j>7 || pBoard->cell[i][j].color!=BLANK || pBoard->cell[i][j].stable==0)
{
printf("%s不能在(%d,%d)落子.\n",nowPlayerName,i+1,j+1);
}
else
{
break;
}
}
}
else /* 轮到电脑下 */
{
printf("\n%s思考中......",nowPlayerName);
pChoice=maximin(pBoard,nowPlayer,dif,-MAX,MAX,pChoice);
i=pChoice->posX;
j=pChoice->posY;
printf("\tscore=%d\n",pChoice->score);
}

putChess(pBoard,pChoice,nowPlayer);
step++;
printf("\n%s,落子于坐标(%d,%d).\n",nowPlayerName,i+1,j+1);
}

nowPlayer=(enum Color)-nowPlayer; /* 换对方下 */
}

view(pBoard);

success=pBoard->whiteNum - pBoard->blackNum;

if(success>0)
{
printf("\n白棋(○)获胜.\n");
}
else if(success<0)
{
printf("\n黑棋(●)获胜.\n");
}
else
{
printf("\n平局.\n");
}

printf("\n游戏结束!\n");

while(restart!='y' && restart!='n')
{
printf("\n再下一盘?(y,n)\n");
scanf("%c",&restart);
if(restart=='y')
{
goto start;
}
}

return 0;
}

#define N 3
#define WHITE 1
#define BLACK 2
#define BLANK 3

void main(){
int a[2*N+1];
int stepCount = 0;
int blankPos = N;

//初始化
for (int i=0;i<N;i++) a[i]=WHITE;
a[i]=BLANK;i++;
for (;i<2*N+1;i++) a[i]=BLACK;

while(!(a[N-1]==BLACK && a[N+1]==WHITE) ){
//走一步,看blankPos两边4个位置就足够
//走步规则
if (a[blankPos -2 ] == WHITE){
if (isAllowedPos(a,blankPos,WHITE)){
swap(a,blankPos-2,blankPos);
blankPos =blankPos-2;
stepCount++;
continue;
}
}
if (a[blankPos -1 ] == WHITE){
if (isAllowedPos(a,blankPos,WHITE)){
swap(a,blankPos-1,blankPos);
blankPos =blankPos-1;
stepCount++;
continue;
}
}
if (a[blankPos +1 ] == BLACK){
if (isAllowedPos(a,blankPos,BLACK)){
swap(a,blankPos+1,blankPos);
blankPos =blankPos+1;
stepCount++;
continue;
}
}
if (a[blankPos +2 ] == BLACK){
if (isAllowedPos(a,blankPos,BLACK)){
swap(a,blankPos+2,blankPos);
blankPos =blankPos+2;
stepCount++;
continue;
}
}
stepCount++;
}
printf("%d",stepCount);
}

void swap(int array[] int a, int b){
int t;

t=array[b];
array[b]=array[a];
array[a]=t;
}

int isAllowedPos(int array[],int index, int color){
if (array[index-1]==color || array[index+1] ==color)
return 0;
else
return 1;
}

还有一些问题:边界,到位时判断不完全