马踏棋盘游戏

设计一个国际象棋的马踏遍棋盘的演示程序。


#include"stdio.h"
#include"stdlib.h"
#include"conio.h"
#include"windows.h"
#define N 12
int top=0;                               //栈顶指针用于记录步数
int col[]= {2,1,-1,-2,-2,-1,1,2};
int row[]= {-1,-2,-2,-1,1,2,2,1};
struct stack
{
    int x;
    int y;
    int step;
} ma[N*N+1]= {{0,0,0}};

void push(int a[][N],int i,int j,int m)   //进栈
{
    ma[top].x=i;
    ma[top].y=j;
    ma[top].step=m;
    a[i][j]=++top;
}

int pop(int a[][N])                       //出栈
{
    int temp;
    top--;
    a[ma[top].x][ma[top].y]=0;
    ma[top].x=0;
    ma[top].y=0;
    temp=ma[top].step+1;                   //转为下一个方向
    ma[top].step=0;
    return temp;
}
int judge(int i,int j,int a[][N])              //判断是否可跳
{
    if(i>=0&&j>=0&&i<N&&j<N&&a[i][j]==0)
        return 1;
    return 0;
}

int jump(int i,int j,int a[][N])
{
    int t,ti=i,tj=j,count=0;
    for(t=0; t<8; t++)
    {
        ti+=row[t];
        tj+=col[t];
        if(judge(ti,tj,a))
            count++;               //计算第二次有多少可跳的方向
        ti-=row[t];
        tj-=col[t];
    }
    return count;
}


int sort(int a[8])                 //参数a数组表示选择每个方向后有多少跳法
{
    int i,min=a[0],t=0;
    for(i=1; i<8; i++)
    {
        if(min>a[i]&&a[i]>-1&&a[i]<8)
        {
            min=a[i];                //找出可跳方向最少的路径
            t=i;
        }
    }
    return t;
}


void disp(int a[][N])
{
    int t,i,j,count=0,b[N][N]= {0};
    for(t=0; t<N*N; t++)
    {
        system("cls");
        printf("显示跳马过程...\n");
        count++;
        for(i=0; i<N; i++)
        {
            for(j=0; j<N; j++)
            {
                if(a[i][j]==count)
                    {
                        b[i][j]=count;
                        break;
                    }
            }
        }
        for(i=0; i<N; i++)
        {
            for(j=0; j<N; j++)
                printf("%4d",b[i][j]);
            printf("\n");
        }
        Sleep(500);
    }
    system("cls");
    printf("最终结果为:\n");
     for(i=0; i<N; i++)
        {
            for(j=0; j<N; j++)
                printf("%4d",b[i][j]);
            printf("\n");
        }

}

void horse(int x,int y)
{
    int i=x,j=y,min,ti,tj,t,temp=0,flag=0,temp1=0;
    int count[8],num[8]= {0};
    int a[N][N]= {{0}};
    for(x=0; x<8; x++)
        count[x]=8;
    push(a,i,j,0);
    while(top<N*N)
    {
        ti=i;
        tj=j;
        temp1=0;
        flag=0;                         //flag表示能否继续跳跃
        for(x=0; x<8; x++)
            count[x]=8;
        for(t=temp; t<8; t++,temp1++)   //计算第一次有多少可跳的方向
        {
            ti+=row[t];
            tj+=col[t];
            if(judge(ti,tj,a))
            {
                count[temp1]=jump(ti,tj,a);  //count数组表示第一次选择的跳跃方向进行第二次跳跃时有多少方向
                flag=1;
            }
            ti-=row[t];
            tj-=col[t];
        }
        if(flag)
        {
            min=sort(count);                  //选择路径最少的方向先跳
            ti+=row[min];
            tj+=col[min];
            push(a,ti,tj,min);
            i=ti;
            j=tj;
            temp=0;
        }
        else
        {
            temp=pop(a);                    //当不能继续跳跃时,出栈回到上一次跳跃位置
            i=ma[top-1].x;
            j=ma[top-1].y;
        }
    }
    printf("\n\n");
    disp(a);
}

main()
{
    int x,y;
    char c;
    printf("                    ********欢迎使用跳马程序********\n");
    while(1)
    {
        system("cls");
        printf("                    ************欢迎使用跳马程序************\n");
        printf("                    *             1.玩法说明               *\n");
        printf("                    *             2.开始游戏               *\n");
        printf("                    *             3.退出游戏               *\n");
        printf("                    ****************************************\n");
        printf("                    请输入功能选项(1..3): ");
        c=getchar();
        system("cls");
        switch(c)
        {
        case '1':
            printf("给定9×9的棋盘格,输入马的任意初始位置,马按“日”字形跳,开始游戏后将显示马跳通所有格子的路径,格子中的数字代表马在第几次跳跃时跳到该格子\n");
            break;
        case '2':
            do
            {
                printf("请输入马初始位置的x坐标:");
                scanf("%d",&x);
                printf("请输入马初始位置的y坐标:");
                scanf("%d",&y);
                if(x>N||y>N||x<1||y<1)
                    printf("错误!请重新输入,X(1~%d),Y(1~%d)\n",N,N);
            }while(x>N||y>N||x<1||y<1);
            system("pause");
            system("cls");
            horse(x-1,y-1);
            break;
         case '3':
            exit(1);
            break;
        default:
            printf("输入有误\n");
        }
        system("pause");
        getchar();
    }
    return 0;
}



package 蓝桥;

//import java.util.Scanner;

public class 马踏棋盘 {

	public static int [][]board=new int[8][8]; 
	public static int index=1;
    public static int x=4;
    public static int y=7;
	public static void main(String[] args) {
		board[x][y]=1;
		hours();
	}
	public static void hours() {
		if(index==64)
		{
			for(int i=0;i<8;i++)
			{
				for(int j=0;j<8;j++)
				{
					System.out.printf("%2d",board[i][j]);
					System.out.print(" ");
				}
				System.out.println();
			}
			System.exit(0);
		}
		else{
			int []b=sort();
			for(int i=0;i<8;i++)
			{
				
  					index++;
					jumpto(b[i]);
					hours();
					index--;
					jumpback(b[i]);
				
			}
		}
		
	}
	public static int jump(int way) {
		switch (way) {
		case 0:
			if(x-2>=0&&y+1<8&&board[x-2][y+1]==0)
			{
				return 1;
			}
			break;
		case 1:
			if(x-1>=0&&y+2<8&&board[x-1][y+2]==0)
			{
				return 1;
			}
			break;
		case 2:
			if(x+1<8&&y+2<8&&board[x+1][y+2]==0)
			{
				return 1;
			}
			break;
		case 3:
			if(x+2<8&&y+1<8&&board[x+2][y+1]==0)
			{
				return 1;
			}
			break;
		case 4:
			if(x+2<8&&y-1>=0&&board[x+2][y-1]==0)
			{
				return 1;
			}
			break;
		case 5:
			if(x+1<8&&y-2>=0&&board[x+1][y-2]==0)
			{
				return 1;
			}
			break;
		case 6:
			if(x-1>=0&&y-2>=0&&board[x-1][y-2]==0)
			{
				return 1;
			}
			break;
		case 7:
 			if(x-2>=0&&y-1>=0&&board[x-2][y-1]==0)
			{
				return 1;
			}
			break;

		default:
			break;
		}
		return 0;
		
	}
	public static int jump(int xi,int yi,int way) {
		switch (way) {
		case 0:
			if(xi-2>=0&&yi+1<8&&board[xi-2][yi+1]==0)
			{
				return 1;
			}
			break;
		case 1:
			if(xi-1>=0&&yi+2<8&&board[xi-1][yi+2]==0)
			{
				return 1;
			}
			break;
		case 2:
			if(xi+1<8&&yi+2<8&&board[xi+1][yi+2]==0)
			{
				return 1;
			}
			break;
		case 3:
			if(xi+2<8&&yi+1<8&&board[xi+2][yi+1]==0)
			{
				return 1;
			}
			break;
		case 4:
			if(xi+2<8&&yi-1>=0&&board[xi+2][yi-1]==0)
			{
				return 1;
			}
			break;
		case 5:
			if(xi+1<8&&yi-2>=0&&board[xi+1][yi-2]==0)
			{
				return 1;
			}
			break;
		case 6:
			if(xi-1>=0&&yi-2>=0&&board[xi-1][yi-2]==0)
			{
				return 1;
			}
			break;
		case 7:
 			if(xi-2>=0&&yi-1>=0&&board[xi-2][yi-1]==0)
			{
				return 1;
			}
			break;

		default:
			break;
		}
		return 0;
		
	}    
    public static void jumpto( int way) {
    	switch (way) {
		case 0:
		{
			x=x-2;y=y+1;
			board[x][y]=index;
		}
			break;
		case 1:
		{
			x=x-1;y=y+2;
			board[x][y]=index;
		}
			break;
		case 2:
		{
			x=x+1;y=y+2;
			board[x][y]=index;
		}
			break;
		case 3:
		{
			x=x+2;y=y+1;
			board[x][y]=index;
		}
			break;
		case 4:
		{
			x=x+2;y=y-1;
			board[x][y]=index;
		}
			break;
		case 5:
		{
			x=x+1;y=y-2;
			board[x][y]=index;
		}
			break;
		case 6:
		{
			x=x-1;y=y-2;
			board[x][y]=index;
		}
			break;
		case 7:
		{
			x=x-2;y=y-1;
			board[x][y]=index;
		}
			break;

		default:
			break;
		}
		
	}
    public static void jumpback(int way) {
    	switch (way) {
		case 0:
		{board[x][y]=0;
			x=x+2;y=y-1;
			
		}
			break;
		case 1:
		{
			board[x][y]=0;
			x=x+1;y=y-2;
			
		}
			break;
		case 2:
		{board[x][y]=0;
			x=x-1;y=y-2;
			
		}
			break;
		case 3:
		{board[x][y]=0;
			x=x-2;y=y-1;
			
		}
			break;
		case 4:
		{board[x][y]=0;
			x=x-2;y=y+1;
			
		}
			break;
		case 5:
		{	board[x][y]=0;
			x=x-1;y=y+2;
		
		}
			break;
		case 6:
		{board[x][y]=0;
			x=x+1;y=y+2;
			
		}
			break;
		case 7:
		{board[x][y]=0;
			x=x+2;y=y+1;
			
		}
			break;

		default:
			break;
		}
		
} 
    public static int [] jumpto(int xi,int yi, int way) {
    	switch (way) {
		case 0:
		{
			xi=xi-2;yi=yi+1;
		}
			break;
		case 1:
		{
			xi=xi-1;yi=yi+2;
		}
			break;
		case 2:
		{
			xi=xi+1;yi=yi+2;
		}
			break;
		case 3:
		{
			xi=xi+2;yi=yi+1;
		}
			break;
		case 4:
		{
			xi=xi+2;yi=yi-1;
		}
			break;
		case 5:
		{
			xi=xi+1;yi=yi-2;
		}
			break;
		case 6:
		{
			xi=xi-1;yi=yi-2;
		}
			break;
		case 7:
		{
			xi=xi-2;yi=yi-1;
		}
			break;

		default:
			break;
		}
    	int []a=new int [2];
    	a[0]=xi;a[1]=yi;
		return a;
		
	}
    
    
    
    public static int  num(int way) {
    	int sum=0;
    	int xi=x;
    	int yi=y;
    	int []a=jumpto(xi, yi, way);
    	for(int i=0;i<8;i++)
    	{
    		if(jump(a[0], a[1], i)==1)
    			sum++;
    	}
		return sum;
	}
    
    
    
    public static int [] sort() {
    	int []a=new int [8];
    	for(int i=0;i<8;i++)
    	{
    		if(jump(i)==0)
    		{
    			a[i]=100;
    		}
    		else{
    			a[i]=num(i);
    		}
    	}
    	
    	int loc=0;
    	int []b=new int [8];
    	for(int m=0;m<8;m++)
    	{
    		int min=100;
    		for(int i=0;i<8;i++)
    		{
    			if(a[i]<min)
    			{
    				min=a[i];
    				loc=i;
    			}
    		}
    		b[m]=loc;
    		a[loc]=10;
    	}

		return b;
	}
}



  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
问题描述:将马随机放在国际象棋的 8X8 棋盘中的某个方格中 马按走棋规则进行移动 要求每个方格上只进入一次 走遍棋盘上全部 64 个方格 编制递归程序 求出马的行走路线 并按求出的行走路线 将数字 1 2 … 64 依次填入 8X8 的方阵输出之 测试数据:由读者指定可自行指定一个马的初始位置 实现提示:每次在多个可走位置中选择一个进行试探 其余未曾试探过的可走位置必须用适当结构妥善管理 以备试探失败时的“回溯”悔棋使用 并探讨每次选择位置的“最佳策略” 以减少回溯的次数 背景介绍: 国际象棋为许多令人着迷的娱乐提供了固定的框架 而这些框架常独立于游戏本身 其中的许多框架都基于骑士奇异的L型移动规则 一个经典的例子是骑士漫游问题 从十八世纪初开始 这个问题就引起了数学家和解密爱好者的注意 简单地说 这个问题要求从棋盘上任一个方格开始按规则移动骑士 使之成功的游历国际象棋棋盘的64个方格 且每个方格都接触且仅接触一次 可以用一种简便的方法表示问题的一个解 即将数字1 64按骑士到达的顺序依次放入棋盘的方格中 一种非常巧妙的解决骑士漫游地方法由J C Warnsdorff于1823年给出 他给出的规则是:骑士总是移向那些具有最少出口数且尚未到达的方格之一 其中出口数是指通向尚未到达方格的出口数量 在进一步的阅读之前 你可以尝试利用Warnsdorff规则手工构造出该问题的一个解 实习任务: 编写一个程序来获得马踏棋盘即骑士漫游问题的一个解 您的程序需要达到下面的要求: 棋盘的规模是8 8; 对于任意给定的初始化位置进行试验 得到漫游问题的解; 对每次实验 按照棋盘矩阵的方式 打印每个格被行径的顺序编号 技术提示: 解决这类问题的关键是考虑数据在计算机中的存储表示 可能最自然的表示方法就是把棋盘存储在一个8 8的二维数组board中 以 x y 为起点时骑士可能进行的八种移动 一般来说 位于 x y 的骑士可能移动到以下方格之一: x 2 y+1 x 1 y+2 x+1 y+2 x+2 y+1 x+2 y 1 x+1 y 2 x 1 y 2 x 2 y 1 但请注意 如果 x y 的位置离某一条边较近 有些可能的移动就会把骑士移到棋盘之外 而这当然是不允许的 骑士的八种可能的移动可以用一个数组MoveOffset方便地表示出来: MoveOffset[0] 2 1 MoveOffset[1] 1 2 MoveOffset[2] 1 2 MoveOffset[3] 2 1 MoveOffset[4] 2 1 MoveOffset[5] 1 2 MoveOffset[6] 1 2 MoveOffset[7] 2 1 于是 位于 x y 的骑士可以移动到 x+MoveOffset[k] x y+MoveOffset[k] y 其中k是0到7之间的某个整数值 并且新方格必须仍位于棋盘上 扩展需求:可以考虑将结果图形化 b 考察所有初始化的情况 测试是否都能够得到解 ">问题描述:将马随机放在国际象棋的 8X8 棋盘中的某个方格中 马按走棋规则进行移动 要求每个方格上只进入一次 走遍棋盘上全部 64 个方格 编制递归程序 求出马的行走路线 并按求出的行走路线 将数字 1 2 … 64 依 [更多]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值