中国象棋小游戏

ez_lcw

2018-08-30 21:11:19

Personal

# 中国象棋小游戏 这个新游戏是本人第一次创作,如果有任何BUG(反正我相信会有很多,请发现的人在评论指出),但希望大家还是玩一玩,(毕竟我是花了九九八十一天才完成的~~我才不会告诉你我是一个下午搞完的~~) 代码如下: ```cpp #include<cstdio> #include<windows.h> #include<iostream> #define N 10 #define M 9 using namespace std; int have[N+1][M+1],stx,sty,edx,edy; //0 无 //1 红車,2红马,3红象,4红士,5红将,6红炮,7红兵 //8 黑車,9黑马,10黑象,11黑士,12黑将,13黑炮,14黑兵 int horsex[8]= {-2,-2,2,2,-1,1,-1,1},horsey[8]= {-1,1,-1,1,-2,-2,2,2}; int xiangx[4]= {-2,-2,2,2},xiangy[4]= {-2,2,-2,2}; int shix[4]= {-1,-1,1,1},shiy[4]= {-1,1,-1,1}; int jiangx[4]= {-1,0,1,0},jiangy[4]= {0,1,0,-1}; bool red,blue,Hint; // 0 = 黑色 8 = 灰色 // 1 = 蓝色 9 = 淡蓝色 // 2 = 绿色 A = 淡绿色 // 3 = 浅绿色 B = 淡浅绿色 // 4 = 红色 C = 淡红色 // 5 = 紫色 D = 淡紫色 // 6 = 黄色 E = 淡黄色 // 7 = 白色 F = 亮白色 enum ConsoleForegroundColor { enmCFC_Red = FOREGROUND_INTENSITY | FOREGROUND_RED, enmCFC_Green = FOREGROUND_INTENSITY | FOREGROUND_GREEN, enmCFC_Blue = FOREGROUND_INTENSITY | FOREGROUND_BLUE, enmCFC_Yellow = FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN, enmCFC_Purple = FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE, enmCFC_Cyan = FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE, enmCFC_Gray = FOREGROUND_INTENSITY, enmCFC_White = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, enmCFC_HighWhite = FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, enmCFC_Black = 0, }; enum ConsoleBackGroundColor { enmCBC_Red = BACKGROUND_INTENSITY | BACKGROUND_RED, enmCBC_Green = BACKGROUND_INTENSITY | BACKGROUND_GREEN, enmCBC_Blue = BACKGROUND_INTENSITY | BACKGROUND_BLUE, enmCBC_Yellow = BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN, enmCBC_Purple = BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_BLUE, enmCBC_Cyan = BACKGROUND_INTENSITY | BACKGROUND_GREEN | BACKGROUND_BLUE, enmCBC_White = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE, enmCBC_HighWhite = BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE, enmCBC_Black = 0, }; void SetConsoleColor(ConsoleForegroundColor foreColor = enmCFC_White, ConsoleBackGroundColor backColor = enmCBC_Black) { HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(handle, foreColor | backColor); } //int allForeColors[] = { enmCFC_Red, enmCFC_Green, enmCFC_Blue, enmCFC_Yellow, enmCFC_Purple, enmCFC_Cyan, enmCFC_Gray, enmCFC_White, enmCFC_HighWhite, enmCFC_Black }; //int allBackColors[] = { enmCBC_Red, enmCBC_Green, enmCBC_Blue, enmCBC_Yellow, enmCBC_Purple, enmCBC_Cyan, 0, enmCBC_White, enmCBC_HighWhite, enmCBC_Black }; //SetConsoleColor((ConsoleForegroundColor)allForeColors[i], (ConsoleBackGroundColor)allBackColors[j]); //Fore: 0 Red,1 Green,2 Blue,3 Yellow,4 Purple,5 Cyan(青),6 Gray,7 White,8 HighWhite,9 Black //Back: 0 Red,1 Green,2 Blue,3 Yellow,4 Purple,5 Cyan(青),6 0 ,7 White,8 HighWhite,9 Black int allForeColors[] = { enmCFC_Red, enmCFC_Green, enmCFC_Blue, enmCFC_Yellow, enmCFC_Purple, enmCFC_Cyan, enmCFC_Gray, enmCFC_White, enmCFC_HighWhite, enmCFC_Black }; int allBackColors[] = { enmCBC_Red, enmCBC_Green, enmCBC_Blue, enmCBC_Yellow, enmCBC_Purple, enmCBC_Cyan, 0, enmCBC_White, enmCBC_HighWhite, enmCBC_Black }; struct MAP { string map[N+1][M+1]; } map1; int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-')f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^'0'); ch=getchar(); } return x*f; } void writemap(MAP map1) { system("cls"); for(int i=0; i<=N; i++) { for(int q=0; q<=M; q++) { if(have[i][q]<=7&&have[i][q]!=0&&map1.map[i][q]!="#") { SetConsoleColor((ConsoleForegroundColor)allForeColors[0], (ConsoleBackGroundColor)allBackColors[9]); } else { if(have[i][q]!=0&&map1.map[i][q]!="#") { SetConsoleColor((ConsoleForegroundColor)allForeColors[2], (ConsoleBackGroundColor)allBackColors[9]); } } printf("%s",map1.map[i][q].c_str()); SetConsoleColor((ConsoleForegroundColor)allForeColors[7], (ConsoleBackGroundColor)allBackColors[9]); if((have[i][q]==0&&map1.map[i][q]!="10")||map1.map[i][q]=="#") { putchar(' '); } } puts(""); } puts(""); } void buildmap() { red=false; blue=false; memset(have,0,sizeof(have)); map1.map[0][0]=" "; map1.map[1][0]="1"; map1.map[2][0]="2"; map1.map[3][0]="3"; map1.map[4][0]="4"; map1.map[5][0]="5"; map1.map[6][0]="6"; map1.map[7][0]="7"; map1.map[8][0]="8"; map1.map[9][0]="9"; map1.map[10][0]="10"; map1.map[0][1]="1"; map1.map[0][2]="2"; map1.map[0][3]="3"; map1.map[0][4]="4"; map1.map[0][5]="5"; map1.map[0][6]="6"; map1.map[0][7]="7"; map1.map[0][8]="8"; map1.map[0][9]="9"; for(int i=1; i<=N; i++) { for(int q=1; q<=M; q++) { map1.map[i][q]="."; } } map1.map[1][1]="車"; have[1][1]=1; map1.map[1][2]="馬"; have[1][2]=2; map1.map[1][3]="相"; have[1][3]=3; map1.map[1][4]="仕"; have[1][4]=4; map1.map[1][5]="帅"; have[1][5]=5; map1.map[1][6]="仕"; have[1][6]=4; map1.map[1][7]="相"; have[1][7]=3; map1.map[1][8]="馬"; have[1][8]=2; map1.map[1][9]="車"; have[1][9]=1; map1.map[3][2]="炮"; have[3][2]=6; map1.map[3][8]="炮"; have[3][8]=6; map1.map[4][1]="卒"; have[4][1]=7; map1.map[4][3]="卒"; have[4][3]=7; map1.map[4][5]="卒"; have[4][5]=7; map1.map[4][7]="卒"; have[4][7]=7; map1.map[4][9]="卒"; have[4][9]=7; map1.map[7][1]="兵"; have[7][1]=14; map1.map[7][3]="兵"; have[7][3]=14; map1.map[7][5]="兵"; have[7][5]=14; map1.map[7][7]="兵"; have[7][7]=14; map1.map[7][9]="兵"; have[7][9]=14; map1.map[8][2]="砲"; have[8][2]=13; map1.map[8][8]="砲"; have[8][8]=13; map1.map[N][1]="车"; have[N][1]=8; map1.map[N][2]="马"; have[N][2]=9; map1.map[N][3]="象"; have[N][3]=10; map1.map[N][4]="士"; have[N][4]=11; map1.map[N][5]="将"; have[N][5]=12; map1.map[N][6]="士"; have[N][6]=11; map1.map[N][7]="象"; have[N][7]=10; map1.map[N][8]="马"; have[N][8]=9; map1.map[N][9]="车"; have[N][9]=8; } bool right(int num,int stx,int sty,int edx,int edy,bool output) { if(num%7==1) { if(stx!=edx&&sty!=edy) { if(output) puts("您的車只可以横竖走,并且只能走直线,您输入错了,请重新输入:"); return false; } if(sty==edy) { bool b=false; for(int i=stx+(edx>stx?1:-1); (edx>stx?i<edx:i>edx); i+=(edx>stx?1:-1)) { if(have[i][sty]) { if(output) puts("O(≧口≦)O,怎么老是被挡住!只能重新选择一个要去的点啦:"); b=true; return false; } } if(b) { return false; } } else { bool b=false; for(int i=sty+(edy>sty?1:-1); (edy>sty?i<edy:i>edy); i+=(edy>sty?1:-1)) { if(have[stx][i]) { if(output) puts("O(≧口≦)O,怎么老是被挡住!只能重新选择一个要去的点啦:"); b=true; break; } } if(b) { return false; } } } if(num%7==2) { bool b=false; int fangxiang;//0 上,1 下,2 左,3 右 for(int i=0; i<8; i++) { if(stx+horsex[i]==edx&&sty+horsey[i]==edy) { fangxiang=i/2; b=true; break; } } if(b) { if(fangxiang==0) { if(have[stx-1][sty]) { if(output) puts("O(≧口≦)O,这都能被蹩马腿(绊马脚),只能重新选择一个要去的点啦:"); return false; } } if(fangxiang==1) { if(have[stx+1][sty]) { if(output) puts("O(≧口≦)O,这都能被蹩马腿(绊马脚),只能重新选择一个要去的点啦:"); return false; } } if(fangxiang==2) { if(have[stx][sty-1]) { if(output) puts("O(≧口≦)O,这都能被蹩马腿(绊马脚),只能重新选择一个要去的点啦:"); return false; } } if(fangxiang==3) { if(have[stx][sty+1]) { if(output) puts("O(≧口≦)O,这都能被蹩马腿(绊马脚),只能重新选择一个要去的点啦:"); return false; } } } else { if(output) puts("您的馬只可以走日字,您输入错了,请重新输入:"); return false; } } if(num%7==3) { if(num<=7?edx>5:edx<6) { if(output) puts("相的活动范围限于“河界”以内的本方阵地,不能过河,您输入错了,请重新输入:"); return false; } bool b=false; int fangxiang;//0 左上,1 右上,2 左下,3 右下 for(int i=0; i<4; i++) { if(stx+xiangx[i]==edx&&sty+xiangy[i]==edy) { fangxiang=i; b=true; break; } } if(b) { if(fangxiang==0) { if(have[stx-1][sty-1]) { if(output) puts("O(≧口≦)O,这都能被塞象眼,只能重新选择一个要去的点啦:"); return false; } } if(fangxiang==1) { if(have[stx-1][sty+1]) { if(output) puts("O(≧口≦)O,这都能被塞象眼,只能重新选择一个要去的点啦:"); return false; } } if(fangxiang==2) { if(have[stx+1][sty-1]) { if(output) puts("O(≧口≦)O,这都能被塞象眼,只能重新选择一个要去的点啦:"); return false; } } if(fangxiang==3) { if(have[stx+1][sty+1]) { if(output) puts("O(≧口≦)O,这都能被塞象眼,只能重新选择一个要去的点啦:"); return false; } } } else { if(output) puts("您的相只可以走田字,您输入错了,请重新输入:"); return false; } } if(num%7==4) { if(num<=7?(edx>3||edy<4||edy>6):(edx<8||edy<4||edy>6)) { if(output) puts("仕的活动范围限于九宫格内,您输入错了,请重新输入:"); return false; } bool b=false; for(int i=0; i<4; i++) { if(stx+shix[i]==edx&&sty+shiy[i]==edy) { b=true; break; } } if(!b) { if(output) puts("您的仕只可以走九宫格内的斜边,并且只能走一段斜线,您输入错了,请重新输入:"); return false; } } if(num%7==5) { if((num<=7?(edx>3||edy<4||edy>6):(edx<8||edy<4||edy>6))&&have[edx][edy]!=(num<=7?12:5)) { if(output) puts("将的活动范围限于九宫格内,您输入错了,请重新输入:"); return false; } bool b=false; for(int i=0; i<4; i++) { if(stx+jiangx[i]==edx&&sty+jiangy[i]==edy) { b=true; break; } } if(b) { bool b=false; for(int i=stx+(num<=7?1:-1); (num<=7?i<=10:i>=1); i+=(num<=7?1:-1)) { if(have[i][edy]) { if(have[i][edy]==(num<=7?12:5)) { b=true; } break; } } if(b) { if(output) puts("您被白脸将杀法控制了,O(≧口≦)O"); return false; } } else { bool b=false; for(int i=stx+(num<=7?1:-1); (num<=7?i<=10:i>=1); i+=(num<=7?1:-1)) { if(have[i][edy]) { if(have[i][edy]==(num<=7?12:5)) { b=true; } break; } } if(!b) { if(output) puts("将只能走一步,您输入错了。"); return false; } } } if(num%7==6) { int k=0; if(stx!=edx&&sty!=edy) { if(output) puts("您的炮只可以横竖走,并且只能走直线,您输入错了,请重新输入:"); return false; } if(sty==edy) { for(int i=stx+(edx>stx?1:-1); (edx>stx?i<edx:i>edx); i+=(edx>stx?1:-1)) { if(have[i][sty]) { k++; } } } else { for(int i=sty+(edy>sty?1:-1); (edy>sty?i<edy:i>edy); i+=(edy>sty?1:-1)) { if(have[stx][i]) { k++; } } } if(k>1) { if(output) puts("O(≧口≦)O,怎么老是被挡住!只能重新选择一个要去的点啦:"); return false; } if(!k&&have[edx][edy]) { if(output) puts("炮走法同车一样时,炮必须不吃子,您输入错了,请重新输入:"); return false; } if(k&&!have[edx][edy]) { if(output) puts("炮隔一个棋子(无论是哪一方的)走时,必须是吃子的时候,您输入错了,请重新输入:"); return false; } } if(num%7==0) { if(num<=7?stx<=5:stx>=6) { if(edy!=sty||stx+(num<=7?1:-1)!=edx) { if(output) puts("兵在没有过“河界”前,每着只许向前直走一步,您输入错了,请重新输入:"); return false; } } else { if((edy!=sty||edx!=stx+(num<=7?1:-1))&&(edy!=sty-1||edx!=stx)&&(edy!=sty+1||edx!=stx)) { if(output) puts("兵在过“河界”后,每步可向前直走或横走一步,但不能后退,您输入错了,请重新输入:"); return false; } } } return true; } void hint(int num,int stx,int sty) { MAP map2=map1; bool b=false; for(int i=1; i<=10; i++) { for(int q=1; q<=9; q++) { if(!have[i][q]||(num<=7?have[i][q]>7:have[i][q]<=7)) { if(right(num,stx,sty,i,q,false)) { map2.map[i][q]="#"; b=true; } } } } writemap(map2); if(!b) { puts("很不幸,无路可走哦!"); } } bool fight(int num) { bool b=false; while(1) { if(!b) { writemap(map1); } else { hint(num,stx,sty); } init: puts("您想让这个棋子移动到哪里?(输入坐标(格式:行 列)(输入“-1 -1”为返回重新选择棋子进行操作,输入“-2 -2”打开或关闭提示)"); edx=read();edy=read(); if(edx==-1&&edx==-1) { return false; } if(edx==-2&&edy==-2) { b=!b; continue; } if(edx>0&&edy>0&&edx<=10&&edy<=9&&(!have[edx][edy]||(num<=7?have[edx][edy]>7:have[edx][edy]<=7))) { if(!right(num,stx,sty,edx,edy,true)) { goto init; } puts("移动中……"); Sleep(500); if(!have[edx][edy]) { swap(map1.map[stx][sty],map1.map[edx][edy]); swap(have[stx][sty],have[edx][edy]); } else { if(have[edx][edy]==12) { blue=true; } if(have[edx][edy]==5) { red=true; } map1.map[edx][edy]=map1.map[stx][sty]; map1.map[stx][sty]="."; have[edx][edy]=have[stx][sty]; have[stx][sty]=0; puts("顺便吃掉了一个敌人,好嗨皮!"); Sleep(1000); } writemap(map1); break; } else { puts("您输入的坐标错误或坐标对应的位置有你方的棋,请重新输入:"); goto init; } } return true; } void play() { while(!red&&!blue) { SetConsoleColor((ConsoleForegroundColor)allForeColors[0], (ConsoleBackGroundColor)allBackColors[9]); printf("红"); SetConsoleColor((ConsoleForegroundColor)allForeColors[7], (ConsoleBackGroundColor)allBackColors[9]); puts("方回合到了,"); while(1) { puts("您需要将哪个棋子进行操作?(输入坐标(格式:行 列)"); stx=read();sty=read(); if(stx>0&&sty>0&&stx<=10&&sty<=9&&have[stx][sty]<=7&&have[stx][sty]>=1) { if(fight(have[stx][sty])) { break; } else { puts("请重新输入:"); continue; } } else { puts("您输入的坐标错误或者坐标对应的位置没有你方的棋,请重新输入:"); } } if(blue) { puts("恭喜红方获胜!!!"); Sleep(5000); return; } SetConsoleColor((ConsoleForegroundColor)allForeColors[2], (ConsoleBackGroundColor)allBackColors[9]); printf("蓝"); SetConsoleColor((ConsoleForegroundColor)allForeColors[7], (ConsoleBackGroundColor)allBackColors[9]); puts("方回合到了,"); while(1) { puts("您需要将哪个棋子进行操作?(输入坐标(格式:行 列)"); stx=read();sty=read(); if(stx>0&&sty>0&&stx<=10&&sty<=9&&have[stx][sty]>7&&have[stx][sty]>=1) { if(fight(have[stx][sty])) { break; } else { puts("请重新输入:"); continue; } } else { puts("您输入的坐标错误或者坐标对应的位置没有你方的棋,请重新输入:"); } } if(red) { puts("恭喜蓝方获胜!!!"); Sleep(5000); return; } } } void see() { puts("中国象棋一共有七种兵种,分别是车、马、炮、兵、士、相、帅。车、马、炮主要是负责进攻的棋子,而士、象是专职防守。"); puts(""); puts("车:可以纵着走也可以横着走,所有一个车能控制的点有17个,纵的有9个,横的有8个。所有车是象棋里面最厉害的棋子。它的吃子方式和走子方式是相同的,比如说在纵线上有敌对棋子,这个时候可以吃掉。"); puts(""); puts("马:马走“日”字,马在中间时能控制的格子有8个,成语说“马”八面威风说的就是这个意思。马在边上的时候能控制的格子就少了很多,所有我们尽量让马放在中间。马的走棋还有个规则就是“绊马脚”。"); puts(""); puts("炮:炮的走法与车相同,但是炮的吃子方式有点特别,它必须格着一个棋子才能吃子,也就是说它要有一个炮架。"); puts(""); puts("兵:兵有5个,位置在河界旁。兵在没过河之前只能往前走,过了河之后它就可以往左和右走。但是兵是不能往后退的,当兵走到底线的时候只能往左右走。兵的价值最好的位置是刚过河不久。如果冲到底线它的价值就降低了。"); puts(""); puts("士:士只能在“九宫”的5个点走,走法按斜上方走或斜下方走。"); puts(""); puts("相:相走“田”,相不能过河。相的走法有个'相眼'的走发(塞相眼)。"); puts(""); puts("王:中国象棋的王红方叫“帅”,黑方叫“将”。王只能在“九宫”中走动,不能出去。王的走法是可以走相邻的格子。双方王不能不隔任何棋子照面。"); puts(""); printf("按下回车即可退出。"); getchar(); } void slowsay(string s) { for(int i=0; s[i]; i++) { cout<<s[i]; Sleep(15); } } void diary() { puts("第一版:萌新游戏。"); puts("第二版:增加了“白脸将”杀法。"); puts("第三版:增加了规则。"); puts("第四版:增加了提示。"); puts("第五版:增加了颜色、更新日志,简化了操作。 ——2018年9月15日"); puts("BUG在每一次更新都会有修改,而且会根据BUG和需要持续更新,多谢大家支持!"); puts("注:目前“白脸将”杀法还是有BUG,正在修复。"); puts(""); printf("按下回车即可退出。"); getchar(); } int main() { memset(have,0,sizeof(have)); SetConsoleColor((ConsoleForegroundColor)allForeColors[7], (ConsoleBackGroundColor)allBackColors[9]); slowsay("欢迎来到中国象棋小游戏\n"); Sleep(1700); while(1) { slowsay("输入1可查看规则,输入2可开始游戏,输入3可查看往期更新内容,输入4退出\n"); int num1; while(1) { num1=read(); if(num1==1) { see(); break; } else { if(num1==2) { while(1) { bool b=false; printf("象棋高手们,你们准备好了吗?按下回车开始游戏哦!(注意:选手各自要先分出红方蓝方(上半部分为红方(玩家1),下半部分为蓝方(玩家2)))"); getchar(); puts("进入游戏中……稍等片刻"); Sleep(1000); buildmap(); writemap(map1); play(); system("cls"); puts("再来一局吗,高手们?(输入1为退出,输入2为再来一局,输入3为返回主界面)"); int num2; while(1) { num2=read(); if(num2==1) { return 0; } else { if(num2==3) { b=true; break; } else { if(num2!=2) { puts("输入错误,请重新输入:"); } } } break; } if(b) { break; } } } else { if(num1==3) { diary(); } else { if(num1==4) { return 0; } else { puts("输入错误,请重新输入:"); continue; } } } } break; } system("cls"); } return 0; } } ``` 第一版:萌新游戏。 第二版:增加了[“白脸将”](https://baike.baidu.com/item/%E7%99%BD%E8%84%B8%E5%B0%86/4445566?fr=aladdin)杀法。 第三版:增加了规则。 第四版:增加了提示。 第五版:棋子有了[颜色(转)](https://www.cnblogs.com/tangxin-blog/p/7257413.html),更容易区分,简化了操作 ——2018年9月9日 BUG在每一次更新都会有修改,而且会根据BUG和需要持续更新,多谢大家支持!