小游戏:2048 代码(乱)

本文详细介绍了一款基于curses库的2048游戏的实现过程,包括游戏逻辑、界面绘制、键盘输入处理等核心模块。游戏使用C++语言编写,通过旋转和平移矩阵来实现游戏的核心玩法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <string>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <ctime>
#include <curses.h>
#define width 5
#define n 4
#define Gnormal 0
#define Gwin 1
#define Glose 2
#define Gquit 3
using namespace std;

class game2048
{
public:
	game2048() :status(Gnormal) {
		setdata();
	}

	int getstatus()
	{
		return status;
	}

	void iprocess()
	{
		char ch = getch();
		if ('a' <= ch&&ch <= 'z')
		{
			ch -= 32;
		}
		if(status==Gnormal)
		{ 
			if (ch == 'A')
			{
				moveleft();
			}
			else if (ch == 'W')
			{
				rotate();
				moveleft();
				rotate();
				rotate();
				rotate();
			}
			else if (ch == 'D')
			{
				rotate();
				rotate();
				moveleft();
				rotate();
				rotate();
			}
			else if (ch == 'S')
			{
				rotate();
				rotate();
				rotate();
				moveleft();
				rotate();
			}
			if (!ifwin())
			{
				if (!randnew())
					status = Glose;
				randnew();
			}
		}
		if (ch == 'Q')
		{
			status = Gquit;
		}
		else if (ch == 'R')
		{
			restart();
		}
	}

	void draw()
	{
		clear();
		const int offset = 12;
		for (int i = 0; i <= n; i++)
			for (int j = 0; j <= n; j++)
				drawitem(i * 2, offset + j*width, '+');
		for (int i = 0; i < n; i++)
			for (int j = 0; j <= n; j++)
				drawitem(1 + i * 2, offset + j*width, '|');
		for (int i = 0; i <= n; i++)
			for (int j = 0; j < n; j++)
				for (int k = 1; k < 5; k++)
					drawitem(2 * i, offset + k + j*width, '-');
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				drawnum(i * 2 + 1, j*width + 4 + offset, data[i][j]);
		mvprintw(2 * n + 2, offset / 2, "W(UP),S(DOWN),A(LEFT),D(RIGHT),R(RESTART),Q(QUIT)");
		mvprintw(2 * n + 3, offset + 10, "my first game");
		if (status == Gwin) {
			mvprintw(n, offset, " YOU WIN,PRESS R TO CONTINUE ");
		}
		else if (status == Glose) {
			mvprintw(n, offset, " YOU LOSE,PRESS R TO CONTINUE ");
		}
	}
	void setdata()
	{
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				data[i][j] = 16 << i << j;
	}
	void drawitem(int row, int col, char ch)
	{
		move(row, col);
		addch(ch);
	}
	void drawnum(int row, int col, int num)
	{
		while (num != 0)
		{
			move(row, col--);
			addch(num % 10 + '0');
			num /= 10;
		}
	}
	void restart()
	{
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				data[i][j] = 0;
		randnew();
		randnew();
		status = Gnormal;
	}
	bool randnew()
	{
		vector<int> emptyxy;
		for (int i = 0; i<n; i++)
			for (int j = 0; j < n; j++)
			{
				if (data[i][j] == 0)
					emptyxy.push_back(i*n + j);
			}
		if (emptyxy.size() == 0)
			return false;
		int value = emptyxy[rand() % emptyxy.size()];
		data[value / n][value%n] = rand() % 10 == 1 ? 4 : 2;
		return true;
	}

	void moveleft()
	{
		int pvalue = 0;
		int cpos = 0;
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < n; j++)
			{
				if (data[i][j] == 0)
				{
					continue;
				}
				else
				{
					if (pvalue == 0)
					{
						pvalue = data[i][j];
						data[i][j] = 0;
					}
					else
					{
						if (pvalue == data[i][j])
						{
							data[i][cpos] = pvalue * 2;
							++cpos;
							pvalue = 0;
							data[i][j] = 0;
						}
						else
						{
							data[i][cpos] = pvalue;
							pvalue = data[i][j];
							data[i][j] = 0;
							++cpos;
						}
					}
				}
			}
			if (pvalue != 0)
				data[i][cpos] = pvalue;
			cpos = 0;
			pvalue = 0;
		}
	}

	bool ifwin()
	{
		bool res = false;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
			{
				if (data[i][j] == 1024)
				{
					res = true;
					status = Gwin;
				}
			}
		return res;
	}

	void rotate()
	{
		int tmp[n][n] = { 0 };
		for (int i = 0; i < n; ++i)
			for (int j = 0; j < n; ++j)
				tmp[i][j] = data[j][n-i-1];
		for (int i = 0; i < n; ++i)
			for (int j = 0; j < n; ++j)
				data[i][j] = tmp[i][j];
	}

private:
	int data[n][n];
	int status;
};


void initialize()
{
	initscr();
	cbreak();
	noecho();
	curs_set(0);
	srand(time(NULL));
}

void shutdown()
{
	endwin();
}

int main() {
	initialize();
	game2048 game;
	do {
		game.draw();
		game.iprocess();
	} while (Gquit != game.getstatus());
	shutdown();
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值