UVa1589 象棋

        考虑一个象棋残局,其中红方有n 2≤ n ≤7 )个棋子,黑方只有一个将。红方除了有一个 帅(G )之外还有 3 种可能的棋子:车( R ),马( H ),炮( C ),并且需要考虑 蹩马 腿” (如图 4-4 所示)与将和帅不能照面(将、帅如果同在一条直线上,中间又不隔着任何棋 子的情况下,走子的一方获胜)的规则。
        输入所有棋子的位置,保证局面合法并且红方已经将军。你的任务是判断红方是否已经把黑方将死。关于中国象棋的相关规则请参见原题。
大一新生,欢迎各位大佬评论提出宝贵意见,觉得对你有用的话点个赞吧!
也可以评论一下想看的题目,我可以去试试 ^v^

头文件(函数的声明)

#include<stdio.h>
#include<string.h>
#include<windows.h>

void menu();//简单打印一个游戏菜单

void show(char[10][9][3]);//用于展示棋盘

void makeboard(char[10][9][3], const char[]);//棋盘的初始化

void puthead(char [10][9][3], char[10][9][3], const char[]);//放置双方将帅

void putchess(char[10][9][3], char[10][9][3], const char[]);//防止普通棋子

int  judge(char[10][9][3]);//判断该情况是否被将死

int  find(int*, int*, char[10][9][3], const char[]);//寻找某个棋子

主函数部分(源文件)

#include"deffunction.h"

int main()
{
	int no, key = 0, hang = 0, lie = 0;
	char showboard[10][9][3];
    //由于象棋是汉字,汉字应该用字符串来表示,占两个字节,所以用三维数组,理解起来就是二维数组的                
    //每个元素为字符串
   	char trueboard[10][9][3];
	char beif[3];
	do
	{
	loop://未被将死时返回此处
		menu();
		no = scanf("%d", &key);
		if (key == 1)
		{
			no = 0;
			hang = 0, lie = 0;
			system("cls");
			makeboard(showboard, " ");//showboard为展示棋盘,初始化为‘ ’
			makeboard(trueboard, "0");//trueboard为用于判断的棋盘,初始化为‘0’
			show(showboard);//打印棋盘
			puthead(trueboard, showboard, "r");//先放置红方的帅
            system("cls");
            show(showboard);//清屏之后再打印棋盘为了美观
			putchess(trueboard, showboard, "r");//再放置普通棋子
            system("cls");
            show(showboard);
			puthead(trueboard, showboard, "b");//放置黑方将
            system("cls");
            show(showboard);
			show(showboard);//打印棋盘
			find(&hang, &lie, trueboard, "Q");//寻找到将的位置
            //寻找到之后判断将的位置,决定将是否能移动,移动之后判定是否被将死
			if (hang + 1 < 10)
			{
				strcpy(beif, trueboard[hang + 1][lie]);//先记录下将要移动到的位置的棋子
				strcpy(trueboard[hang + 1][lie], "Q");//再将将移动过去
				strcpy(trueboard[hang][lie], "0");//把原来将的位置设为‘0’
				no = judge(trueboard);//判定是否将军
				if (no)
				{
                    system("cls");
                    show(showboard);//打印黑方没有将死的走法
					printf("黑方未被将死\n\n");
					system("pause");
					system("cls");
					goto loop;
				}
				strcpy(trueboard[hang + 1][lie], beif);把记录下的棋子放回原处
				strcpy(trueboard[hang][lie], "Q");//把将放回原处
			}
			if (hang - 1 >6)
			{
				strcpy(beif, trueboard[hang - 1][lie]);
				strcpy(trueboard[hang - 1][lie], "Q");
				strcpy(trueboard[hang][lie], "0");
				no = judge(trueboard);
				if (no)
				{
                    system("cls");
                    show(showboard);
					printf("黑方未被将死\n\n");
					system("pause");
					system("cls");
					goto loop;
				}
				strcpy(trueboard[hang - 1][lie], beif);
				strcpy(trueboard[hang][lie], "Q");
			}
			if (lie + 1 < 6)
			{
				strcpy(beif, trueboard[hang][lie + 1]);
				strcpy(trueboard[hang][lie + 1], "Q");
				strcpy(trueboard[hang][lie], "0");
				no = judge(trueboard);
				if (no)
				{
                    system("cls");
                    show(showboard);
					printf("黑方未被将死\n\n");
					system("pause");
					system("cls");
					goto loop;
				}
				strcpy(trueboard[hang][lie + 1], beif);
				strcpy(trueboard[hang][lie], "Q");
			}
			if (lie - 1 > 2)
			{
				strcpy(beif, trueboard[hang][lie - 1]);
				strcpy(trueboard[hang][lie - 1], "Q");
				strcpy(trueboard[hang][lie], "0");
				no = judge(trueboard);
				if (no)
				{
                    system("cls");
                    show(showboard);
					printf("黑方未被将死\n\n");
					system("pause");
					system("cls");
					goto loop;
				}
				strcpy(trueboard[hang][lie - 1], beif);
				strcpy(trueboard[hang][lie], "Q");
			}
			printf("黑方已经被将死\n\n");//若没有返回loop处,则表示黑方被将死
			system("pause");
			system("cls");
		}
	} while (key);
	return 0;
}

函数定义(源文件)

#include"deffunction.h"

void menu()
{
	printf("####################################\n");
	printf("##########   1.开始游戏   ##########\n");
	printf("##########   0.退出游戏   ##########\n");
	printf("####################################\n");
	printf("请选择--> ");
}

void show(char board[10][9][3])
{
	int  hang = 0,lie = 0, i = 0;
	printf("   ");
	for (i = 0; i < 9; i++)
		printf(" %-4d", i + 1);
	printf("\n");
	for (hang = 0; hang < 10; hang++)
	{
		printf("%2d ", hang + 1);
		for (lie = 0; lie < 8; lie++)
			printf("%2s---", board[hang][lie]);
		printf("%2s\n", board[hang][lie]);
		if (hang == 4)
		{
			printf("   ");
			printf("||       楚河                汉界       ||\n");
			continue;
		}
		if (hang < 9)
		{
			if (hang == 0)
				printf("   ||   ||   ||   || \\ || / ||   ||   ||   ||\n");
			else if (hang == 1)
				printf("   ||   ||   ||   || / || \\ ||   ||   ||   ||\n");
			else if (hang == 7)
				printf("   ||   ||   ||   || \\ || / ||   ||   ||   ||\n");
			else if (hang == 8)
				printf("   ||   ||   ||   || / || \\ ||   ||   ||   ||\n");
			else 
				printf("   ||   ||   ||   ||   ||   ||   ||   ||   ||\n");
		}
	}
	printf("\n");
}

void makeboard(char board[10][9][3], const char c[])
{
	int lie, hang;
	for (hang = 0; hang < 10; hang++)
		for (lie = 0; lie < 9; lie++)
		{
			strcpy(board[hang][lie], c);
			//初始化为字符串c
		}
}

void puthead(char trueboard[10][9][3], char showboard[10][9][3], const char c[])
{
	int hang, lie, no;
	loop:
	if (c == "r")
	{
		printf("请选择红方“帅”的位置 --> ");//个人设定红方在上,黑方在下
		no = scanf("%d%d", &hang, &lie);
		if (hang < 0 || hang > 3 || lie < 4 || lie > 6)
		{
			printf("输入无效,请重新输入");
			goto loop;
		}
		strcpy(showboard[hang - 1][lie - 1] , "帅");
		strcpy(trueboard[hang - 1][lie - 1] , "s" );
	}
	else
	{
		printf("请选择黑方“将”的位置 --> ");
		no = scanf("%d%d", &hang, &lie);
		if (hang > 10 || hang < 8 || lie < 4 || lie > 6)
		{
			printf("输入无效,请重新输入");
			goto loop;
		}
		strcpy(showboard[hang - 1][lie - 1], "将");
		strcpy(trueboard[hang - 1][lie - 1], "Q" );
	}
}

void putchess(char trueboard[10][9][3], char showboard[10][9][3], const char c[])
{
	char ml[3] = "0";
	int a1 = 0, a2 = 0, a3 = 0, k = 0, hang, lie, no;
	//a1,a2,a3用于记录不同种类棋子放置的数量,当三个都为2时自动结束放置
	//no无实际意义,用于减少vs的警告
	//k用于判定操作
	do
	{
		if (a1 == 2 && a2 == 2 && a3 == 2)
		{
			printf("放置结束\n");
			Sleep(800);
			break;
		}
		system("cls");
		show(showboard);//打印棋盘
		show(trueboard);
		printf("输入“0”结束放置\n");
		printf("请选择红方将要放置的棋子: 1.马 2.车 3.炮   --->");
		no = scanf("%d", &k);
		switch (k)
		{
		case 1:
			loop1:
			if (a1 == 2)//最多放置两个同类型的棋子
			{
				printf("您没马了\n");
				Sleep(800);
				break;
			}
			printf("请选择红方“马”的位置 -->");
			no = scanf("%d%d", &hang, &lie);
			if (hang < 0 || hang > 10 || lie < 0 || lie > 9 || strcmp(trueboard[hang - 1][lie - 1], "0") != 0)
			{
				printf("输入无效,请重新输入\n");
				goto loop1;
			}
			strcpy(showboard[hang - 1][lie - 1], "马");
			strcpy(trueboard[hang - 1][lie - 1], "m" );
			a1++;
			break;
		case 2:
			loop2:
			if (a2 == 2)
			{
				printf("规则只允许场上存在红方两个“车”\n");
				Sleep(800);
				break;
			}
			printf("请选择红方“车”的位置 -->");
			no = scanf("%d%d", &hang, &lie);
			if (hang < 0 || hang > 10 || lie < 0 || lie > 9 || strcmp(trueboard[hang - 1][lie - 1], "0") != 0)
			{
				printf("输入无效,请重新输入\n");
				goto loop2;
			}
			strcpy(showboard[hang - 1][lie - 1], "车");
			strcpy(trueboard[hang - 1][lie - 1], "c" );
			a2++;
			break;
		case 3:
			loop3:
			if (a3 == 2)
			{
				printf("规则只允许场上存在红方两个“炮”\n");
				Sleep(800);
				break;
			}
			printf("请选择红方“炮”的位置 -->");
			no = scanf("%d%d", &hang, &lie);
			if (hang < 0 || hang > 10 || lie < 0 || lie > 9 || strcmp(trueboard[hang - 1][lie - 1], "0") != 0)
			{
				printf("输入无效,请重新输入\n");
				goto loop3;
			}
			strcpy(showboard[hang - 1][lie - 1], "炮");
			strcpy(trueboard[hang - 1][lie - 1], "p" );
			a3++;
			break;
		default:
			break;
		}
	} while (k);
}

int  judge(char board[10][9][3])
{
	int hang = 0, lie = 0, hang1 = 0, lie1 = 0, hang3 = 0, lie3 = 0, n = 0, mid = 0;
	//hang来记录“将”的位置,hang1来记录红方某个棋子的位置,hang3为变量,n用于记录find的返回值,mid用于统计两个棋子中间棋子的数量

	find(&hang, &lie, board, "Q");
	//找到“将”的位置

	n = find(&hang1, &lie1, board, "s");
	//找到"帅"的位置
	if (n)
		for (hang3 = 0; hang3 < 10; hang3++)//
			if (strcmp(board[hang3][lie1], "Q") == 0)
				return 1;//如果帅将对面,则黑方未被将死

	hang1 = 0; lie1 = 0;//hang1初始化从头开始找起

	n = find(&hang1, &lie1, board, "c");//找到第一个车
	if (n)
	{
		if (hang1 == hang && lie1 > lie)//只有在hang1与hang相同,或者lie1与lie相同的时候车才可能将军
		{
			mid = 1;//mid设为1表示处于同一行,如果没有变成2,表示可以将军(和mid == 0区分开来)
			for (lie3 = lie + 1; lie3 < lie1; lie3++)
				if (strcmp(board[hang1][lie3], "0") != 0 && strcmp(board[hang1][lie3], "1") != 0)
					mid = 2;//如果车和将中间有棋子则吃不了,mid设为2
		}
		else if (hang1 == hang && lie1 < lie)
		{
			mid = 1;
			for (lie3 = lie1 + 1; lie3 < lie; lie3++)
				if (strcmp(board[hang1][lie3], "0") != 0 && strcmp(board[hang1][lie3], "1") != 0)
					mid = 2;
		}
		else if (lie1 == lie && hang1 < hang)
		{
			mid = 1;
			for (hang3 = hang1 + 1; hang3 < hang; hang3++)
				if (strcmp(board[hang3][lie1], "0") != 0 && strcmp(board[hang3][lie1], "1") != 0)
					mid = 2;
		}
		else if (lie1 == lie && hang1 > hang)
		{
			mid = 1;
			for (hang3 = hang + 1; hang3 < hang1; hang3++)
				if (strcmp(board[hang3][lie1], "0") != 0 && strcmp(board[hang3][lie1], "1") != 0)
					mid = 2;
		}
		if (mid == 1)//mid为1表示处于同一行或同一列,且中间没有棋子阻挡
			return 0;
	}
	mid = 0;//将mid设为0,避免下次一寻找车的时候mid初始化不正确,出现未在同一行或同一列但mid == 1的情况
	lie1++;//从第一个车的下一格开始寻找车
	n = find(&hang1, &lie1, board, "c");
	if (n)
	{
		if (hang1 == hang && lie1 > lie)
		{
			for (lie3 = lie + 1; lie3 < lie1; lie3++)
				if (strcmp(board[hang1][lie3], "0") != 0 && strcmp(board[hang1][lie3], "1") != 0)
					mid = 2;
		}
		else if (hang1 == hang && lie1 < lie)
		{
			mid = 1;
			for (lie3 = lie1 + 1; lie3 < lie; lie3++)
				if (strcmp(board[hang1][lie3], "0") != 0 && strcmp(board[hang1][lie3], "1") != 0)
					mid = 2;
		}
		else if (lie1 == lie && hang1 < hang)
		{
			mid = 1;
			for (hang3 = hang1 + 1; hang3 < hang; hang3++)
				if (strcmp(board[hang3][lie1], "0") != 0 && strcmp(board[hang3][lie1], "1") != 0)
					mid = 2;
		}
		else if (lie1 == lie && hang1 > hang)
		{
			mid = 1;
			for (hang3 = hang + 1; hang3 < hang1; hang3++)
				if (strcmp(board[hang3][lie1], "0") != 0 && strcmp(board[hang3][lie1], "1") != 0)
					mid = 2;
		}
		if (mid == 1)
			return 0;
	}
	mid = 0;//初始化为0,下次计算炮与将中间棋子数
	hang1 = 0; lie1 = 0;
	//回到(0,0),从头开始寻找下一种棋子

	n = find(&hang1, &lie1, board, "p");
	if (n)
	{
		if (hang1 == hang && lie1 > lie)//只有在hang1与hang相同,或者lie1与lie相同的时候跑才可能吃
		{
			for (lie3 = lie + 1; lie3 < lie1; lie3++)
				if (strcmp(board[hang1][lie3], "0") != 0 && strcmp(board[hang1][lie3], "1") != 0)
					mid++;//统计炮和将中间棋子的数量
		}
		else if (hang1 == hang && lie1 < lie)
		{
			for (lie3 = lie1 + 1; lie3 < lie; lie3++)
				if (strcmp(board[hang1][lie3], "0") != 0 && strcmp(board[hang1][lie3], "1") != 0)
					mid++;
		}
		else if (lie1 == lie && hang1 < hang)
		{
			for (hang3 = hang1 + 1; hang3 < hang; hang3++)
				if (strcmp(board[hang3][lie1], "0") != 0 && strcmp(board[hang3][lie1], "1") != 0)
					mid++;
		}
		else if (lie1 == lie && hang1 > hang)
		{
			for (hang3 = hang + 1; hang3 < hang1; hang3++)
				if (strcmp(board[hang3][lie1], "0") != 0 && strcmp(board[hang3][lie1], "1") != 0)
					mid++;
		}
		if (mid == 1)//炮和将中间棋子的数量为1的时候才能将军
			return 0;
	}
	mid = 0;//初始化为0,使下次计算时从0开始计算棋子数
	lie1++;
	n = find(&hang1, &lie1, board, "p");
	if (n)
	{
		if (hang1 == hang && lie1 > lie)
		{
			for (lie3 = lie + 1; lie3 < lie1; lie3++)
				if (strcmp(board[hang1][lie3], "0") != 0 && strcmp(board[hang1][lie3], "1") != 0)
					mid++;
		}
		else if (hang1 == hang && lie1 < lie)
		{
			for (lie3 = lie1 + 1; lie3 < lie; lie3++)
				if (strcmp(board[hang1][lie3], "0") != 0 && strcmp(board[hang1][lie3], "1") != 0)
					mid++;
		}
		else if (lie1 == lie && hang1 < hang)
		{
			for (hang3 = hang1 + 1; hang3 < hang; hang3++)
				if (strcmp(board[hang3][lie1], "0") != 0 && strcmp(board[hang3][lie1], "1") != 0)
					mid++;
		}
		else if (lie1 == lie && hang1 > hang)
		{
			for (hang3 = hang + 1; hang3 < hang1; hang3++)
				if (strcmp(board[hang3][lie1], "0") != 0 && strcmp(board[hang3][lie1], "1") != 0)
					mid++;
		}
		if (mid == 1)
			return 0;
	}
	hang1 = 0; lie1 = 0;
	//回到(0,0),从头开始寻找下一种棋子

	n = find(&hang1, &lie1, board, "m");
	if (n)
	{
		if (hang1 + 2 <= 10)//判定是否在边缘出现无法跳出棋盘的情况
			if (board[hang1 + 1][lie1] == "0" || board[hang1 + 1][lie1] == "1")//判定是否“被别马脚”了
			{
				if (lie1 + 1 <= 9)
					if (board[hang1 + 2][lie1 + 1] == "Q")
						return 0;
				if (lie1 - 1 >= 0)
					if (board[hang1 + 2][lie1 - 1] == "Q")
						return 0;
			}
		if (hang1 - 2 >= 0)
			if (board[hang1 - 1][lie1] == "0" || board[hang1 - 1][lie1] == "1")
			{
				if (lie1 + 1 <= 9)
					if (board[hang1 - 2][lie1 + 1] == "Q")
						return 0;
				if (lie1 - 1 >= 0)
					if (board[hang1 - 2][lie1 - 1] == "Q")
						return 0;
			}
		if (lie1 + 2 <= 10)
			if (board[hang1][lie1 + 1] == "0" || board[hang1][lie1 + 1] == "1")
			{
				if (hang1 + 1 <= 10)
					if (board[hang1 + 1][lie1 + 2] == "Q")
						return 0;
				if (hang1 - 1 >= 0)
					if (board[hang1 - 1][lie1 + 2] == "Q")
						return 0;
			}
		if (lie1 - 2 >= 0)
			if (board[hang1][lie1 - 1] == "0" || board[hang1][lie1 - 1] == "1")
			{
				if (hang1 + 1 <= 10)
					if (board[hang1 + 1][lie1 - 2] == "Q")
						return 0;
				if (hang1 - 1 >= 0)
					if (board[hang1 - 1][lie1 - 2] == "Q")
						return 0;
			}
	}
	lie1++;
	n = find(&hang1, &lie1, board, "m");
	if (n)
	{
		if (hang1 + 2 <= 10)
			if (board[hang1 + 1][lie1] == "0" || board[hang1 + 1][lie1] == "1")
			{
				if (lie1 + 1 <= 9)
					if (board[hang1 + 2][lie1 + 1] == "Q")
						return 0;
				if (lie1 - 1 >= 0)
					if (board[hang1 + 2][lie1 - 1] == "Q")
						return 0;
			}
		if (hang1 - 2 >= 0)
			if (board[hang1 - 1][lie1] == "0" || board[hang1 - 1][lie1] == "1")
			{
				if (lie1 + 1 <= 9)
					if (board[hang1 - 2][lie1 + 1] == "Q")
						return 0;
				if (lie1 - 1 >= 0)
					if (board[hang1 - 2][lie1 - 1] == "Q")
						return 0;
			}
		if (lie1 + 2 <= 10)
			if (board[hang1][lie1 + 1] == "0" || board[hang1][lie1 + 1] == "1")
			{
				if (hang1 + 1 <= 10)
					if (board[hang1 + 1][lie1 + 2] == "Q")
						return 0;
				if (hang1 - 1 >= 0)
					if (board[hang1 - 1][lie1 + 2] == "Q")
						return 0;
			}
		if (lie1 - 2 >= 0)
			if (board[hang1][lie1 - 1] == "0" || board[hang1][lie1 - 1] == "1")
			{
				if (hang1 + 1 <= 10)
					if (board[hang1 + 1][lie1 - 2] == "Q")
						return 0;
				if (hang1 - 1 >= 0)
					if (board[hang1 - 1][lie1 - 2] == "Q")
						return 0;
			}
	}
	hang1 = 0; lie1 = 0;
	//回到(0,0)
	return 1;//如果中途没有return 0说明最终没有棋子可以将军,即返回1表示未被将死
}

int find(int* hang, int* lie, char board[10][9][3], const char key[])
{
	for (; *hang < 10; (*hang)++)//不需要初始化,为了第二次开始寻找某个棋子的时候从该格下一个开始寻找
	{
		for (; *lie < 9; (*lie)++)
		{
			if ((*hang) < 10 && (*lie) < 9)
				if (strcmp(board[*hang][*lie], key) == 0)//寻找到了则返回1
					return 1;
		}
		if (*lie == 9)
			*lie = 0;
	}
	(*hang) = 0, (*lie) = 0;//未寻找到则返回0,并重置到(0,0)
	return 0;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值