C趣味程序百例(28)黑白子交换
87.黑白互换
有三个白种和三个黑子排列如下:○○○○○○○○○○○○○○○○○○○○○
游戏的目的是用最少的步数交换上图中白化星和黑子的位置:
●●●●。○○○
游戏规则是:(1)一次只能移动一个棋子;(2)兵可以移动到空格,或跳过一个对手的兵进入空格,但不能向后跳或跳过两个孩子。请用电脑实现以上游戏。
*问题分析与算法设计
计算机解决这类问题的关键是找出问题的规律,或者说制定一套计算机动作的规则。分析这个问题,可以先用人来解决问题,可以总结出以下规律:
(1)黑子向左跳过白子落入空格,转(5)
(2)白子向右跳过黑子落入空格,转(5)
。转(5)
(4)白子向右移动一格,落入空格(但应该没有棋子阻挡),转(5)
(5)判断游戏是否结束,如果没有,转(1)继续。
所谓“堵”现象,就是在移动棋子的过程中,将两个还没有到位的同色棋子连接在一起,使棋盘中的其他棋子无法继续移动。比如移动棋子如下:
0
○○○●
1○○○○○○○○○○96
产生阻塞的现象的原因是在第2步(△状态)时,棋子○不能向右移动,只能将●向左移动。
总结产生阻塞的原因,当棋盘出现“黑、白、空、黑”或“白、空、黑、白”状态时,不能向左或向右移动中间的棋子,只移动两边的棋子。
按照上述规则,可以保证在移动棋子的过程中,不会出现棋子无法移动的现象,且可以用最少的步数完成白子和黑子的位置交换。
*程序与程序注释
#include
int number;
void print(int a[]);
void change(int *n,int *m);
void main()
{
int t={1,1,1,0,2,2,2}; /*初始化数组1:白子 2:黑子 0:空格*/
int i,flag;
print(t);
while(t[0]+t[1]+t[2]!=6||t[4]+t+t!=3) /*判断游戏是否结束
若还没有完成棋子的交换则继续进行循环*/
{
flag=1; /*flag 为棋子移动一步的标记1:尚未移动棋子 0:已经移动棋子*/
for(i=0;flag&&i if(t[i]==1&&t[i+1]==2&&t[i+2]==0)
{change(&t[i],&t[i+2]); print(t); flag=0;}
for(i=0;flag&&i if(t[i]==0&&t[i+1]==1&&t[i+2]==2)
{change(&t[i],&t[i+2]); print(t); flag=0;}
for(i=0;flag&&i if(t[i]==1&&t[i+1]==0&&(i==0||t[i-1]!=t[i+2]))
{change(&t[i],&t[i+1]); print(t);flag=0;}
for(i=0;flag&&i if(t[i]==0&&t[i+1]==2&&(i==5||t[i-1]!=t[i+2]))
{ change(&t[i],&t[i+1]); print(t);flag=0;}
}
}
void print(int a[])
{
int i;
printf("No. %2d:.............................\n",number++);
printf(" ");
for(i=0;i
0条评论