欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C++ 和 EasyX 图形库,实现2048小游戏

程序员文章站 2024-03-18 14:54:16
...

C++ 和 EasyX 图形库,实现2048小游戏

C++ 和 EasyX 图形库,实现2048小游戏

MainGame2048.cpp

/** Name: Game2048CoreClass*/
#include<iostream>
#include<graphics.h>
#include<stdio.h>
#include<windows.h>
#include<conio.h>
#include<stdio.h>
#include"Game2048.h"
#define BLOCK_SIZE 60
#define SIZE_COL 10
#define SIZE_ROW 10
using namespace std;
void DisplayMap(Game2048& mygame);
int GetMove();
int main(int argc, char * argv[])
{
	HWND hwnd=initgraph(SIZE_COL*BLOCK_SIZE, SIZE_ROW*BLOCK_SIZE);
	setbkmode(TRANSPARENT);
	setbkcolor(RGB(180,180,180));
	settextcolor(RGB(0,180,80));
	cleardevice();
	while (1)
	{
		Game2048 mygame(SIZE_ROW, SIZE_COL);
		while (1)
		{
			DisplayMap(mygame);
			int mov = GetMove();
			cout << mov << endl;
			if (!mygame.Run(mov))
				break;
		}
		if (MessageBox(hwnd, "游戏结束,是否重玩?", "Tips", MB_YESNO) == IDNO)
			break;
	}
	
	return 0;
}
int GetMove()
{
	char move = '\0';
	move = getch();
	if (move == 'w' || move == '8' || move == 'W')
		return MOV_UP;
	if (move == 's' || move == '5' || move == 'S')
		return MOV_DOWN;
	if (move == 'a' || move == '4' || move == 'A')
		return MOV_LEFT;
	if (move == 'd' || move == '6' || move == 'D')
		return MOV_RIGHT;
	if (move == '*')
		return MOV_NULL;
	return 0;
}
void DisplayMap(Game2048& mygame)
{
	BeginBatchDraw();
	cleardevice();
	char temp[20] = { 0 };
	system("cls");
	cout << mygame.GetScore() << " " << mygame.GetStep() << " " << mygame.GetUsedTime()<<" " << mygame.GetMaxNum() << endl;
	for (int i = 0; i<mygame.GetLines(); i++)
	{
		for (int j = 0; j<mygame.GetCols(); j++)
		{
			cout.width(4);
			cout << mygame.MapAt(i,j);
			if (mygame.MapAt(i, j) == 0)
			{
				setfillcolor(RGB(220,220,220));
				solidcircle(j*BLOCK_SIZE + BLOCK_SIZE / 2, i*BLOCK_SIZE + BLOCK_SIZE / 2, BLOCK_SIZE / 2);
			}
			else
			{
				int size=mygame.MapAt(i, j);
				sprintf(temp, "%d\0",size );
				size /= 2;
				setfillcolor(RGB(200, 255-size*20, 0+size*20));
				solidcircle(j*BLOCK_SIZE + BLOCK_SIZE / 2, i*BLOCK_SIZE + BLOCK_SIZE / 2, BLOCK_SIZE / 2);
				outtextxy(j*BLOCK_SIZE, i*BLOCK_SIZE,temp);
			}

		}
		printf("\n");
	}
	cout << "-------" << endl;
	sprintf(temp,"Score : %d\0",mygame.GetScore());
	outtextxy(0, 1*BLOCK_SIZE/3, temp);
	sprintf(temp, "Step : %d\0", mygame.GetStep());
	outtextxy(0, 2 * BLOCK_SIZE / 3, temp);
	sprintf(temp, "Time : %d\0", mygame.GetUsedTime());
	outtextxy(0, 3 * BLOCK_SIZE / 3, temp);
	sprintf(temp, "MAX : %d\0", mygame.GetMaxNum());
	outtextxy(0, 4 * BLOCK_SIZE / 3, temp);
	EndBatchDraw();
}

Game2048.h

#ifndef _GAME2048_H_
#define _GAME2048_H_
/*For example:
Game2048 mygame(10,10);
int main(int argc, char * argv[])
{
	while (1)
	{
		DisplayMap();
		int mov = GetMove();
		cout << mov << endl;
		if (!mygame.Run(mov))
			break;
}
system("pause");
return 0;
}
*/
#include<stdlib.h>
#include<time.h>
typedef int MoveDirect;
#define MOV_NULL 0
#define MOV_UP 8
#define MOV_DOWN 5
#define MOV_LEFT 4
#define MOV_RIGHT 6
class Game2048
{
public:
    Game2048(int line=5,int col=5);
    ~Game2048();
	bool Run(MoveDirect mov);
	int GetCols();
	int GetLines();
	int MapAt(int rindex, int cindex);//return >=0 is true,-1 is bad index,0 mean space,other mean number.
	int GetStep();
	int GetScore();
	int GetUsedTime();
	int GetMaxNum();
	void clear();
private:
	void CreateNew();
	void MoveAndResult(MoveDirect mov);
	bool IsDead();
    //运行图和运行时环境
	int * Map;
	int lines;
	int cols;
    int step;
    int core;
    long runtime;
    int usetime;
    int maxnum;

};

#endif // _GAME2048_H_

Game2048.cpp

#include"Game2048.h"
Game2048::Game2048(int line,int col)
{
	this->lines = line;
	this->cols = col;
    this->step=0;
    this->core=0;
    this->runtime=0;
    this->usetime=0;
    this->maxnum=2;
    this->Map=(int *)malloc(sizeof(int)*(this->lines)*(this->cols));
	runtime = time(NULL);     //记录开始时间,用于算总时长
	srand((unsigned)time(NULL));
	for (int i = 0; i<this->lines; i++)
	{
		for (int j = 0; j<this->cols; j++)
		{
			Map[i*this->cols+j] = 0;
		}
	}
	CreateNew();
}
Game2048::~Game2048()
{
	free(this->Map);
}
void Game2048::clear()
{
	this->step = 0;
	this->core = 0;
	this->runtime = 0;
	this->usetime = 0;
	this->maxnum = 2;
	runtime = time(NULL);     //记录开始时间,用于算总时长
	srand((unsigned)time(NULL));
	for (int i = 0; i<this->lines; i++)
	{
		for (int j = 0; j<this->cols; j++)
		{
			Map[i*this->cols + j] = 0;
		}
	}
	CreateNew();
}
bool Game2048::Run(MoveDirect mov)
{
	CreateNew();
	MoveAndResult(mov);
	if (step > (lines*cols * 2))
	if (IsDead() == 1)
		return false;
	usetime = time(NULL) - runtime;
	return true;
}
int Game2048::GetCols()
{
	return this->cols;
}
int Game2048::GetLines()
{
	return this->lines;
}
int Game2048::MapAt(int rindex, int cindex)
{
	if (rindex<0||cindex<0||rindex >= this->lines || cindex >= this->cols)
		return -1;
	return Map[rindex*this->cols+cindex];
}
int Game2048::GetStep()
{
	return this->step;
}
int Game2048::GetScore()
{
	return this->core;
}
int Game2048::GetUsedTime()
{
	return this->usetime;
}
int Game2048::GetMaxNum()
{
	return this->maxnum;
}
void Game2048::CreateNew()
{
	int hasfull = 1;
	for (int i = 0; i<lines; i++)
	{
		for (int j = 0; j<cols; j++)
		{
			if (Map[i*this->cols+j] == 0)
				hasfull = 0;      //判断是否满了,不满才创建
		}
	}
	if (hasfull == 1)
		return;
	int si, sj;
	si = rand() % lines;
	sj = rand() % cols;
	while (Map[si*this->cols+sj] != 0)
	{
		si = rand() % lines;
		sj = rand() % cols;
	}
	Map[si*this->cols+sj] = 2;
}
bool Game2048::IsDead()
{
	for (int i = 0; i<lines; i++)
	{
		for (int j = 0; j<cols; j++)
		{
			if (Map[i*this->lines + j] == 0)
				return false;       //如果存在空的格则肯定不结束
			int up, down, right, left;
			up = i - 1;
			down = i + 1;
			right = j + 1;
			left = j - 1;       //四个方向进行判定
			while (up >= 0 && Map[up*this->lines + j] == 0)
				up--;
			if (Map[up*this->lines + j] == Map[i*this->lines + j] && up != -1)       //只要一个方向可以合并则不结束
				return false;
			while (down<lines&&Map[down*this->lines + j] == 0)
				down--;
			if (Map[down*this->lines + j] == Map[i*this->lines + j] && down != lines)
				return false;
			while (right<cols&&Map[i*this->lines + right] == 0)
				right++;
			if (Map[i*this->lines + right] == Map[i*this->lines + j] && right != cols)
				return false;
			while (left >= 0 && Map[i*this->lines + left] == 0)
				left--;
			if (Map[i*this->lines + left] == Map[i*this->lines + j] && left != -1)
				return false;
		}
	}
	return true;       //排除所有情况不结束,肯定结束了
}
void Game2048::MoveAndResult(MoveDirect mov)
{
	if (mov == MOV_NULL)
		return;
	step++;     //步数增加
	int ffind, nfind;
	if (mov == MOV_UP)
	{
		for (int i = 0; i<cols; i++)
		{
			ffind = -1;
			nfind = -1;
			for (int j = 0; j<lines; j++)
			{
				int k = j;
				while (k<lines&&Map[k*this->cols+i] == 0)
					k++;
				if (k != lines)
					ffind = k;
				k++;
				while (k<lines&&Map[k*this->lines + i] == 0)
					k++;
				if (k != lines)
					nfind = k;     //获取第一个不为零和下一个不为零
				if (ffind != -1 && nfind != -1)
				{
					if (ffind != nfind)
					{
						if (Map[ffind*this->lines + i] == Map[nfind*this->lines + i])        //两个获取相等则叠加
						{
							Map[ffind*this->lines + i] *= 2;
							if (Map[ffind*this->lines + i]>maxnum)
								maxnum = Map[ffind*this->lines + i];
							Map[nfind*this->lines + i] = 0;
							core++;         //分数增加
						}
					}
				}

			}
			int count = 0;
			for (int j = 0; j<lines; j++)      //单边对齐
			{
				if (Map[j*this->lines + i] != 0)
				{
					int temp = Map[j*this->lines + i];
					Map[j*this->lines + i] = 0;
					Map[count*this->lines + i] = temp;
					count++;
				}

			}

		}
	}
	else if (mov == MOV_DOWN)
	{
		for (int i = 0; i<cols; i++)
		{
			ffind = -1;
			nfind = -1;
			for (int j = lines; j >= 0; j--)
			{
				int k = j;
				while (k >= 0 && Map[k*this->cols+i] == 0)
					k--;
				if (k != -1)
					ffind = k;
				k--;
				while (k >= 0 && Map[k*this->cols+i] == 0)
					k--;
				if (k != -1)
					nfind = k;
				if (ffind != -1 && nfind != -1)
				{
					if (ffind != nfind)
					{
						if (Map[ffind*this->cols+i] == Map[nfind*this->cols+i])
						{
							Map[ffind*this->cols+i] *= 2;
							if (Map[ffind*this->cols+i]>maxnum)
								maxnum = Map[ffind*this->cols+i];
							Map[nfind*this->cols+i] = 0;
							core++;
						}
					}
				}

			}
			int count = lines - 1;
			for (int j = lines - 1; j >= 0; j--)
			{
				if (Map[j*this->cols+i] != 0)
				{
					int temp = Map[j*this->cols+i];
					Map[j*this->cols+i] = 0;
					Map[count*this->cols+i] = temp;
					count--;
				}

			}
		}
	}
	else if (mov == MOV_LEFT)
	{
		for (int i = 0; i<lines; i++)
		{
			ffind = -1;
			nfind = -1;
			for (int j = 0; j<cols; j++)
			{
				int k = j;
				while (k<cols&&Map[i*this->cols+k] == 0)
					k++;
				if (k != cols)
					ffind = k;
				k++;
				while (k<cols&&Map[i*this->cols+k] == 0)
					k++;
				if (k != cols)
					nfind = k;
				if (ffind != -1 && nfind != -1)
				{
					if (ffind != nfind)
					{
						if (Map[i*this->cols+ffind] == Map[i*this->cols+nfind])
						{
							Map[i*this->cols+ffind] *= 2;
							if (Map[i*this->cols+ffind]>maxnum)
								maxnum = Map[i*this->cols+ffind];
							Map[i*this->cols+nfind] = 0;
							core++;
						}
					}
				}

			}
			int count = 0;
			for (int j = 0; j<cols; j++)
			{
				if (Map[i*this->cols+j] != 0)
				{
					int temp = Map[i*this->cols+j];
					Map[i*this->cols+j] = 0;
					Map[i*this->cols+count] = temp;
					count++;
				}

			}
		}
	}
	else if (mov == MOV_RIGHT)
	{
		for (int i = 0; i<lines; i++)
		{
			ffind = -1;
			nfind = -1;
			for (int j = cols; j >= 0; j--)
			{
				int k = j;
				while (k >= 0 && Map[i*this->cols+k] == 0)
					k--;
				if (k != -1)
					ffind = k;
				k--;
				while (k >= 0 && Map[i*this->cols+k] == 0)
					k--;
				if (k != -1)
					nfind = k;
				if (ffind != -1 && nfind != -1)
				{
					if (ffind != nfind)
					{
						if (Map[i*this->cols+ffind] == Map[i*this->cols+nfind])
						{
							Map[i*this->cols+ffind] *= 2;
							if (Map[i*this->cols+ffind]>maxnum)
								maxnum = Map[i*this->cols+ffind];
							Map[i*this->cols+nfind] = 0;
							core++;
						}
					}
				}

			}
			int count = cols - 1;
			for (int j = cols - 1; j >= 0; j--)
			{
				if (Map[i*this->cols+j] != 0)
				{
					int temp = Map[i*this->cols+j];
					Map[i*this->cols+j] = 0;
					Map[i*this->cols+count] = temp;
					count--;
				}

			}
		}
	}
}