2048-控制台版本
来源:互联网 发布:2016qq悄悄话破解软件 编辑:程序博客网 时间:2024/06/05 14:57
/最近修改2017/6/26/
/修改2017/7/4,修改之前各自填满之后无法移动的错误,暂时未发现大的错误/
/最后修改2017/7/5,添加前景色,添加模式选择,改善界面/
一.实现目标:
2048游戏
二.要求:
1、在屏幕上显示4*4的表格
2、随机生成2、4数字及位置
3、颜色设置
三.运行环境和工具:
VC++6.0
四.实现步骤
0.游戏逻辑:
把游戏画面想象成4*4的数组,其中数值为0的位置表示空的格子,
有数值的位置代表对应的格子。然后对于每一行按列来遍历,或者每一列按行来遍历,实现每一行每一列的对应数字合并,直到出现2048的格子就胜利,否则就失败.
1.编写用于实现数字移动的方向函数
以向左移动为例:
把游戏画面想象成4*4的数组,其中数值为0的位置表示空的格子,
先看其中一行,有四列,用一个变量k=0,从第一列开始,另一个变量j=1开始,代表k之后的列,开始遍历。
如果第j列这个位置不为0的话,那么之后可以分为3种情况:
第一种情况:第k列和第j列相同,这个时候就将第k列的数字加倍,第j列重置为0.
第二种情况:第k列为0,那么就交换第k列和第j列的数字。
第三种情况:第k列和第j列都不为0,但是两者不相等,这个时候,就把两个数紧挨在一起,如果j和k原本就紧挨在一起,那么什么也不做。
而如果第j列为,也什么也不做。
在向左移动的时候,每一行都向左移动,所以逐行相加,然后按列遍历。
同理,向右移动,区别在于,向右是反向的按列遍历,向上是逐列相加,按行遍历,向右于向左移动是行列相反的遍历。
每次移动,步数就+1,每次合并,就会加上当前合并的格子的数值。
2.编写用于实现随机数字和随机位置的函数,以及游戏结束函数,显示格子函数,初始化函数,退出函数等 #define TARGET 2048
标记最终的目标,同时也是判断游戏是否结束的标志之一,如果在格子中出现了2048的格子,玩家胜利,游戏结束。另一种结束方式是,当所有的格子都被填满的时候,同时不存在可以相互合并的格子,并且没有2048的格子,游戏结束,玩家失败。
3.困难模式下随机函数用来随机出现数字2和4,使得出现的概率之比为1:10,保证游戏时间不至于过短。
正常模式下随机函数2和4出现概率之比为1:4
4.Begin()函数用来将数组初始化为0,包括分数和步数的清零
但是这个只在游戏开始的时候执行一次。
5.显示格子函数:设置好打印颜色,以及格子间距
五.程序运行:
六.以下为完整代码
#include<conio.h>#include<time.h>#include<Windows.h>#include<stdio.h>#include<string.h>#include<math.h>#include<stdlib.h>#define TARGET 2048 //最终目标HANDLE myHandle; //控制句柄,对象const WORD FORE_BLUE =FOREGROUND_BLUE; //蓝色文本const WORD FORE_GREEN =FOREGROUND_GREEN; //绿色文本const WORD FORE_RED =FOREGROUND_RED; //红色文本 const WORD FORE_YELLOW =FORE_RED|FORE_GREEN; //黄色文本,其他颜色用三原色搭配const WORD FORE_GRAY =FORE_BLUE|FORE_GREEN; //紫色文本const WORD BACK_BLUE =BACKGROUND_BLUE; //蓝色背景const WORD BACK_GREEN =BACKGROUND_GREEN; //绿色背景const WORD BACK_RED =BACKGROUND_RED; //红色背景 const WORD BACK_YELLOW =BACK_RED|BACK_GREEN; //黄色背景,其他颜色用三原色搭配const WORD BACK_GRAY =BACK_BLUE|BACK_GREEN; //紫色背景int pass=0; //用来判断是否需要返回int Game; //标记游戏是否结束int ax[4][4]; //控制的二维数组int score=0; //记录分数int step=0; //记录所花费的步数void Up(); //向上移动数字,使其相同的合成,不同的紧凑void Down(); //向下void Right(); //向右 void Left(); //向左void Movement(); //正常移动void Movement_2(); //困难移动void GAME_OVER(); //标记游戏是否结束void Exit(); //退出函数void Begin(); //初始化数组void Run(); //将随机出现的数字放入随机的坐标当中,概率修改void Run_2(); //概率之比为1:10void Show(); //显示格子void Mode1(); //正常模式void Mode2(); //困难模式void Help(); //帮助手册void choice(); //选择void Menu(); //菜单void Help(){ system("cls"); HANDLE handle_out=GetStdHandle(STD_OUTPUT_HANDLE); //获取标准输入设备句柄 CONSOLE_SCREEN_BUFFER_INFO csbi; //定义窗口缓冲区信息结构体 GetConsoleScreenBufferInfo(handle_out,&csbi); //获得窗口缓冲区信息 SetConsoleTextAttribute(handle_out,FORE_YELLOW); //设置打印颜色为绿色 printf(" --------------------------------------------\n"); printf(" ********************************************\n\n"); printf(" 操作说明:\n↓:下 ←:左 ↑:上 →:右 ESC键:退出\n\n"); printf(" 游戏介绍:每次选择一个方向滑动,每次滑动,除了数字向该方向靠拢之外,系统会在空格处生成随机数字2或者4,\n"); printf(" 相同数字可以相加。如果拼凑出“2048”这个数字,则游戏胜利!\n"); system("pause"); system("cls");}void Left(){ int i,j,k; for(i=0;i<4;i++) //行数 { for(j=1,k=0;j<4;j++) //每一行按列来遍历 { if(ax[i][j]!=0) { if(ax[i][k]==ax[i][j]) { ax[i][k]<<=1; score+=ax[i][k]; ax[i][j]=0; k++; } else if(ax[i][k]==0) { ax[i][k]=ax[i][j]; ax[i][j]=0; k++; } else { k++; ax[i][k]=ax[i][j]; if(k!=j) { ax[i][j]=0; } } } } } step++;}void Right(){ int i,j,k; for(i=0;i<4;i++) { for(j=2,k=3;j>=0;j--) { if(ax[i][j]!=0) { if(ax[i][j]==ax[i][k]) { ax[i][k]<<=1; score+=ax[i][k]; ax[i][j]=0; k--; } else if(ax[i][k]==0) { ax[i][k]=ax[i][j]; ax[i][j]=0; k--; } else { k--; ax[i][k]=ax[i][j]; if(j!=k) { ax[i][j]=0; } } } } } step++;}void Up(){ int n,i,j,k; for(n=0;n<4;n++) { k=0; for(i=0;i<4;i++) { if(ax[i][n]!=0) { for(j=i;j>k;j--) { if(ax[j-1][n]==0) //上一行没有数字 { ax[j-1][n]=ax[j][n]; ax[j][n]=0; } else if(ax[j-1][n]==ax[j][n]) { ax[j-1][n]=2*ax[j-1][n]; score+=ax[j-1][n]; ax[j][n]=0; k=j; Sleep(1); break; } else break; } } } } step++;}void Down(){ int i,j,k; for(j=0;j<4;j++) { for(i=2,k=3;i>=0;i--) { if(ax[i][j]!=0) { if(ax[i][j]==ax[k][j]) { ax[k][j]<<=1; score+=ax[k][j]; ax[i][j]=0; k--; } else if(ax[k][j]==0) { ax[k][j]=ax[i][j]; ax[i][j]=0; k--; } else { k--; ax[k][j]=ax[i][j]; if(k!=i) { ax[i][j]=0; } } } } } step++;}void Movement(){ if(kbhit()) { switch(getch()) { case 27: Exit(); break; case 75: //向左 Left(); Run(); Show(); break; case 72: //向上 Up(); Run(); Show(); break; case 77: //向右 Right(); Run(); Show(); break; case 80: //向下 Down(); Run(); Show(); break; default: break; } }}void Movement_2(){ if(kbhit()) { switch(getch()) { case 27: Exit(); break; case 75: //向左 Left(); Run_2(); Show(); break; case 72: //向上 Up(); Run_2(); Show(); break; case 77: //向右 Right(); Run_2(); Show(); break; case 80: //向下 Down(); Run_2(); Show(); break; default: break; } }}void Exit(){ int i=0; printf("\n退出中"); for(i=4;i>0;--i) { Sleep(200); printf("."); } exit(0);}void Begin(){ int i=0,j=0; score=0; //分数清零 Game=0; //初始游戏 step=0; //步数清零 SetConsoleTitleA("游戏:2048"); for(i=0;i<4;i++) { for(j=0;j<4;j++) { ax[i][j]=0; } }}void Run(){ int x,y,temp,num; srand((int)time(0)); while(1) { x=rand()%4; y=rand()%4; temp=rand()%5; //概率之比为1:4 if(temp==1) num=4; else num=2; if(ax[x][y]==0) { ax[x][y]=num; break; } }}void Run_2(){ int x,y,temp,num; srand((int)time(0)); while(1) { x=rand()%4; y=rand()%4; temp=rand()%10; //概率之比为1:10 if(temp==1) num=4; else num=2; if(ax[x][y]==0) { ax[x][y]=num; break; } }}void GAME_OVER(){ int i,j; for(i=0;i<4;i++) { for(j=0;j<3;j++) { if(ax[i][j]==ax[i][j+1]||ax[j][i]==ax[j+1][i]) { Game=0;//同列中的存在刻意继续合并的数字,游戏继续 return ; } else if(ax[i][j]==0||ax[i][j+1]==0||ax[j][i]==0||ax[j+1][i]==0) { Game=0; return ; } else if(ax[i][j]==TARGET||ax[i][j+1]==TARGET||ax[j][i]==TARGET||ax[j+1][i]==TARGET) { Game=2; return; //存在2048,游戏结束 } } } Game =1; //不存在2048,但是同行同列中没有能够合并的数字,并且没有空位置,游戏结束}void Show(){ int i,j; HANDLE handle_out=GetStdHandle(STD_OUTPUT_HANDLE); //获取标准输入设备句柄 CONSOLE_SCREEN_BUFFER_INFO csbi; //定义窗口缓冲区信息结构体 GetConsoleScreenBufferInfo(handle_out,&csbi); //获得窗口缓冲区信息 system("cls"); SetConsoleTextAttribute(handle_out,FORE_GREEN); //设置打印颜色为绿色 printf(" --------------------------------------------\n"); printf(" ********************************************\n"); //上界 SetConsoleTextAttribute(handle_out,FORE_RED); //设置打印颜色为红色 printf(" |----|----|----|----|\n"); //格子上半部分 for(i=0;i<4;i++) { SetConsoleTextAttribute(handle_out,FORE_RED); //设置打印颜色为红色 printf(" |"); for(j=0;j<4;j++) { if(ax[i][j]!=0) { SetConsoleTextAttribute(handle_out,FORE_YELLOW); //设置打印颜色为黄色 printf("%4d|",ax[i][j]); } else { SetConsoleTextAttribute(handle_out,FORE_YELLOW); //设置打印颜色为黄色 printf(" |"); } } printf("\n"); SetConsoleTextAttribute(handle_out,FORE_RED); //设置打印颜色为红色 printf(" |----|----|----|----|\n"); } //格子下半部分 SetConsoleTextAttribute(handle_out,FORE_GREEN); //设置打印颜色为绿色 printf(" --------------------------------------------\n"); printf(" ********************************************\n"); printf(" ↓:下 ←:左 ↑:上 →:右 ESC键:退出\n\n"); SetConsoleTextAttribute(handle_out,FORE_RED); //设置打印颜色为红色 printf(" ■▲□■○□■○□ ■○□■○□■○□\n"); printf(" ▲▲"); SetConsoleTextAttribute(handle_out,FORE_YELLOW); //设置答应颜色为黄色 printf("分数:%-3d ",score); SetConsoleTextAttribute(handle_out,FORE_RED); printf("▲□ ■○"); SetConsoleTextAttribute(handle_out,FORE_YELLOW); printf("步数:%-3d ",step); SetConsoleTextAttribute(handle_out,FORE_RED); printf("○□\n"); printf(" ■▲ ○□ ■○ ○□\n"); printf(" ■▲▲■▲□■○□ ■○□■○□■○□\n"); //下界 if(Game==1) //游戏结束,失败 { printf("\n Sorry,you losed!!!!!!!!!!!!!!!!!!!!!!\n"); system("pause"); Exit(); } if(Game==2) //游戏成功,胜利 { printf("\n Good!YOU WIN!!!!!!!!!!!!!!!!!!!!!!!!\n"); system("pause"); Exit(); }}void Mode1(){ Begin(); //游戏初始化 Run(); //随机一个数字 Run(); Show(); while(1) { GAME_OVER(); //每次都判断一次游戏是否结束 if(Game==1||Game==2) { break; } Movement(); } Show(); return ;}void Mode2(){ Begin(); Run_2(); Run_2(); Show(); while(1) { GAME_OVER(); if(Game==1||Game==2) { break; } Movement_2(); } Show(); return ;}void Menu(){ SetConsoleTitleA("游戏:2048"); HANDLE handle_out=GetStdHandle(STD_OUTPUT_HANDLE); //获取标准输入设备句柄 SetConsoleTextAttribute(handle_out,FORE_GREEN); //设置打印颜色为绿色 printf(" --------------------------------------------\n"); printf(" ********************************************\n"); SetConsoleTextAttribute(handle_out,FORE_YELLOW); //设置打印颜色为绿色 printf(" 菜单\n"); SetConsoleTextAttribute(handle_out,FORE_GREEN|FORE_YELLOW); //设置打印颜色为青色 printf(" a.正常模式\n"); printf(" b.困难模式\n"); printf(" c.帮助手册\n"); printf(" d.游戏结束\n"); printf(" 请输入你的选择\n");}void choice(){ char ch='0'; scanf(" %c",&ch); switch(ch) { case 'a': Mode1(); break; case'b': Mode2(); break; case'c': Help(); break; case'd': exit(0); break; default: break; }}int main(void){ while(1) { Menu(); choice(); } return 0;}
- Linux控制台版本2048
- Linux控制台版本2048
- 2048-控制台版本
- 【小游戏】C++打造2048控制台版本
- 断点续传控制台版本
- java控制台版本 俄罗斯方块
- Java成绩管理系统控制台版本
- 控制台添加版本信息
- 人品计算器控制台版本4.0
- 人品计算机控制台1.0版本
- 人品计算器控制台版本1.
- 控制台 2048
- 控制台2048
- Subversion版本读取控制台及源码 发布
- Windows 控制台注册表工具 - 版本 3.0
- PjComm:控制台版本的串口调试助手
- 继续小程序--控制台版本#字游戏
- 如何在控制台切换Xcode的版本
- Zookeeper集群环境搭建实践
- 设计模式——工厂模式之工厂方法
- mac下安装pyaudio
- 50以内奇数的和
- 基础知识记录:intent解析
- 2048-控制台版本
- sql group by,order by
- 只执行一次的装饰器
- javascript笔记(六)
- 尚学堂百战程序员1573题 答案 第三章
- STM32 485 调试
- 远场(far-field)语音识别的主流技术有哪些
- 【1】稀疏表示与匹配追踪
- Leveldb源码解析第七篇【log】