博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
游戏 黑白棋
阅读量:5249 次
发布时间:2019-06-14

本文共 5203 字,大约阅读时间需要 17 分钟。

jing shi给的灵感,一共是两天赶了5个小时做出来了,写完真的感觉代码力会提高不少

自己做的第一款游戏,但可能也是退役前最后一款了,目前还没测试出bug

鸣谢:

@附外赵日天 @浮生 (测试)

@niiick (修改查错)

更新日志

v2.5

  • 由于刷新率太慢,输入模式还原为坐标输入

  • 加入了存读档功能

  • 加入了退出游戏提前结算棋子数功能

  • 加入游戏结束动画

  • 修复了判断坐标合法RE的bug

  • 修复了边缘坐标始终合法的bug

v2.0

  • 更换输入坐标模式,利用wasd控制坐标输入

  • 加入开头动画

v1.0

  • 修复了吃棋过多的bug

  • 加入游戏小标题

v0.1

  • 初号机,制定了游戏大体框架

  • 递归的思想得到验证,确认算法核心

  • 若干bug等待调试

规则

如果玩家在棋盘上没有地方可以下子,则该玩家对手可以连下。双方都没有棋子可以下时棋局结束,以棋子数目来计算胜负,棋子多的一方获胜。

在棋盘还没有下满时,如果一方的棋子已经被对方吃光,则棋局也结束。将对手棋子吃光的一方获胜。
翻转棋类似于棋盘游戏“奥赛罗 (Othello)”,是一种得分会戏剧性变化并且需要长时间思考的策略性游戏。
翻转棋的棋盘上有 64 个可以放置黑白棋子的方格(类似于国际象棋和跳棋)。游戏的目标是使棋盘上自己颜色的棋子数超过对手的棋子数。
该游戏非常复杂,其名称就暗示着结果的好坏可能会迅速变化。
当游戏双方都不能再按规则落子时,游戏就结束了。通常,游戏结束时棋盘上会摆满了棋子。结束时谁的棋子最多谁就是赢家。

玩法

每个“翻转棋”游戏开始时,棋盘上已经交叉放好了四颗棋子。其中两颗是黑棋,另两颗是白棋。黑棋总是先走。

当您的棋子在某一直线方向包围了对手的棋子时,就可以翻转这些棋子的颜色,使它们成为您方的颜色。例如,如果您执黑棋,并且看到在一排白棋的某一端是一颗黑棋,那么当您将一颗黑棋放在这一排的另一端时,所有的白棋都将翻转并变为黑棋!
所有的直线方向均有效:水平、垂直和斜线方向。
走棋的唯一规则是只能走包围并翻转对手的棋子。每一回合都必须至少翻转一颗对手的棋子。
按规则不能再走棋时,这一回合弃权。这一步的行棋权将被交给对方。

核心原理

从8个方向增量数组出发,利用递归寻找同色棋,若找到则回溯,同时翻转路径上的所有棋子(位置合法判断方法大致相同)

Code

#include 
#include
#include
#include
#include
#include
#include
using namespace std;const int maxn = 19;int now;int map[maxn][maxn];int out[maxn][maxn];int can[maxn][maxn];int mx[8] = {-1,0,1,-1,1,-1,0,1};int my[8] = {-1,-1,-1,0,0,1,1,1};void PTONY(){//Tony!!! SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN);}void Pwhite(){//-1SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);} void Pred(){//1SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);}void Pblue(){//0SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_BLUE);}void read(){fstream File("save.txt",ios::in | ios::out);int temp;for(int i = 0;i <= 9;i++){ for(int j = 0;j <= 9;j++){ File>>temp; map[i][j] = temp; } }for(int i = 0;i <= 9;i++){ for(int j = 0;j <= 9;j++){ File>>temp; out[i][j] = temp; } }for(int i = 0;i <= 9;i++){ for(int j = 0;j <= 9;j++){ File>>temp; can[i][j] = temp; } }File>>temp;now = temp;}bool goon,end;void start(){PTONY();printf("Tony's mini Game\n");Sleep(1000);Pred(); printf("HOW TO PLAY\n");Pwhite();printf("输入坐标控制落子\n先纵轴 后横轴 以空格隔开\nEnter = 确定\n");printf("坐标 0, 0结束游戏\n坐标19,19存档\n请在游玩时关闭输入法\n");Sleep(1000);PTONY();printf("Tony Double Sky ");Sleep(1000);printf("Present\n");Sleep(1000);Pblue();printf("thx:@Charles @niiick\n");Pwhite();printf("Press any key to continue");char c = getch();system("cls");printf("请选择:\n1.读取存档\n2.新游戏\n");char a = getch();while(!(a == '1' || a == '2'))a = getch();if(a == '1'){ read(); goon = 1; PTONY(); printf("读档成功\n"); Sleep(2000); }}void print(){system("cls");PTONY();printf(" Tony's mini Game\n");Pwhite();printf(" ");for(int i = 1;i <= 8;i++)printf("%d ",i);printf("\n");for(int i = 1;i <= 8;i++){ Pwhite();printf("%d",i); for(int j = 1;j <= 8;j++){ if(out[i][j] == -1){ Pwhite();printf("■"); } else if(out[i][j] == 1){ Pred();printf("■"); } else{ Pblue();printf("■"); } } printf("\n"); }if(now){Pred();printf("红方下\n");}else{Pblue();printf("蓝方下\n");}Pwhite();printf("请输入坐标\n");}void init(){memset(map,-1,sizeof(map));memset(out,-1,sizeof(out));map[4][4] = out[4][4] = 1;map[4][5] = out[4][5] = 0;map[5][4] = out[5][4] = 0;map[5][5] = out[5][5] = 1;now = 1;}bool change(int x,int y,int mx,int my,int c){if(map[x][y] == c)return 1;if(map[x][y] == -1)return 0;bool flag = change(x + mx,y + my,mx,my,c);out[x][y] ^= flag;return flag;}bool judge(int x,int y,int mx,int my,int c,bool flag){if(map[x][y] == c)return (1 && flag);if(map[x][y] == -1)return 0;if(map[x][y] == c ^ 1)flag = 1;return judge(x + mx,y + my,mx,my,c,flag);}bool check(int c){memset(can,0,sizeof(can));bool flag = 0;for(int i = 1;i <= 8;i++){ for(int j = 1;j <= 8;j++){ if(map[i][j] == -1){ for(int k = 0;k < 8;k++){ int gox = mx[k]; int goy = my[k]; can[i][j] |= judge(i + gox,j + goy,gox,goy,c,0); if(can[i][j]){ flag = 1; break; } } } } }return flag;}void save(){ofstream SaveFile("save.txt");for(int i = 0;i <= 9;i++){ for(int j = 0;j <= 9;j++){ SaveFile<
<<" "; } SaveFile<
<= 9;i++){ for(int j = 0;j <= 9;j++){ SaveFile<
<<" "; } SaveFile<
<= 9;i++){ for(int j = 0;j <= 9;j++){ SaveFile<
<<" "; } SaveFile<
<= maxn;i++){ for(int j = 0;j <= maxn;j++){ out[i][j] = map[i][j]; } } for(int k = 0;k < 8;k++){ int gox = mx[k]; int goy = my[k]; change(x + gox,y + goy,gox,goy,now); } } else{ if(now == 1)Pred(),printf("无棋可下\n"); else Pblue(),printf("无棋可下\n"); Sleep(2000); if(again)break; else again = 1; } now ^= 1; print(); for(int i = 0;i <= maxn;i++){ for(int j = 0;j <= maxn;j++){ map[i][j] = out[i][j]; } } } int R = 0,B = 0; for(int i = 1;i <= 8;i++){ for(int j = 1;j <= 8;j++){ if(map[i][j] == 1)R++; else if(map[i][j] == 0)B++; } } Pred();printf("红方得分:%d\n",R); Pblue();printf("蓝方得分:%d\n",B); Sleep(1000); if(R == B){ Pwhite();printf("--平局--\n"); } else if(R > B){ Pred();printf("--红方胜--\n"); } else{ Pblue();printf("--蓝方胜--\n"); } Sleep(2000); PTONY();printf("Thanks to play my game\n"); Sleep(2000); printf("Press any key to end\n"); char c = getch(); return 0; }

转载于:https://www.cnblogs.com/Tony-Double-Sky/p/9285526.html

你可能感兴趣的文章
C# Dynamic通用反序列化Json类型并遍历属性比较
查看>>
前台freemark获取后台的值
查看>>
Leetcode: Unique Binary Search Trees II
查看>>
C++ FFLIB 之FFDB: 使用 Mysql&Sqlite 实现CRUD
查看>>
Spring-hibernate整合
查看>>
c++ map
查看>>
exit和return的区别
查看>>
Django 相关
查看>>
比较安全的获取站点更目录
查看>>
空间分析开源库GEOS
查看>>
RQNOJ八月赛
查看>>
前端各种mate积累
查看>>
Python(软件目录结构规范)
查看>>
Windows多线程入门のCreateThread与_beginthreadex本质区别(转)
查看>>
Nginx配置文件(nginx.conf)配置详解1
查看>>
linux php编译安装
查看>>
name phone email正则表达式
查看>>
重置GNOME-TERMINAL
查看>>
redis哨兵集群、docker入门
查看>>
hihoCoder 1233 : Boxes(盒子)
查看>>