用C++ 写小项目 2048

通过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();
    }
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值