• 游戏 黑白棋


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

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

    鸣谢:

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

    @niiick (修改查错)

    更新日志

    v2.5

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

    • 加入了存读档功能

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

    • 加入游戏结束动画

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

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

    v2.0

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

    • 加入开头动画

    v1.0

    • 修复了吃棋过多的bug

    • 加入游戏小标题

    v0.1

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

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

    • 若干bug等待调试

    规则

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

    玩法

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

    核心原理

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

    Code

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <windows.h>
    #include <ctime>
    #include <conio.h>
    #include <fstream>
    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(){//-1
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
    } 
    void Pred(){//1
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);
    }
    void Pblue(){//0
    SetConsoleTextAttribute(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
    ");
    Sleep(1000);
    Pred(); 
    printf("HOW TO PLAY
    ");
    Pwhite();
    printf("输入坐标控制落子
    先纵轴 后横轴 以空格隔开
    Enter = 确定
    ");
    printf("坐标 0, 0结束游戏
    坐标19,19存档
    请在游玩时关闭输入法
    ");
    Sleep(1000);
    PTONY();
    printf("Tony Double Sky ");
    Sleep(1000);
    printf("Present
    ");
    Sleep(1000);
    Pblue();
    printf("thx:@Charles @niiick
    ");
    Pwhite();
    printf("Press any key to continue");
    char c = getch();
    system("cls");
    printf("请选择:
    1.读取存档
    2.新游戏
    ");
    char a = getch();
    while(!(a == '1' || a == '2'))a = getch();
    if(a == '1'){
    	read();
    	goon = 1;
    	PTONY();
    	printf("读档成功
    ");
    	Sleep(2000);
    	}
    }
    void print(){
    system("cls");
    PTONY();printf(" Tony's mini Game
    ");
    Pwhite();
    printf(" ");
    for(int i = 1;i <= 8;i++)printf("%d ",i);
    printf("
    ");
    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("
    ");
    	}
    if(now){Pred();printf("红方下
    ");}
    else{Pblue();printf("蓝方下
    ");}
    Pwhite();printf("请输入坐标
    ");
    }
    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<<map[i][j]<<" ";
    		}
    	SaveFile<<endl;
    	}
    for(int i = 0;i <= 9;i++){
    	for(int j = 0;j <= 9;j++){
    		SaveFile<<out[i][j]<<" ";
    		}
    	SaveFile<<endl;
    	}
    for(int i = 0;i <= 9;i++){
    	for(int j = 0;j <= 9;j++){
    		SaveFile<<can[i][j]<<" ";
    		}
    	SaveFile<<endl;
    	}
    SaveFile<<now<<endl;
    SaveFile.close();
    }
    int main(){
    	start();
    	if(!goon)init();
    	print();
    	int cnt = 4;
    	int x,y;
    	bool again = 0;
    	while(1){
    		if(check(now)){
    			scanf("%d%d",&x,&y);
    			if(x == 19 && y == 19){
    				save();
    				PTONY();
    				printf("已保存
    ");
    				Sleep(2000);
    				print();
    				continue;
    				}
    			else if(x == 0 && y == 0){
    				break;
    				}
    			while(!can[x][y]){
    				
    				printf("位置不合法请重新输入:
    ");
    				scanf("%d%d",&x,&y);
    				if(x == 19 && y == 19){
    					save();
    					PTONY();
    					printf("已保存
    ");
    					Sleep(2000);
    					print();
    					continue;
    					}
    				else if(x == 0 && y == 0){
    					end = 1;
    					break;
    					}
    				}
    			if(end)break;
    			map[x][y] = now;cnt++;again = 0;
    			for(int i = 0;i <= 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("无棋可下
    ");
    			else Pblue(),printf("无棋可下
    ");
    			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
    ",R);
    	Pblue();printf("蓝方得分:%d
    ",B);
    	Sleep(1000);
    	if(R == B){
    		Pwhite();printf("--平局--
    ");
    		}
    	else if(R > B){
    		Pred();printf("--红方胜--
    ");
    		}
    	else{
    		Pblue();printf("--蓝方胜--
    "); 
    		}
    	Sleep(2000);
    	PTONY();printf("Thanks to play my game
    ");
    	Sleep(2000);
    	printf("Press any key to end
    ");
    	char c = getch();
    	return 0;
    	}
    
  • 相关阅读:
    多继承
    NavigationController的使用
    WebService概述
    IOS block 教程
    多测师肖老师__项目讲解(12.3)
    跨平台跨服务器跨网站SSO(单点登录)方案的DEMO
    使用SQL Server Profiler
    asp.net生成高质量缩略图通用函数(c#代码),支持多种生成方式
    SQL优化实例:从运行30分钟到运行只要30秒
    测试工具的选择和使用
  • 原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/9285526.html
Copyright © 2020-2023  润新知