考虑一个象棋残局,其中红方有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)//寻找到了则返回1return 1;}if (*lie == 9)*lie = 0;}(*hang) = 0, (*lie) = 0;//未寻找到则返回0,并重置到(0,0)return 0;
}

UVa1589 象棋相关推荐

  1. UVA1589 象棋 + UVA 220 黑白棋

    UVA1589 象棋 象棋是中国最受欢迎的两人桌游之一.该游戏代表了两支军队之间的战斗,目的是捕获敌人的"将军". 现在我们介绍一些象棋的基本规则. 象棋在10×9的棋盘上演奏,并 ...

  2. 第三十四题 UVA1589 象棋 Xiangqi 说来惭愧

    PDF 题意翻译 [输入] 输入数据≤40组,对于每组数据,第一行有三个数:第一个数代表红方棋数 N(2≤N≤7),第二三个数代表黑将的坐标 接下来N行每行一个字符两个数,代表每个红子的详细信息,字符 ...

  3. 《算法竞赛入门经典》 习题4-1(象棋 Xiangqi ACM ICPC Fuzhou 2011,UVa1589)——仅提供大体方法

    原题及翻译 Xiangqi is one of the most popular two-player board games in China. 象棋是中国最流行的两人棋类游戏之一. The gam ...

  4. 习题4-1 象棋(Xiangqi,ACM/ICPC Fuzhou 2011,UVa1589)

    原题链接:https://vjudge.net/problem/UVA-1589 分类:函数 备注:复杂模拟 注意 各个棋子和将的相对位置是怎么样的. 不管是什么棋子都要考虑是否有其它棋子拦路. 将能 ...

  5. 象棋 Uva1589

    在网上看到的超棒的代码:http://www.cnblogs.com/cumulonimbus/p/5184725.html 自己看完之后又重新码了一遍 QAQ 变量命名有些窒息 思路:模拟黑棋可以移 ...

  6. 象棋 (Xiangqi, ACM/ICPC Fuzhou 2011, UVa1589)

    Description Xiangqi is one of the most popular two-player board games in China. The game represents ...

  7. 【UVa1589】象棋

    分享一下我的思路吧 先判断初始局面是不是老将脸对脸,如果是的话,黑方获胜,输出NO 如果不是,黑方老将最多只有走下一步的方式,判断一下走完之后是否仍被将军,是就输出YES,否就输出N 判断黑方老将是否 ...

  8. POJ4001 HDU4121 UVA1589 UVALive5829 Xiangqi【模拟+回溯】

    Xiangqi Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1791   Accepted: 444 Descriptio ...

  9. Xiangqi UVA - 1589(蛮好玩的中国象棋~·)

    题目: 给出一个中国象棋残局,黑方只有将,红方有仅包含马車炮帅在内的n(2≤n≤7)个棋子,且黑方已被将军,输出是否已被将死(无路可走) R(车) C(炮) H(马) G(帅)(将) https:// ...

最新文章

  1. 单目和多目视觉统一标定
  2. 节省磁盘空间的新一代包管理工具PNPM
  3. 转: 常见加密算法分,用途,原理以及比较
  4. JavaScript学习笔记(4)
  5. 其实,人的核心职场时间是有限的,一定要和高手玩
  6. Eclipse jetty和plugin 的结合使用
  7. e2140服务器性能,4000 还是E2140?两大人气CPU对决
  8. java的this()与super()用法
  9. SpringBoot以jar包部署需要注意的thymeleaf页面映射问题
  10. ufw命令的基本使用
  11. 行人重识别论文阅读11-BDTR 红外光行人重识别
  12. 学硕计算机可考大数据博士吗,专硕考博比学硕考博难度更大吗?听听上岸的人怎么说...
  13. 常用的DOS命令大全
  14. 微信订阅号小技巧及相关知识普及
  15. 计算机内存清理器,轻量便捷的内存清理工具PC版
  16. 计算机大学四年该如何努力学习?
  17. Modifiers should be declared in the correct order 修饰符应按正确的顺序声明
  18. 学生查分系统该怎么制作?
  19. 腾讯的核心竞争力是什么!
  20. 分类器评估指标——混淆矩阵 ROC AUC KS AR PSI Lift Gain

热门文章

  1. 《岗位说明书》--老白的作业
  2. js定时器的练习(一)淘宝广告效果
  3. 深度无盘服务器网卡,无盘网吧网卡参数设置建议
  4. 企业应用架构之业务逻辑层的顶层设计与底层思考
  5. 12月不良与垃圾信息举报:网络垃圾环比减少7%
  6. java swing substance_java swing皮肤使用(substance)
  7. 郭天祥,我的大学六年
  8. 西门子SMART 存储区
  9. 5.8输出所有的“水仙花数”,所谓“水仙花数”是指一个3位数,其各位数字立方和等于该数本身。例如153是一位水仙花数,因为153=13+53+33。
  10. obs 推流编码在哪设置_obs rtmp推流地址设置