通过C++来实现2048小程序 我通过思维导图来画出了整个框架,大家可以参考一下
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <vector>
#include <time.h>
#include <stdlib.h>
using namespace std;
const int ROW = 4; //数组行和列
const int COL = 4;
//定义一个全局数组
static int data[ROW ][COL];
//上下左右
int const UP = 1;
int const DOWN = 2;
int const LEFT = 3;
int const RIGHT = 4;
static bool move_flag = false;//默认为无效移动
inline int getrand(){ //通过时间作为随机种子,获取随机数
srand(static_cast<unsigned int>(time(nullptr)));
return rand();
}
void Print(void)
{
system("cls");//清屏
cout << "************* 2048 控制台程序**************"<<endl<<endl;
cout<<"*********** by lincsen 2018-3-27 *************"<<endl<<endl;
cout << endl << endl;
for (int i =0; i < ROW; i++) { //打印表格,比较粗糙,感兴趣可以用配合界面软件来做
cout << " --------" << endl;
for(int j = 0; j < COL; j++){
cout <<"|"<<data[i][j];
}
cout<<"|"<<endl;
}
cout<< " --------" << endl;
}
bool CreatNumber()//创造随机数
{
int RandNum = getrand()%3;
vector<int> index;
for(int i = 0; i < ROW; i++){
for(int j = 0; j < COL; j++){
if(!data[i][j])
index.push_back(i*4+j); //记录空白格的索引'
}
}
if(index.empty())
{
return false;
}
else{
Num CreatNum;
int r = getrand()%index.size();
if(RandNum == 0){
CreatNum = Num_4; //1/3概率是4
}
else {
CreatNum = Num_2; //2/3概率是2
}
data[index[r]/4][index[r]%4] = CreatNum;
}
}
int Input() //通过键盘的上下左右键来控制程序
{
int up = 0;
int down = 0;
int left = 0;
int right = 0;
int direction = 0;
while(true)
{
up = GetAsyncKeyState(VK_UP);//window.h头文件
down = GetAsyncKeyState(VK_DOWN);
left = GetAsyncKeyState(VK_LEFT);
right = GetAsyncKeyState(VK_RIGHT);
if(up)
{
direction = UP;
cout << "it is UP"<<endl;
break;
}
if(down){
direction = DOWN;
break;
}
if(left){
direction = LEFT;
break;
}
if(right){
direction = RIGHT;
break;
}
Sleep(300);//延时300ms
}
return direction;
}
void clear_left(void){
int cur = 0;
for(int i=0;i<ROW;i++){
for(int j=0;j<COL-1;j++){
cur = j;
if(data[i][cur]==0 && (cur+1)<=3 && data[i][cur+1]){
swap(data[i][cur],data[i][cur+1]);
move_flag = true;
}
}
}
}
void clear_up(void){
int cur = 0;
for(int j=0;j<COL;j++){
for(int i=0;i<ROW-1;i++){
cur=i;
if(data[i][j]==0 &&(cur+1)<=3 && data[cur+1][j]){
swap(data[cur][j],data[cur+1][j]);
move_flag = true;
}
}
}
}
void clear_down(void){
int cur = 0;
for(int j=0;j<COL;j++){
for(int i=ROW-1;i>0;i--){
cur=i;
if(data[i][j]==0 &&cur-1>=0 && data[cur-1][j]){
swap(data[cur][j],data[cur-1][j]);
move_flag = true;
}
}
}
}
void clear_right(void){
int cur = 0;
for(int i=0;i<ROW;i++){
for(int j=COL-1;j>0;j--){
cur = j;
if(data[i][cur]==0 && (cur-1)>=0 && data[i][cur-1]){
swap(data[i][cur],data[i][cur-1]);
move_flag = true;
}
}
}
}
void move(const int direction_num){
switch (direction_num) {
case UP://判断当前的行的值是否为空;跟下一行的值一样就合并,把下一行标记为空;不一样则继续
for(int j = 0; j < COL;j++){
for(int i = 0; i < ROW-1;i++){
clear_up();//UP的情况,先清0
if(!data[i][j]) break; //清0后如果第一个数还是0,说明整一列都是0直接去处理下一列
if(data[i][j]==data[i+1][j]){
data[i][j] = 2*data[i][j];
data[i+1][j]=0;
move_flag = true;
}
}
}
break;
case DOWN:
for(int j = 0;j < COL;j++){
for(int i = ROW-1;i > 0;i--){
clear_down();
if(!data[i][j]) break;
if(data[i][j]==data[i-1][j]){
data[i][j] = 2*data[i][j];
data[i-1][j] = 0;
move_flag = true;
}
}
}
break;
case LEFT:
for(int i = 0;i< ROW;i++){
for(int j = 0;j < COL-1;j++){
clear_left();
if(!data[i][j]) break;
if(data[i][j]==data[i][j+1]){
data[i][j] = 2*data[i][j];
data[i][j+1] = 0;
move_flag = true;
}
}
}
break;
case RIGHT:
for(int i = 0;i < ROW; i++){
for(int j = COL - 1; j > 0; j--){
clear_right();
if(!data[i][j]) break;
if(data[i][j]==data[i][j-1]){
data[i][j] = 2*data[i][j];
data[i][j-1] = 0;
move_flag = true;
}
}
}
break;
}
}
bool judge_win(void){
for(int i=0;i<ROW;i++){
for(int j=0;j<COL;j++){
if(data[i][j]==2048){
cout << "you are win !" <<endl;
}
}
}
}
bool judge_lose(void){//返回 true说明还没有失败
//移动之后,所有方格都填满,并且没有可以再相加的方格则失败
bool has_empty_grid = false;
bool has_num_can_add = false;
for(int i=0;i<ROW;i++){ //只要有一个空格就把has_empty_grig置true
for(int j=0;j<COL;j++){
if(!data[i][j]) has_empty_grid = true;
}
}
for(int i=0;i<ROW-1;i++){
for(int j=0;j<COL-1;j++){
if((data[i][j]==data[i][j+1])||(data[i][j] == data[i+1][j])) has_num_can_add = true;
}
}
if(data[2][3]== data[3][3] || data[3][2] == data[3][3]) has_num_can_add = true;
if(!(has_empty_grid||has_num_can_add)) cout << "you are failed" <<endl;
return (has_empty_grid||has_num_can_add);
}
void init_num(void){
memset(data,0,sizeof(data));
CreatNumber();
CreatNumber();
}
int main(){
init_num();
Print();
while(1){
move(Input());
if(move_flag){
CreatNumber();
move_flag = false;
}
judge_win();
bool flag = judge_lose(); //返回失败的情况,判断是否要再来一次
if(!flag) cout <<"press enter to try again"<<endl;
while(!flag){
if(GetAsyncKeyState(VK_RETURN)){
init_num();
flag = true;
}
}
Print();
}
}