# include <stdio.h>
/****************************************
*程序名称: 跳 马 *
*程序作者: flyli(ProgramFan) *
*程序版本: 1.01 *
*完成时间:2006.6.1 *
*修改时间: *
*程序说明:此程序所完成的事情是算出中国 *
* 象棋中的“马”从一个位置调到 *
* 另一个位置的所有算法。 *
* 上一版本(1.01)中的马只能向 *
* 右走,此版本去除了以上限制, *
* 规定马可以往任何方向走,只是 *
* 不能走重复的路线而以。提高了 *
* 的难度程序 。 *
*特殊说明:由于此程序的运算量较大,如果 *
* 使用像上一版本那样的链表法的 *
* 话,程序的运算速度将会大幅下 *
* 降,于是此程序用的是数组,模 *
* 拟堆栈的方法 *
****************************************/
/********************
* 宏定义 *
********************/
# define XNum 4 //棋盘的大小
# define YNum 5
/********************
* 全局变量 *
********************/
char Map[10][10] = {0}; //默认值,如果需要可以把次值改的和棋盘大小一样
char *PIHead,*PIP2,*PIR;
char MidSate=0;
unsigned ALL;
void NewInformation(char X,char Y,char Sate);
char SetStart(char X,char Y,char Sate);
void Del_Free(void);
/*******************
* 主函数 *
*******************/
int main(void)
{
Map[0][0] = 1;
PIHead = PIP2 = malloc(sizeof(char)*(10*10*3+1));
*PIP2 = 0;PIP2 ++;*PIP2 = 0;PIP2 ++;*PIP2 = 0;PIP2 ++;//主要是判断结束时用的标志
*PIP2 = 0;PIP2 ++;*PIP2 = 0;PIP2 ++;*PIP2 = 0;PIP2 ++;//初始化第一个 步骤
while(PIP2 != PIHead) //当PIP2还没有指向最头的时候
{
while(SetStart(*(PIP2-3),*(PIP2-2),MidSate))//再探索
{
MidSate=1; //每层都从第一种可能开始扫描
}
Del_Free(); //扫描不动时 返回上一层
while(MidSate == 9) //防止程序停在最后一种可能性上
{
Del_Free();
}
}
free(PIHead);
printf(“%d”,ALL);
system(“pause”);
return 0;
}
/***********************************
*函数说明:建立一个新点的信息 *
*函数输入:新的链中的字符位置 *
***********************************/
void NewInformation(char X,char Y,char Sate)
{
*PIP2 = X; // 对小指针的各位进行赋值
PIP2++;
*PIP2 = Y;
PIP2++;
*PIP2 = Sate;
PIP2++;
*PIP2=’X';
}
char SetStart(char X,char Y,char Sate)
{
if (Sate ==1)
goto X1;
else if (Sate ==2)
goto X2;
else if (Sate ==3)
goto X3;
else if (Sate ==4)
goto X4;
else if (Sate ==5)
goto X5;
else if (Sate ==6)
goto X6;
else if (Sate ==7)
goto X7;
else if (Sate ==8)
goto X8;
X1: if(X+1<XNum && Y+2<YNum && Map[X+1][Y+2] != 1) //当马跳后不会超出棋盘时
{
NewInformation(X+1,Y+2,1); //继续跳
Map[X+1][Y+2] = 1; //将地图上的跳过的点进行标记
return 1; //判断变量为真
}
X2: if(X+1<XNum && Y-2>=0 && Map[X+1][Y-2] != 1)
{
NewInformation(X+1,Y-2,2);
Map[X+1][Y-2] = 1;
return 1;
}
X3: if(X+2<XNum && Y+1<YNum && Map[X+2][Y+1] !=1)
{
NewInformation(X+2,Y+1,3);
Map[X+2][Y+1] = 1;
return 1;
}
X4: if(X+2<XNum && Y-1>=0 && Map[X+2][Y-1] !=1)
{
NewInformation(X+2,Y-1,4);
Map[X+2][Y-1]= 1;
return 1;
}
X5: if(X-1>=0 && Y+2<YNum && Map[X-1][Y+2] != 1)
{
NewInformation(X-1,Y+2,5);
Map[X-1][Y+2] = 1;
return 1;
}
X6: if(X-1>=0 && Y-2>=0 && Map[X-1][Y-2] != 1)
{
NewInformation(X-1,Y-2,6);
Map[X-1][Y-2] = 1;
return 1;
}
X7: if(X-2>=0 && Y+1<YNum && Map[X-2][Y+1] !=1)
{
NewInformation(X-2,Y+1,7);
Map[X-2][Y+1] = 1;
return 1;
}
X8: if(X-2>=0 && Y-1>=0 && Map[X-2][Y-1] !=1)
{
NewInformation(X-2,Y-1,8);
Map[X-2][Y-1]= 1;
return 1;
}
/*============以上是马总共有的8种条法==============*/
if(*(PIP2-3) == XNum-1&& *(PIP2-2) == YNum-1)
{
ALL++;
/* PIR = PIHead;
PIR+=3;
while(*PIR != ‘X’)
{
printf(“%d,”,*PIR);
PIR++;
printf(“%d “,*PIR);
PIR+=2;
}
puts(“\n”);*/
//以上一小部分为打印路径是要用到的代码,需要的时候可以去掉注释以观察路经
}
return 0;
}
/***********************************
*函数说明:删除一个一个无用的信息 *
*函数输入: *
***********************************/
void Del_Free(void)
{
char x,y;
PIP2 –;
MidSate = *PIP2+1; //对中间变量进行赋值
*PIP2 = ‘X’;
PIP2 –;
y=*PIP2; //为了将地图上的标记也同时磨掉,所以把坐标保留下来
*PIP2 = ‘X’;
PIP2 –;
x=*PIP2;
*PIP2 = ‘X’;
Map[x][y] = 0;
}
/****************************************
*程序名称: 跳 马 *
*程序作者: flyli(ProgramFan) *
*程序版本: 1.01 *
*完成时间:2006.6.1 *
*修改时间: *
*程序说明:此程序所完成的事情是算出中国 *
* 象棋中的“马”从一个位置调到 *
* 另一个位置的所有算法。 *
* 上一版本(1.01)中的马只能向 *
* 右走,此版本去除了以上限制, *
* 规定马可以往任何方向走,只是 *
* 不能走重复的路线而以。提高了 *
* 的难度程序 。 *
*特殊说明:由于此程序的运算量较大,如果 *
* 使用像上一版本那样的链表法的 *
* 话,程序的运算速度将会大幅下 *
* 降,于是此程序用的是数组,模 *
* 拟堆栈的方法 *
****************************************/
/********************
* 宏定义 *
********************/
# define XNum 4 //棋盘的大小
# define YNum 5
/********************
* 全局变量 *
********************/
char Map[10][10] = {0}; //默认值,如果需要可以把次值改的和棋盘大小一样
char *PIHead,*PIP2,*PIR;
char MidSate=0;
unsigned ALL;
void NewInformation(char X,char Y,char Sate);
char SetStart(char X,char Y,char Sate);
void Del_Free(void);
/*******************
* 主函数 *
*******************/
int main(void)
{
Map[0][0] = 1;
PIHead = PIP2 = malloc(sizeof(char)*(10*10*3+1));
*PIP2 = 0;PIP2 ++;*PIP2 = 0;PIP2 ++;*PIP2 = 0;PIP2 ++;//主要是判断结束时用的标志
*PIP2 = 0;PIP2 ++;*PIP2 = 0;PIP2 ++;*PIP2 = 0;PIP2 ++;//初始化第一个 步骤
while(PIP2 != PIHead) //当PIP2还没有指向最头的时候
{
while(SetStart(*(PIP2-3),*(PIP2-2),MidSate))//再探索
{
MidSate=1; //每层都从第一种可能开始扫描
}
Del_Free(); //扫描不动时 返回上一层
while(MidSate == 9) //防止程序停在最后一种可能性上
{
Del_Free();
}
}
free(PIHead);
printf(“%d”,ALL);
system(“pause”);
return 0;
}
/***********************************
*函数说明:建立一个新点的信息 *
*函数输入:新的链中的字符位置 *
***********************************/
void NewInformation(char X,char Y,char Sate)
{
*PIP2 = X; // 对小指针的各位进行赋值
PIP2++;
*PIP2 = Y;
PIP2++;
*PIP2 = Sate;
PIP2++;
*PIP2=’X';
}
char SetStart(char X,char Y,char Sate)
{
if (Sate ==1)
goto X1;
else if (Sate ==2)
goto X2;
else if (Sate ==3)
goto X3;
else if (Sate ==4)
goto X4;
else if (Sate ==5)
goto X5;
else if (Sate ==6)
goto X6;
else if (Sate ==7)
goto X7;
else if (Sate ==8)
goto X8;
X1: if(X+1<XNum && Y+2<YNum && Map[X+1][Y+2] != 1) //当马跳后不会超出棋盘时
{
NewInformation(X+1,Y+2,1); //继续跳
Map[X+1][Y+2] = 1; //将地图上的跳过的点进行标记
return 1; //判断变量为真
}
X2: if(X+1<XNum && Y-2>=0 && Map[X+1][Y-2] != 1)
{
NewInformation(X+1,Y-2,2);
Map[X+1][Y-2] = 1;
return 1;
}
X3: if(X+2<XNum && Y+1<YNum && Map[X+2][Y+1] !=1)
{
NewInformation(X+2,Y+1,3);
Map[X+2][Y+1] = 1;
return 1;
}
X4: if(X+2<XNum && Y-1>=0 && Map[X+2][Y-1] !=1)
{
NewInformation(X+2,Y-1,4);
Map[X+2][Y-1]= 1;
return 1;
}
X5: if(X-1>=0 && Y+2<YNum && Map[X-1][Y+2] != 1)
{
NewInformation(X-1,Y+2,5);
Map[X-1][Y+2] = 1;
return 1;
}
X6: if(X-1>=0 && Y-2>=0 && Map[X-1][Y-2] != 1)
{
NewInformation(X-1,Y-2,6);
Map[X-1][Y-2] = 1;
return 1;
}
X7: if(X-2>=0 && Y+1<YNum && Map[X-2][Y+1] !=1)
{
NewInformation(X-2,Y+1,7);
Map[X-2][Y+1] = 1;
return 1;
}
X8: if(X-2>=0 && Y-1>=0 && Map[X-2][Y-1] !=1)
{
NewInformation(X-2,Y-1,8);
Map[X-2][Y-1]= 1;
return 1;
}
/*============以上是马总共有的8种条法==============*/
if(*(PIP2-3) == XNum-1&& *(PIP2-2) == YNum-1)
{
ALL++;
/* PIR = PIHead;
PIR+=3;
while(*PIR != ‘X’)
{
printf(“%d,”,*PIR);
PIR++;
printf(“%d “,*PIR);
PIR+=2;
}
puts(“\n”);*/
//以上一小部分为打印路径是要用到的代码,需要的时候可以去掉注释以观察路经
}
return 0;
}
/***********************************
*函数说明:删除一个一个无用的信息 *
*函数输入: *
***********************************/
void Del_Free(void)
{
char x,y;
PIP2 –;
MidSate = *PIP2+1; //对中间变量进行赋值
*PIP2 = ‘X’;
PIP2 –;
y=*PIP2; //为了将地图上的标记也同时磨掉,所以把坐标保留下来
*PIP2 = ‘X’;
PIP2 –;
x=*PIP2;
*PIP2 = ‘X’;
Map[x][y] = 0;
}
>> 本文固定链接: http://www.vcgood.com/archives/1384