C++基于EasyX图形库实现2048小游戏

 更新时间:2020年02月28日 13:20:45   作者:Ugex  
这篇文章主要为大家详细介绍了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--;
 }

 }
 }
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C++ vector的介绍及常见功能实现

    C++ vector的介绍及常见功能实现

    这篇文章主要介绍了C++ vector的介绍及模拟实现,vector在实际中非常的重要,但在实际中我们只要熟悉常见的接口就可以了,最重要的是理解他的底层原理,要能够自己模拟实现出一个简单的vector,本文结合示例代码给大家详细介绍,需要的朋友可以参考下
    2023-05-05
  • C++编程中的格式化输出详解

    C++编程中的格式化输出详解

    这篇文章主要介绍了C++编程中的格式化输出详解,是C++入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • VS Code 中搭建 Qt 开发环境方案分享

    VS Code 中搭建 Qt 开发环境方案分享

    这篇文章主要介绍了VS Code 中搭建 Qt 开发环境方案分享的相关资料,需要的朋友可以参考下
    2022-12-12
  • C语言中socket相关网络编程函数小结

    C语言中socket相关网络编程函数小结

    这篇文章主要介绍了C语言中socket相关网络编程函数小结,是C语言入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • C++无痛实现日期类的示例代码

    C++无痛实现日期类的示例代码

    凡是要写类必须要提到六大默认成员(六位大爷):构造函数、析构函数、拷贝构造函数、赋值重载函数、取地址重载函数(包括const对象和普通对象);那么这次的日期类又需要伺候哪几位大爷呢?本文就来详细说说
    2022-10-10
  • C语言实现影院管理系统

    C语言实现影院管理系统

    这篇文章主要为大家详细介绍了C语言实现影院管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-12-12
  • C语言中的内存管理详情

    C语言中的内存管理详情

    这篇文章主要介绍了C语言中的内存管理详情,手工申请内存使用malloc展开全文内容,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-05-05
  • C语言代码实现三子棋游戏

    C语言代码实现三子棋游戏

    这篇文章主要为大家详细介绍了C语言代码实现三子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-11-11
  • C++日期与时间 chrono库介绍及使用教程

    C++日期与时间 chrono库介绍及使用教程

    chrono库是C++11中的一个标准库,它提供了一系列与时间相关的类和函数,用于表示和处理时间间隔,时钟和时间点,C++20新增Calendar,这篇文章主要介绍了C++日期与时间 chrono库介绍及使用,需要的朋友可以参考下
    2023-12-12
  • C++改变编程入口为main函数

    C++改变编程入口为main函数

    这篇文章主要介绍了C++改变编程入口为main函数的方法的相关资料,需要的朋友可以参考下
    2015-06-06

最新评论