美文网首页
C控制台实现2048小游戏

C控制台实现2048小游戏

作者: MagicalGuy | 来源:发表于2018-10-27 15:19 被阅读0次
    image.png
    #include"stdafx.h"
    #include"stdlib.h"
    #include"stdio.h"
    #include"time.h"
    #include"conio.h"
    #include"windows.h"
    
    int grid[4][4] = { 0 };  //保存4*4的格子数字
    int score = 0;//游戏分数
    
    void gotoXY(int x, int y)      //设定输出位置
    {
        COORD c;   //光标位置
        c.X = x - 1;
        c.Y = y - 1;
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);//获取句柄,设置位置
    
        HANDLE hOutStd = GetStdHandle(STD_OUTPUT_HANDLE);
        CONSOLE_CURSOR_INFO cci;   //控制台光标信息结构类型
        cci.dwSize = 1;   //光标大小
        cci.bVisible = 0;      //是否显示光标  true显示
        SetConsoleCursorInfo(hOutStd, &cci);   //设置控制台屏幕光标大小和可见性
    }
    
    
    
    void printGrid() {   //打印游戏表格
        system("cls");
        printf("======C语言控制台版2048游戏======\n");
        for (int i = 0; i < 4; i++) {
            printf("---------------------------------\n");
            for (int j = 0; j < 4; j++) {
                if (grid[i][j] == 0) { printf("|  \t"); }//打印空数
                else printf("| %d\t", grid[i][j]);//打印数字
            }
            printf("|\n");//换行
        }
    
        printf("---------------------------------\n");
    
        gotoXY(18 * 2, 5);//定位输出
        printf("目前得分:%d", score);
        gotoXY(18 * 2, 7);
        printf("《请按四个方向箭头进行操作》");
    }
    
    
    void  randomNum() {
        srand((unsigned int)time(NULL));
        int x = rand() % 4;   //随机坐标
        int y = rand() % 4;
    
        while (grid[x][y] != 0) {//生成的位置已经有数字就重新生成
            x = rand() % 4;
            y = rand() % 4;
        }
    
        int z = rand() % 5;//概率媒介
    
        if (z == 0)grid[x][y] = 4;//五分之一的概率产生数字4
        else grid[x][y] = 2;//五分之四的概率产生数字2
    }
    
    
    //获取格子中的最大的数字
    int getMax() {
        int max = 0;
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if (grid[i][j] > max) {
                    max = grid[i][j];
                }
            }
        }
        return max;
    }
    
    
    int  gameOver() {
    
        int result = 1;//等于0继续游戏,等于1结束游戏
    
        //计算最大的数为2048时赢得游戏结束
        if (getMax() == 2048) {
            result = 1;
            printf("恭喜你赢得游戏!/n");
            system("pause");
        }
    
        //判断存在空格子,继续
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if (grid[i][j] == 0) result = 0;
                break;
            }
        }
    
    
        //如果格子都不为空,需要进一步判断相邻格子数字是否相同
        if (result == 1) {
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 4; j++) {
                    if (i != 0 && grid[i][j] == grid[i - 1][j]) result = 0;  //与上面的数比较
                    if (i != 3 && grid[i][j] == grid[i + 1][j]) result = 0;  //与下面的数比较
                    if (j != 0 && grid[i][j] == grid[i][j - 1]) result = 0;//与左边的数比较
                    if (j != 3 && grid[i][j] == grid[i][j + 1]) result = 0;//与右边的数比较
                }
            }
        }
    
        return result;
    
    }
    
    
    //向上划
    int toUp() {
    
        int col, row;
        int isMove = 0;//默认0不移动,设置为1表明已经移动
    
        for (col = 0; col < 4; col++) {
            for (row = 1; row < 4; row++) {//纵向开始
                if (grid[row][col] && grid[row - 1][col] == 0) {  //本格不为空,上一格数为空,补空位
                    grid[row - 1][col] = grid[row][col];
                    grid[row][col] = 0;//补位后置空
                    //重置row,补位到最终位置
                    if (row > 1) row -= 2;
                    isMove = 1;
                }
            }
    
            //纵向相邻相同的数字则累加合位
            for (int row = 1; row < 4; row++) {
                if (grid[row][col] && grid[row - 1][col] == grid[row][col]) {//本格不为空,且与上一格数字相同则合并
                    grid[row - 1][col] *= 2;
                    score += grid[row][col];
                    grid[row][col] = 0;//合并完后置空
                    isMove = 1;
                }
            }
    
            //合并后再次补空位
            for (row = 1; row < 4; row++) {
                if (grid[row][col] && grid[row - 1][col] == 0) {  //本格数不为空,上一格数为空,补空位
                    grid[row - 1][col] = grid[row][col];
                    grid[row][col] = 0;//补位后置空
                    //重置row,补位到最终位置
                    if (row > 1) row -= 2;
                }
            }
    
        }
    
    
        return isMove;
    
    }
    
    //向下划
    int toDown() {
        int col, row;
        int isMove = 0;//默认0不移动
    
        for (col = 0; col < 4; col++) {
            for (row = 2; row >= 0; row--) {//纵向开始
                if (grid[row][col] && grid[row + 1][col] == 0) {  //本格数不为空,下一格数为空,补空位
                    grid[row + 1][col] = grid[row][col];
                    grid[row][col] = 0;//补位后置空
                     //重置row,补位到最终位置
                    if (row < 2) row += 2;
                    isMove = 1;
                }
            }
    
            //纵向相邻相同的数字则累加合位
            for (row = 2; row >= 0; row--) {
                if (grid[row][col] && grid[row + 1][col] == grid[row][col]) {//本格不为空,且与下一格数字相同则合并
                    grid[row + 1][col] *= 2;
                    score += grid[row][col];
                    grid[row][col] = 0;//合并完后置空
                    isMove = 1;
                }
            }
    
            //合并后再次补空位
            for (row = 2; row >= 0; row--) {
                if (grid[row][col] && grid[row + 1][col] == 0) {  //本格数不为空,下一格数为空,补空位
                    grid[row + 1][col] = grid[row][col];
                    grid[row][col] = 0;//补位后置空
                     //重置row,补位到最终位置
                    if (row < 2) row += 2;
                }
            }
    
        }
    
    
        return isMove;
    
    }
    
    
    //向左划
    int toLeft() {
        int col, row;
        int isMove = 0;//默认0不移动
    
        for (row = 0; row < 4; row++) {
            for (col = 1; col < 4; col++) {//横向开始
                if (grid[row][col] && grid[row][col - 1] == 0) {  //本格数不为空,左格数为空,补空位
                    grid[row][col - 1] = grid[row][col];
                    grid[row][col] = 0;//补位后置空
                    //重置col,补位到最终位置
                    if (col > 1) col -= 2;
                    isMove = 1;
                }
            }
    
            //横向相邻相同的数字则累加合位
            for (int col = 1; col < 4; col++) {
                if (grid[row][col] && grid[row][col - 1] == grid[row][col]) {//本格不为空,且与左边数字相同则合并
                    grid[row][col - 1] *= 2;
                    score += grid[row][col];
                    grid[row][col] = 0;//合并完后置空
                    isMove = 1;
                }
            }
    
            //合并后再次补空位
            for (col = 1; col < 4; col++) {
                if (grid[row][col] && grid[row][col - 1] == 0) {  //本格数不为空,左格数为空,补空位
                    grid[row][col - 1] = grid[row][col];
                    grid[row][col] = 0;//补位后置空
                    //重置col,补位到最终位置
                    if (col > 1) col -= 2;
                }
            }
    
        }
    
        return isMove;
    
    }
    
    
    //向右划
    int toRight() {
        int col, row;
        int isMove = 0;//默认0不移动
    
        for (row = 0; row < 4; row++) {
            for (col = 2; col >= 0; col--) {//横向开始
                if (grid[row][col] && grid[row][col + 1] == 0) {  //本格数不为空,右格数为空,补空位
                    grid[row][col + 1] = grid[row][col];
                    grid[row][col] = 0;//补位后置空
                    //重置col,补位到最终位置
                    if (col < 2) col += 2;
                    isMove = 1;
                }
            }
    
            //横向相邻相同的数字则累加合位
            for (col = 2; col >= 0; col--) {
                if (grid[row][col] && grid[row][col + 1] == grid[row][col]) {//本格不为空,且与右边数字相同则合并
                    grid[row][col + 1] *= 2;
                    score += grid[row][col];
                    grid[row][col] = 0;//合并完后置空
                    isMove = 1;
                }
            }
    
            //合并后再次补空位
            for (col = 2; col >= 0; col--) {
                if (grid[row][col] && grid[row][col + 1] == 0) {  //本格数不为空,右格数为空,补空位
                    grid[row][col + 1] = grid[row][col];
                    grid[row][col] = 0;//补位后置空
                     //重置col,补位到最终位置
                    if (col < 2) col += 2;
                }
            }
    
        }
    
        return isMove;
    }
    
    //接收移动按键并刷新格子移动
    void moveDirection() {
        int ch = _getch();
    
        switch (ch) {
            //向上箭头 224 72  判断接收两次
        case 72: //上划
            if (toUp() == 1) {
                randomNum();
                printGrid();
            }
            break;
            //向下箭头 224 80  判断接收两次
        case 80://下划
            if (toDown() == 1) {
                randomNum();
                printGrid();
            }
            break;
            //向左箭头 224 75  判断接收两次
        case 75: //左划
            if (toLeft() == 1) {
                randomNum();
                printGrid();
            }
            break;
            //向右箭头 224 77  判断接收两次
        case 77://右划
            if (toRight() == 1) {
                randomNum();
                printGrid();
            }
            break;
        default:break;
        }
    }
    
    
    void playGame() {   //开始游戏
    
        int flag = 1;
    
        while (flag) {
            //初始化格子,设置为0
            memset(grid, 0, sizeof(grid));
            //产生两个随机数字
            randomNum();
            randomNum();
            //打印格子
            printGrid();
    
            //游戏没有结束就可以一直操作,1是结束游戏
            while (gameOver() == 0) {
                //接收移动按键并进行移动
                moveDirection();
            }
    
            system("cls");
            printf("游戏结束,您的分数为:%d\n", score);
            printf("按y继续游戏,按n退出游戏!\n");
    
    
            //切换英文输入法
            keybd_event(VK_SHIFT, 0, 0, 0);
            Sleep(100);
            keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
    
            int mark = 1;
            while (mark) {
    
                //接收按键
                char ch = _getch();
    
                if (ch == 'y' || ch == 'Y') {
                    flag = 1;
                    mark = 0;
                    score = 0;
                }
                else if (ch == 'n' || ch == 'N') {
                    system("cls");
                    printf("欢迎下次来玩!\n");
                    system("pause");
                    exit(1);
                }
                else {
                    printf("输入错误,请重新输入!\n");
                }
            }
        }
    }
    
    int main() {
        //进行2048游戏
        playGame();
        system("pause");
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:C控制台实现2048小游戏

          本文链接:https://www.haomeiwen.com/subject/mssdtqtx.html