IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 推箱子(C++类实现) -> 正文阅读

[C++知识库]推箱子(C++类实现)

直接上代码

#include <iostream>
#include <fstream>
#include <algorithm>

using namespace std;

// 从文件中获取数据
void readFile(char** buffer, int* size, const char* filename)
{
	//ifstream in(filename, ios::binary);
	ifstream in(filename);
	if (!in)
	{
		// 失败
		*buffer = NULL;
		*size = 0;
	}
	else
	{
		in.seekg(0, ifstream::end);	// 设置文件指针到末尾
		*size = static_cast<int>(in.tellg());	// 读取文件长度
		in.seekg(0, ifstream::beg);	// 设置文件指针到开头
		*buffer = new char[*size];	// 申请内存
		in.read(*buffer, *size);	// 读取文件内容
	}
}

// 二维数组类,采用模板类方式
template<class T> class Array2D
{
public:
	Array2D() : m_pArray(NULL) {}
	~Array2D() 
	{
		if (m_pArray)
		{
			delete[] m_pArray;
			m_pArray = NULL;
		}
	}

public:
	void setSize(int sizex, int sizey)
	{
		m_nSizeX = sizex;
		m_nSizeY = sizey;
		m_pArray = new T[sizex * sizey];
	}

	T& operator()(int indexX,int indexY)
	{
		return m_pArray[indexY * m_nSizeX + indexX];
	}
	
	const T& operator()(int indexX, int indexY) const 
	{
		return m_pArray[indexY * m_nSizeX + indexX];
	}

private:
	T* m_pArray;
	int m_nSizeX;
	int m_nSizeY;	
};

// 状态类
class State 
{
public:
	State(const char* stageData, int size);
	void update(char input);
	void draw() const;
	bool hasCleared() const;

private:
	void setSize(const char* stageData, int size);

private:
	enum Object
	{
		OBJ_SPACE,
		OBJ_WALL,
		OBJ_BLOCK,
		OBJ_MAN,
		
		OBJ_UNKNOWN,
	};

	int m_nWidth;
	int m_nHeight;
	Array2D<Object> m_Objects;
	Array2D<bool> m_GoalFlags;
};

State::State(const char* stageData, int size) 
{
	// 确保容量
	setSize(stageData, size);
	
	// 确保空间,object用的是枚举类型,也即是int类型,goalflags用的是char
	m_Objects.setSize(m_nWidth, m_nHeight);
	m_GoalFlags.setSize(m_nWidth, m_nHeight);

	// 预设初始值
	for (int y = 0; y < m_nHeight; ++y)
	{
		for (int x = 0; x < m_nWidth; ++x)
		{
			m_Objects(x, y) = OBJ_WALL;	// 多余部分都设置为墙壁
			m_GoalFlags(x, y) = false;	// 非终点
		}
	}

	int xPos = 0, yPos = 0;
	for (int i = 0; i < size; ++ i)
	{
		Object t;
		bool goalFalg = false;
		switch (stageData[i]) 
		{
		case '#': t = OBJ_WALL; break;
		case ' ': t = OBJ_SPACE; break;
		case 'o': t = OBJ_BLOCK; break;
		case 'O': t = OBJ_BLOCK; goalFalg = true; break;
		case '.': t = OBJ_SPACE; goalFalg = true; break;
		case 'p': t = OBJ_MAN; break;
		case 'P': t = OBJ_MAN; goalFalg = true; break;
		case '\n': xPos = 0; ++yPos; t = OBJ_UNKNOWN; break;
		default: t = OBJ_UNKNOWN; break;
		}

		if (t != OBJ_UNKNOWN)
		{
			m_Objects(xPos, yPos) = t;	// 写入
			m_GoalFlags(xPos, yPos) = goalFalg;	// 终点信息
			++xPos;
		}
	}
}

void State::setSize(const char* stageData, int size)
{
	m_nWidth = m_nHeight = 0;
	
	int xPos = 0, yPos = 0;
	
	for (int i = 0; i < size; i++)
	{
		switch (stageData[i])
		{
		case '#':
		case ' ':
		case 'o':
		case 'O':
		case 'p':
		case 'P':
			{
				++xPos;
				break;
			}
		case '\n':
			{
				++yPos;
				m_nWidth = max(m_nWidth, xPos);
				m_nHeight = max(m_nHeight, yPos);
				xPos = 0;
				break;
			}

		}
	}	
}

void State::draw() const 
{
	for ( int y = 0; y < m_nHeight; ++y)
	{
		for (int x = 0; x < m_nWidth; ++x)
		{
			Object o = m_Objects(x, y);
			bool goalFlag = m_GoalFlags(x, y);
			if (goalFlag) 
			{
				switch (o)
				{
				case OBJ_SPACE: cout << '.'; break;
				case OBJ_WALL: cout << '#'; break;
				case OBJ_BLOCK: cout << 'O'; break;
				case OBJ_MAN: cout << 'P'; break;
				}
			}
			else
			{
				switch (o)
				{
				case OBJ_SPACE: cout << ' '; break;
				case OBJ_WALL: cout << '#'; break;
				case OBJ_BLOCK: cout << 'o'; break;
				case OBJ_MAN: cout << 'p'; break;
				}
			}
		}
		cout << endl;
	}
}

void State::update(char input)
{
	int dx = 0, dy = 0;
	switch (input)
	{
	case 'a': dx = -1; break;
	case 's': dx = 1; break;
	case 'w': dy = -1; break;
	case 'z': dy = 1; break;
	}

	int width = m_nWidth;
	int height = m_nHeight;
	Array2D<Object>& o = m_Objects;

	// 查找小人坐标
	int x = 0, y = 0;
	bool found = false;
	for (y = 0; y < height; ++y)
	{
		for (x = 0; x < width; ++x)
		{
			if (o(x,y) == OBJ_MAN)
			{
				found = true;
				break;
			}
		}
		if (found)
			break;
	}

	// 移动后的坐标
	int xMov = x + dx;
	int yMov = y + dy;

	if (xMov < 0 || yMov < 0 || xMov > width || yMov > height)
		return ;


	if (o(xMov, yMov) == OBJ_SPACE)
	{
		o(xMov, yMov) = OBJ_MAN;
		o(x, y) = OBJ_SPACE;
	}
	else if (o(xMov, yMov) == OBJ_BLOCK)
	{
		int xMovNext = xMov + dx;
		int yMovNext = yMov + dy;
		if (xMovNext < 0 || yMovNext < 0 || xMovNext > width || yMovNext > height)
			return ;

		if (o(xMovNext, yMovNext) == OBJ_SPACE)
		{
			o(xMovNext, yMovNext) = OBJ_BLOCK;
			o(xMov, yMov) = OBJ_MAN;
			o(x, y) = OBJ_SPACE;
		}
	}
}

bool State::hasCleared() const 
{
	for (int y = 0; y < m_nHeight; ++y)
		for (int x = 0; x < m_nWidth; ++x)
			if (m_Objects(x, y) == OBJ_BLOCK && m_GoalFlags(x, y) == false)
				return false;

	return true;
}

int main(int argc, char** argv)
{
	const char* filename = "stageData.txt";
	if (argc >= 2)
	{
		filename = argv[1];
	}

	char* stageData;
	int fileSize;
	readFile(&stageData, &fileSize, filename);
	if (!stageData)
	{
		cout << "stage file could not be read." << endl;
		return 1;
	}

	State* state = new State(stageData, fileSize);

	// 主循环
	while (true)
	{
		state->draw();	// 绘制
		if (state->hasCleared())	// 通关检测 
			break;
		cout << "a:left s:right w:up z:down. command?" <<endl;
		char input;
		cin >> input;
		state->update(input);	// 刷新
	}

	cout << "Congratulation's! you won." << endl;
	delete[] stageData;
	stageData = 0;

	system("pause");
	return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-16 21:55:40  更:2021-07-16 21:56:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/28 12:33:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码