C语言实现小游戏2048

前言:如何检测你是否已经基本入门编程了?来做个2048吧,熟悉语法,会将问题具象为代码来解决,好处大大滴有啊🤩,下面贴上博主自己用C实现的2048,之前虽然写过一次,但全忘干净了😶,所以这次的代码看起来会比较臃肿(大脑已经干了,现在干啥啥不会),大家参考后可以自行优化修改,也欢迎讨论😘

main函数:

#include "map.h"
#include "move_and_add.h"
#include "score.h"
int main(){
    int map[4][4]={0};
    char input_key;
    int if_init=0;
    int score=0;
    int end_flay=0;
    printf("Using w,a,s,d to control map moving!\n");
    while(1){
        end_flay=game_End(map,&score);
        if(end_flay){//判断游戏是否结束
            printf("GAME OVER!\nYour score is %d\n",score);
        }
        generate_Map(map,if_init);
        print_Map(map);
        scanf("%c",&input_key);
        getchar();//使用scanf后记得过滤回车键
        switch(input_key){
            case 'w':
                move_Up(map);//先做移动
                add(map,'U');//全部移动完毕都再合并
                move_Up(map);//合并后棋盘中可能会有空缺,再移动一次
                break;
            case 's':
                move_Down(map);
                add(map,'D');
                move_Down(map);
                break;
            case 'a':
                move_Left(map);
                add(map,'L');
                move_Left(map);
                break;
            case 'd':
                move_Right(map);
                add(map,'R');
                move_Right(map);
                break;
            default:
                printf("Wrong input!\n");
                break;
        }
        if_init++;
    }
    return 0;
}

移动和相加函数:

//比较容易遇到的问题:每次相加只能执行一次
#include "move_and_add.h"
void add(int (*m)[4],char direction){//实现等项相加
    int bool_num=0;
    switch(direction){
        case 'U':
            for(int i=0;i<4;i++){//从上往下遍历,有空缺再用一次move来弥补
                for(int j=0;j<3;j++){
                    if(bool_num==1){
                        break;
                    }
                    if(m[j][i]==m[j+1][i]){
                        m[j][i]+=m[j][i];
                        m[j+1][i]=0;
                        bool_num=1;
                    }
                }
                bool_num=0;
            }
            break;
        case 'D':
            for(int i=0;i<4;i++){
                for(int j=4;j>0;j--){
                    if(bool_num==1){
                        break;
                    }
                    if(m[j][i]==m[j-1][i]){
                        m[j][i]+=m[j][i];
                        m[j-1][i]=0;
                        bool_num=1;
                    }
                }
                bool_num=0;
            }
            break;
        case 'L':
            for(int i=0;i<4;i++){
                for(int j=0;j<3;j++){
                    if(bool_num==1){
                        break;
                    }
                    if(m[i][j]==m[i][j+1]){
                        m[i][j]+=m[i][j];
                        m[i][j+1]=0;
                        bool_num=1;
                    }
                }
                bool_num=0;
            }
        case 'R':
            for(int i=0;i<4;i++){
                for(int j=3;j>0;j--){
                    if(bool_num==1){
                        break;
                    }
                    if(m[i][j]==m[i][j-1]){
                        m[i][j]+=m[i][j];
                        m[i][j-1]=0;
                        bool_num=1;
                    }
                }
                bool_num=0;
            }
    }
}
void move_Up(int (*m)[4]){//向上操作,下面的三个函数同理
    for(int i=0;i<4;i++){
        for(int j=1;j<4;j++){//从上至下依次遍历,直到出现非0数字,再进行反向遍历将其移动至顶端,下同
            if(m[j][i]!=0){
                for(int k=j;k>0;k--){//若两个不同数字相邻,则改变下标,进行三次循环
                    if(m[k-1][i]==0){
                        m[k-1][i]=m[k][i];
                        m[k][i]=0;
                    }
                }
            }
        }
    }
}
void move_Down(int (*m)[4]){
    for(int i=0;i<4;i++){
        for(int j=3;j>=0;j--){
            if(m[j][i]!=0){
                for(int k=j;k<3;k++){
                    if(m[k+1][i]==0){
                        m[k+1][i]=m[k][i];
                        m[k][i]=0;
                    }
                }
            }
        }
    }
}
void move_Left(int (*m)[4]){
    for(int i=0;i<4;i++){
        for(int j=1;j<4;j++){
            if(m[i][j]!=0){
                for(int k=j;k>0;k--){
                    if(m[i][k-1]==0){
                        m[i][k-1]=m[i][k];
                        m[i][k]=0;
                    }
                }
            }
        }
    }
}
void move_Right(int (*m)[4]){
    for(int i=0;i<4;i++){
        for(int j=3;j>=0;j--){
            if(m[i][j]!=0){
                for(int k=j;k<3;k++){
                    if(m[i][k+1]==0){
                        m[i][k+1]=m[i][k];
                        m[i][k]=0;
                    }
                }
            }
        }
    }
}

棋盘操作函数:

#include "map.h"
void generate_Map(int (*m)[4],int if_start){
    srand(time(NULL));
    int quit=0;//每次只生成2个随即数
    int rand_num=0;
    int rand_line=0;
    int rand_columu=0;
    for(int i=0;i<16;i++){
        if(if_start==0){
            if(quit>=2){//当产生两个随机数后退出
                break;
            }
        }
        else{
            if(quit>=1){
                break;
            }
        }
        rand_num=(int)((double)rand()/RAND_MAX*2);//随机生成0或1判断填入的数是2还是4
        rand_line=(int)((double)rand()/RAND_MAX*4);//随机生成0~3代表要填入数字的行,下面的列同理
        rand_columu=(int)((double)rand()/RAND_MAX*4);
        if(m[rand_line][rand_columu]==0){//判断此位置原先存放的数是否为0
            if(rand_num==0){
                m[rand_line][rand_columu]=2;
            }
            else{
                m[rand_line][rand_columu]=4;
            }
            quit++;
        }
    }
}
void print_Map(int (*m)[4]){
    for(int i=0;i<4;i++){
        for(int j=0;j<4;j++){
            printf("%d\t",m[i][j]);//打印每一行的数据
        }
        printf("\n\n\n");//行间换行
    }
}

计分并判断是否结束的函数:

#include "score.h"
int game_End(int (*m)[4],int* score){
    int bool_num=1;
    *score=0;
    for(int i=0;i<4;i++){
        for(int j=0;j<4;j++){
            if(m[i][j]==0){
                bool_num=0;
            }
            if(*score<m[i][j]){
                *score=m[i][j];
            }
        }
    }
    return bool_num;
}

以下是2048小游戏C语言完整版代码: ```c #include <stdio.h> #include <stdlib.h> #include <time.h> #include <conio.h> #define ROW 4 #define COL 4 int board[ROW][COL] = {0}; int score = 0; void init_board() { int i, j; for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) { board[i][j] = 0; } } srand(time(NULL)); int r1 = rand() % ROW; int c1 = rand() % COL; board[r1][c1] = 2; int r2 = rand() % ROW; int c2 = rand() % COL; while (r2 == r1 && c2 == c1) { r2 = rand() % ROW; c2 = rand() % COL; } board[r2][c2] = 2; score = 0; } void draw_board() { system("cls"); printf("-----------------------------\n"); printf("| 2048 Game |\n"); printf("-----------------------------\n"); printf("Score: %d\n", score); int i, j; for (i = 0; i < ROW; i++) { printf("|"); for (j = 0; j < COL; j++) { if (board[i][j] == 0) { printf(" |"); } else { printf("%-6d|", board[i][j]); } } printf("\n"); printf("-----------------------------\n"); } } void merge(int arr[]) { int i, j; for (i = 0; i < COL - 1; i++) { if (arr[i] == 0) { continue; } for (j = i + 1; j < COL; j++) { if (arr[j] == 0) { continue; } if (arr[i] == arr[j]) { arr[i] += arr[j]; arr[j] = 0; score += arr[i]; break; } else { break; } } } } void shift_left() { int i, j; for (i = 0; i < ROW; i++) { merge(board[i]); for (j = 0; j < COL - 1; j++) { if (board[i][j] == 0) { int k; for (k = j + 1; k < COL; k++) { if (board[i][k] != 0) { board[i][j] = board[i][k]; board[i][k] = 0; break; } } } } } } void shift_right() { int i, j; for (i = 0; i < ROW; i++) { merge(board[i]); for (j = COL - 1; j > 0; j--) { if (board[i][j] == 0) { int k; for (k = j - 1; k >= 0; k--) { if (board[i][k] != 0) { board[i][j] = board[i][k]; board[i][k] = 0; break; } } } } } } void shift_up() { int i, j, k; for (j = 0; j < COL; j++) { int arr[ROW] = {0}; for (i = 0, k = 0; i < ROW; i++) { arr[k++] = board[i][j]; } merge(arr); for (i = 0, k = 0; i < ROW; i++) { board[i][j] = arr[k++]; } } } void shift_down() { int i, j, k; for (j = 0; j < COL; j++) { int arr[ROW] = {0}; for (i = ROW - 1, k = 0; i >= 0; i--) { arr[k++] = board[i][j]; } merge(arr); for (i = ROW - 1, k = 0; i >= 0; i--) { board[i][j] = arr[k++]; } } } int game_over() { int i, j; for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) { if (board[i][j] == 0) { return 0; } if (i < ROW - 1 && board[i][j] == board[i + 1][j]) { return 0; } if (j < COL - 1 && board[i][j] == board[i][j + 1]) { return 0; } } } return 1; } int get_key() { int ch = getch(); if (ch == 0xE0 || ch == 0) { ch = getch(); switch (ch) { case 72: return 'w'; case 80: return 's'; case 75: return 'a'; case 77: return 'd'; } } return ch; } int main() { init_board(); draw_board(); while (1) { int key = get_key(); switch (key) { case 'w': shift_up(); break; case 's': shift_down(); break; case 'a': shift_left(); break; case 'd': shift_right(); break; case 'q': exit(0); default: continue; } if (game_over()) { printf("Game Over!\n"); break; } int r = rand() % ROW; int c = rand() % COL; while (board[r][c] != 0) { r = rand() % ROW; c = rand() % COL; } board[r][c] = 2; draw_board(); } return 0; } ``` 可以在命令行中编译运行实现了基本的2048游戏功能。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值