c++控制台小程序——2048(新手简易版)

先上效果图

在这里插入图片描述

大致思路

1.打印地图

老办法gotoxy函数

2.生成随机位置新数字

我在这部分加入了算法生成,因为随机生成通过时间改变来实现,因此如果当前位置有数字,时间改变坐标才变,若多次位置均有数字,界面就会停滞一段时间,算法使得很快就生成新的坐标

3.最麻烦的数字移动

首先使用键盘监听确定方向
然后我使用了3个大循环

(1)移动,覆盖空格
(2)向当前方向合并一次(只有一次!!!)
(3)再次覆盖空格

为什么要有3个大循环?

首先(1)移动填补空格,这个毫无疑问
然后(2)合并一次!!!这个决对不可以循环,更不可以嵌套在(1)里面!!!举个例子,当前4 2 0 2,向左应该是4 4 0 0,如果按照上述错误方法,就会变成8 0 0 0
最后(3)也必不可少,由于(2)的特殊,不可以嵌套入(1),如下面这个例子:4 4 2 2
向左为8 4 0 0,但只有(1)(2)的话最后是8 0 4 0,这就需要再次移动覆盖

4.游戏结束

很简单,移动后无法生成新数字则结束游戏

代码

#include <iostream>
#include <ctime>
#include <windows.h>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <conio.h>
using namespace std;

int map[4][4] = {0}; //定义4*4地图
int g = 1;  //主函数循环
int score = 0;
int move = 0;  //排除无效方向

void gotoxy(short x, short y);
void start();
void newNumber();
void print();
void hide();
void toTop();
void toBottom();
void toLeft();
void toRight();
void changeMap();
void gameOver();

int main()
{
    hide();
    start();
    newNumber();
    while(g)
    {
        if (kbhit()!=0)
            changeMap();

    }
    system("cls");  //打印分数
    gotoxy(5,5);
    cout << "your score: " << score;
    return 0;
}

void hide()  //隐藏光标
{
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO CursorInfo;
	GetConsoleCursorInfo(handle, &CursorInfo);//获取控制台光标信息
	CursorInfo.bVisible = false; //隐藏控制台光标
	SetConsoleCursorInfo(handle, &CursorInfo);
}

void gotoxy(short x, short y)  //定位
{
    COORD position = { x, y };
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(hOut, position);
}

void start()  //初始化界面
{
    gotoxy(20,3);
    cout << "score: " << score;
    for(int k=1;k<=7;)
    {
        for(int l=0;l<=16;)
        {
            gotoxy(l,k);
            cout << "|";
            l += 4;
        }
        k += 2;
    }
    for(int i=0;i<9;)
    {
        gotoxy(0,i);
        cout << "+---+---+---+---+";
        i += 2;
    }
}

void print()   //打印变化后的界面
{
    system("cls");
    start();
    for(int i=0;i<4;i++)
    {
        for(int l=0;l<4;l++)
        {
            gotoxy(4*i+2,2*l+1);
            if(map[i][l] != 0)
                cout << map[i][l];
            else
                cout << " ";
        }
    }
    gotoxy(20,3);
    cout << "score: " << score;
}

void newNumber()  //生成新数字坐标并打印
{
    Sleep(500);
    move = 0;
    int f = 1;
	while(f)
	{
	    int h = 1;
        srand((int)time(0));
        int x = rand() % 4;
        int y = rand() % 4;
        int y2 = y;
        if(map[x][y] != 0)  //时间随机不行就算法生成
        {
            while(h)
            {
                x += 1;
                y = y2;
                if(x == 4)
                    x = 0;
                for(int l=0;l<4;l++)
                {
                    if(map[x][y] == 0)
                    {
                        h = 0;
                        break;
                    }
                    else
                    {
                        y += 1;
                        if(y == 4)
                            y = 0;
                    }
                }
            }

        }
        map[x][y] = 2;
        f = 0;
        gotoxy(4*x+2,2*y+1);
        cout << map[x][y];

	}
}

void toTop()  //向上移动
{               //1.填补空位
    for(int i=0;i<4;i++)
    {
        for(int l=1;l<=3;l++)
        {
            while(map[i][l] != 0 && map[i][l-1] == 0)
            {
                map[i][l-1] = map[i][l];
                map[i][l] = 0;
                if(l>1)
                    l--;
                move = 1;
            }
        }
    }
    for(int m=0;m<4;m++)  //2.合并相同
    {
        for(int n=0;n<3;n++)
        {
            if(map[m][n] != 0 && map[m][n+1] == map[m][n])
            {
                map[m][n] += map[m][n+1];
                score += map[m][n+1];
                map[m][n+1] = 0;
                move = 1;
            }
        }
    }
    for(int j=0;j<4;j++)  //再次填补空位
    {
        for(int k=1;k<=3;k++)
        {
            while(map[j][k] != 0 && map[j][k-1] == 0)
            {
                map[j][k-1] = map[j][k];
                map[j][k] = 0;
                if(k>1)
                    k--;
            }
        }
    }
}

void toBottom()  //向下移动
{
    for(int i=0;i<4;i++)
    {
        for(int l=2;l>=0;l--)
        {
            while(map[i][l] != 0 && map[i][l+1] == 0)
            {
                map[i][l+1] = map[i][l];
                map[i][l] = 0;
                if(l<2)
                    l++;
                move = 1;
            }
        }
    }
    for(int m=0;m<4;m++)
    {
        for(int n=3;n>=0;n--)
        {
            if(map[m][n] != 0 && map[m][n-1] == map[m][n])
            {
                map[m][n] += map[m][n-1];
                score += map[m][n-1];
                map[m][n-1] = 0;
                move = 1;
            }
        }
    }
    for(int j=0;j<4;j++)
    {
        for(int k=2;k>=0;k--)
        {
            while(map[j][k] != 0 && map[j][k+1] == 0)
            {
                map[j][k+1] = map[j][k];
                map[j][k] = 0;
                if(k<2)
                    k++;
            }
        }
    }
}

void toLeft()   //向左移动
{
    for(int i=1;i<4;i++)
    {
        for(int l=0;l<4;l++)
        {
            while(map[i][l] != 0 && map[i-1][l] == 0)
            {
                map[i-1][l] = map[i][l];
                map[i][l] = 0;
                if(i>1)
                    i--;
                move = 1;
            }
        }
    }
    for(int m=0;m<3;m++)
    {
        for(int n=0;n<4;n++)
        {
            if(map[m][n] != 0 && map[m+1][n] == map[m][n])
            {
                map[m][n] += map[m+1][n];
                score += map[m+1][n];
                map[m+1][n] = 0;
                move = 1;
            }
        }
    }
    for(int j=1;j<4;j++)
    {
        for(int k=0;k<4;k++)
        {
            while(map[j][k] != 0 && map[j-1][k] == 0)
            {
                map[j-1][k] = map[j][k];
                map[j][k] = 0;
                if(j>1)
                    j--;
            }
        }
    }
}

void toRight()   //向右移动
{
    for(int i=2;i>=0;i--)
    {
        for(int l=0;l<4;l++)
        {
            while(map[i][l] != 0 && map[i+1][l] == 0)
            {
                map[i+1][l] = map[i][l];
                map[i][l] = 0;
                if(i<2)
                    i++;
                move = 1;
            }
        }
    }
    for(int m=3;m>=0;m--)
    {
        for(int n=0;n<4;n++)
        {
            if(map[m][n] != 0 && map[m-1][n] == map[m][n])
            {
                map[m][n] += map[m-1][n];
                score += map[m-1][n];
                map[m-1][n] = 0;
                move = 1;
            }
        }
    }
    for(int j=2;j>=0;j--)
    {
        for(int k=0;k<4;k++)
        {
            while(map[j][k] != 0 && map[j+1][k] == 0)
            {
                map[j+1][k] = map[j][k];
                map[j][k] = 0;
                if(j<2)
                    j++;
            }
        }
    }
}

void changeMap()  //键盘监听,组装函数
{
    char key = getch();
    switch (key)
    {
        case 'w':
		case 'W':
            toTop();
            break;
        case 's':
		case 'S':
            toBottom();
            break;
        case 'a':
		case 'A':
            toLeft();
            break;
        case 'd':
		case 'D':
			toRight();
            break;
        default:
            break;
    }
    print();
    gameOver();
    if(move)  //方向可移动进行下一步
        newNumber();
}

void gameOver() //结束游戏(无法生成新数字)
{
    g = 0;
    for(int i=0;i<4;i++)
    {
        for(int l=0;l<4;l++)
        {
            if(map[i][l] == 0)
            {
                g = 1;
                break;
                break;
            }
        }
    }
}

因为算法比较暴力所以后期出新数字会慢,所以增加了一个finish来显示状态

发布了30 篇原创文章 · 获赞 27 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_44616044/article/details/89229141