// 项目：纸牌上的坦克大战 - SDL2 Linux Port
#include <iostream>
#include <ctime>
#include <random>
#include <string>
#include <unordered_map>
#include <unistd.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_mixer.h>
#include <SDL2/SDL_ttf.h>

// 引入 data_config 等头文件
#include "data_config.h"
// #include "map.h"	// 引入预设地图头文件
// #include "main.h"	// 引入函数声明头文件

using namespace std;

// -------- 全局变量定义 ---------
int map[MAP_CELL_NUM][MAP_CELL_NUM]; //用map.h预置
int kill = 5;						//玩家击杀数
tank player;					//玩家
tank enemies[ENEMIES_NUM];      //敌人
bullet E_bullets[BULLET_NUM * ENEMIES_NUM];	//敌方坦克子弹数量
bullet P_bullets[BULLET_NUM];  //玩家子弹数量
tank enemy;						// 用于修改敌人的属性，难度设置时用到

// -------- SDL2 全局变量 --------
SDL_Window* g_window = NULL;
SDL_Renderer* g_renderer = NULL;
TTF_Font* g_font = NULL;
Mix_Music* g_bgm = NULL;

// -------- 辅助函数 --------

// 加载纹理（带缩放）
SDL_Texture* load_texture(const char* path) {
    static unordered_map<string, SDL_Texture*> tex_cache;
    string key(path);
    auto it = tex_cache.find(key);
    if (it != tex_cache.end()) {
        return it->second;
    }
    SDL_Surface* surf = IMG_Load(path);
    if (!surf) {
        fprintf(stderr, "IMG_Load error: %s - %s\n", path, IMG_GetError());
        return NULL;
    }
    SDL_Texture* tex = SDL_CreateTextureFromSurface(g_renderer, surf);
    SDL_FreeSurface(surf);
    if (tex) {
        SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND);
    } else {
        fprintf(stderr, "CreateTexture error: %s - %s\n", path, SDL_GetError());
    }
    tex_cache[key] = tex;
    return tex;
}

// 渲染纹理到指定位置和大小
void render_texture(SDL_Texture* tex, int x, int y, int w, int h) {
    if (!tex) return;
    SDL_Rect dst = {x, y, w, h};
    SDL_RenderCopy(g_renderer, tex, NULL, &dst);
}

// 渲染纹理到指定位置（不缩放，使用纹理原始大小）
void render_texture_raw(SDL_Texture* tex, int x, int y) {
    if (!tex) return;
    int w, h;
    SDL_QueryTexture(tex, NULL, NULL, &w, &h);
    SDL_Rect dst = {x, y, w, h};
    SDL_RenderCopy(g_renderer, tex, NULL, &dst);
}

// 带缩放加载并渲染纹理（一次性操作）
void draw_image(const char* path, int x, int y, int w, int h) {
    SDL_Texture* tex = load_texture(path);
    render_texture(tex, x, y, w, h);
}

// 渲染文本
void render_text(const char* text, int x, int y, SDL_Color color) {
    if (!g_font || !text) return;
    SDL_Surface* surf = TTF_RenderUTF8_Blended(g_font, text, color);
    if (!surf) return;
    SDL_Texture* tex = SDL_CreateTextureFromSurface(g_renderer, surf);
    if (tex) {
        SDL_Rect dst = {x, y, surf->w, surf->h};
        SDL_RenderCopy(g_renderer, tex, NULL, &dst);
        SDL_DestroyTexture(tex);
    }
    SDL_FreeSurface(surf);
}

// 渲染int数值为文本
void render_int(int value, int x, int y, SDL_Color color) {
    string s = to_string(value);
    render_text(s.c_str(), x, y, color);
}

// 清屏
void clear_screen() {
    SDL_SetRenderDrawColor(g_renderer, 0, 0, 0, 255);
    SDL_RenderClear(g_renderer);
}

// 更新画面
void present_screen() {
    SDL_RenderPresent(g_renderer);
}

// 事件处理辅助：等待并处理键盘和鼠标事件，返回是否退出 / 转到菜单
// 返回: 0=继续循环, -1=退出/返回菜单
int handle_menu_events(bool& goto_menu) {
    SDL_Event e;
    while (SDL_PollEvent(&e)) {
        if (e.type == SDL_QUIT) {
            exit(0);
        }
        if (e.type == SDL_KEYDOWN) {
            if (e.key.keysym.sym == SDLK_ESCAPE) {
                goto_menu = true;
                return -1;
            }
        }
        if (e.type == SDL_MOUSEBUTTONDOWN) {
            return 1; // 鼠标点击发生，调用者需检查坐标
        }
    }
    return 0;
}

// -------- 原函数声明（保持不变） --------
void EnemyBulletMove();
void PlayerBulletMove();
int BulletMoveCheck(int dir, bullet bul);
void change();
void EnemiesMove();
void EnemyInit();
void EnemyShoot();
void GameView();
void GameView_ShowBullet();
void GameView_ShowLose();
void GameView_ShowMap();
void GameView_ShowTank();
void GameView_ShowWIN();
void InitMap();
// void InitMap(const int preset_map[50][50]);
bool IsWin();
void Level();
void MemberView();
void MenuView();
void Move();
void PlayerInit();
void PlayerMove();
void PlayerShoot();
int TankMoveCheck(int dir, tank tank);
void Update();

// git 提交

/*
	菜单界面：
	展示开始游戏，难度设置，退出等选项
	用户通过w/s来选择对应的按钮，回车进行选择

		开始游戏：
		当选中开始游戏时，跳转游戏主函数，直接进入游戏。

		难度设置：
		当选中难度设置时，跳转难度选择函数，进行对敌方坦克血量以及攻击力进行变化等操作。
		调整完毕之后需要esc返回菜单然后才可以进入游戏。

		退出游戏：
		当选中退出时，直接退出程序。

		关于开发人员
		跳转相关信息页面，展示开发人员信息

		// 游戏进行中的开始页面

游戏过程
	展示地图和坦克，玩家控制己方坦克进行自动移动和开火
	操作wsad控制己方坦克进行上下左右移动
	按下空格控制己方向前发射子弹
	撞到墙，掉血
	当杀死所有敌方坦克时，游戏胜利,返回主菜单

	暂停界面
	展示继续游戏、退出游戏按钮，同时游戏暂停
*/

/*
	功能模块
		1.菜单界面
		2.菜单界面转到游戏界面
		3.游戏界面转到暂停界面
		4.暂停界面转到菜单界面
*/

//-----------------view------------------------
/*
	功能描述：
	功能：展示开始游戏，难度设置，退出等选项, 关于我们
		开始游戏：
			当选中开始游戏时，跳转游戏主函数，直接进入游戏。
		难度设置：
			当选中难度设置时，跳转难度选择函数，进行对敌方坦克血量以及攻击力进行变化等操作。
			调整完毕之后需要esc返回菜单然后才可以进入游戏。
		退出游戏：
			当选中退出时，直接退出程序。
		关于我们：
			展示团队信息
		// 游戏进行中的开始页面
*/
void MenuView();

/*
* 游戏界面
	功能描述：
*/
// 每一帧，地图和坦克每一帧状态渲染
// 在一个新的地图上进行操作，包括坦克和子弹的坐标：位置和方向
void GameView()   //游戏主界面视图
{
	InitMap();  //初始化地图
	// InitMap(map1);  //初始化地图
	EnemyInit();  //初始化敌方坦克的位置
	PlayerInit(); //初始化己方坦克的位置

	// 初始渲染
	clear_screen();
	GameView_ShowMap(); //显示地图
	GameView_ShowTank(); //显示坦克
	present_screen();

	while (!IsWin())  // 游戏循环没有胜利
	{
		if (player.hp <= 0)    //判断玩家的生命值是否小于或等于 0
		{
			GameView_ShowLose(); //调用 failView 函数显示失败视图
			/*MenuView();*/   //返回主菜单界面
			break;
		}

		// 处理ESC和窗口事件
		SDL_Event e;
		while (SDL_PollEvent(&e)) {
			if (e.type == SDL_QUIT) {
				exit(0);
			}
			if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE) {
				MenuView();  //调用菜单 menuView 函数返回主菜单界面
			}
		}

		Move(); // 调用 Move、Shoot 和 Update 函数：这些函数需要实现坦克和子弹的移动、射击和状态更新。
		//射击
		const Uint8* keys = SDL_GetKeyboardState(NULL);
		if (keys[SDL_SCANCODE_SPACE])
			PlayerShoot();
		EnemyShoot();
		// Update();
		Update();
		
		// 渲染帧
		clear_screen();
		GameView_ShowMap(); //显示地图的最新状态
		GameView_ShowBullet(); //再进行子弹显示更新状态
		GameView_ShowTank(); //显示坦克的最新状态
		present_screen();
		
		SDL_Delay(16); // ~60 FPS，控制帧率
	}

	if (IsWin())  //如果游戏胜利，调用 winView 函数显示胜利界面，并返回主菜单界面。
	{
		GameView_ShowWIN();
		/*MenuView();*/
	}
}

/*
	创建者:桃仁和毛血旺
	功能
	用来判断玩家子弹是否到达上限，0-3跳过直接返回0-3并找到第一个is_live == false,break
	射击模块：子弹初始化发射
*/
void PlayerShoot()
{
	static clock_t start = clock() - 500;
	if ((clock() - start) < 500)
		return;
	start = clock();
	for (int i = 0; i < SINGLE_BULLET; i++)
	{
		if (P_bullets[i].is_live == false)
		{
			//初始化子弹
			P_bullets[i].x = player.x;
			P_bullets[i].y = player.y;
			P_bullets[i].dir = player.dir;
			P_bullets[i].damage = player.attack;
			P_bullets[i].is_live = true;
			break;
		}
	}
}

/*
	创建者:桃仁和毛血旺
	输入：敌人结构体数组
	敌人发射子弹自动射击,由敌方坦克
	先通过随机数判断是否要发射，随机数%2,返回0或1
	if 要发射 则循环子弹数组
*/
void EnemyShoot()
{
	static clock_t start = clock() - 3000;
	if ((clock() - start) < 3000)
		return;
	start = clock();
	for (int i = 0; i < ENEMIES_NUM; i++)  //遍历所有敌方坦克
	{
		if (enemies[i].hp > 0) {
			for (auto& j : E_bullets)
			{
				if (j.is_live == false) //只要一个子弹不存活，发射，否则若都已经存在，则不发射子弹
				{
					j.x = enemies[i].x;
					j.y = enemies[i].y;
					j.dir = enemies[i].dir;
					j.damage = enemy.attack;
					j.is_live = true;
					break;
				}
			}
		}
	}
}

/*
	创建者:桃仁和毛血旺
	功能：
		调用移动函数，子弹移动函数和碰撞检测等
*/
void Move()
{
	bool move = false;
	const Uint8* keys = SDL_GetKeyboardState(NULL);
	if (keys[SDL_SCANCODE_W] || keys[SDL_SCANCODE_UP])
	{
		player.dir = UP;
		move = true;
	}
	else if (keys[SDL_SCANCODE_S] || keys[SDL_SCANCODE_DOWN])
	{
		player.dir = DOWN;
		move = true;
	}
	else if (keys[SDL_SCANCODE_A] || keys[SDL_SCANCODE_LEFT])
	{
		player.dir = LEFT;
		move = true;
	}
	else if (keys[SDL_SCANCODE_D] || keys[SDL_SCANCODE_RIGHT])
	{
		player.dir = RIGHT;
		move = true;
	};//设置方向



	if (move) {
		PlayerMove();   //player.dir 是全局变量所以能调用
	}
	EnemiesMove();  //敌人移动函数
	PlayerBulletMove();
	EnemyBulletMove();
}

///*
//* 判断我方坦克前方是否为空地
//*/
//bool PlayerCollision();


/*
	创建者：小 yang
	功能：
		根据map数组生成地图
*/
void GameView_ShowMap()	// 坦克是全局的，不需要传参
//void GameView_ShowMap(tank player)
{
	//绘制背景
	draw_image("images/游戏主界面背景.jpg", 0, 0, 700, 700);

	//红色方HP渲染
	SDL_Texture* hp_tex = load_texture("images/red_hp_bar.jpg");
	for (int i = 0; i < player.hp; i++)
	{
		render_texture(hp_tex, 100 + i * 30, 10, CELL_SIZE, CELL_SIZE);
	}

	////蓝色方HP渲染
	//for (int j = 0; j < player.hp; j++)
	//{
	//	putimage(570 - j * 30, 120, &image_RED_HP);
	//}

	int dieNum = 0;
	for (auto& i : enemies) {
		if (i.hp <= 0) dieNum++;
	}
	
	//文本渲染杀敌数
	SDL_Color text_color = {157, 157, 157, 255};
	render_text("杀敌：", 110, 660, text_color);
	render_int(dieNum, 185, 660, text_color);
	render_text("/", 210, 660, text_color);
	render_text("10", 225, 660, text_color);

	//当前攻击力
	string atk_str = "当前攻击力" + to_string(player.attack);
	render_text(atk_str.c_str(), 325, 660, text_color);

	//墙壁纹理渲染
	SDL_Texture* wall_tex = load_texture("images/wall.jpg");
	for (int i = 0; i < MAP_CELL_NUM; i++)
	{
		for (int j = 0; j < MAP_CELL_NUM; j++)
		{
			if (map[i][j] == WALL)
			{
				render_texture(wall_tex, j * CELL_SIZE + X_OFFSET, i * CELL_SIZE + Y_OFFSET, CELL_SIZE, CELL_SIZE);
			}
		}
	}
}


/*
	创建者：
	功能：渲染子弹到地图
*/
// void GameView_ShowBullet();
// void GameView_ShowBullet(bullet b);

/*
	创建者：小 yang
	功能：渲染坦克到地图

*/
void GameView_ShowTank()
// void GameView_ShowTank(tank player, tank enemies[])
{
	//我方坦克纹理
	SDL_Texture* red_up = load_texture("images/red_up_b.png");
	SDL_Texture* red_down = load_texture("images/red_down_b.png");
	SDL_Texture* red_left = load_texture("images/red_left_b.png");
	SDL_Texture* red_right = load_texture("images/red_right_b.png");

	//敌方坦克纹理
	SDL_Texture* blue_up = load_texture("images/blue_up_b.png");
	SDL_Texture* blue_down = load_texture("images/blue_down_b.png");
	SDL_Texture* blue_left = load_texture("images/blue_left_b.png");
	SDL_Texture* blue_right = load_texture("images/blue_right_b.png");

	//死亡坦克纹理
	SDL_Texture* dead_tank = load_texture("images/dead_tank_b.png");

	//渲染地图元素
	for (int i = 0; i < MAP_CELL_NUM; i++)
	{
		for (int j = 0; j < MAP_CELL_NUM; j++)
		{
			if (map[i][j] == RED_TANK && player.dir == LEFT)
			{
				render_texture(red_left, player.x * CELL_SIZE + X_OFFSET, player.y * CELL_SIZE + Y_OFFSET, CELL_SIZE, CELL_SIZE);
			}

			if (map[i][j] == RED_TANK && player.dir == RIGHT)
			{
				render_texture(red_right, player.x * CELL_SIZE + X_OFFSET, player.y * CELL_SIZE + Y_OFFSET, CELL_SIZE, CELL_SIZE);
			}

			if (map[i][j] == RED_TANK && player.dir == DOWN)
			{
				render_texture(red_down, player.x * CELL_SIZE + X_OFFSET, player.y * CELL_SIZE + Y_OFFSET, CELL_SIZE, CELL_SIZE);
			}

			if (map[i][j] == RED_TANK && player.dir == UP)
			{
				render_texture(red_up, player.x * CELL_SIZE + X_OFFSET, player.y * CELL_SIZE + Y_OFFSET, CELL_SIZE, CELL_SIZE);
			}
		}
	}

	//渲染敌方坦克
	for (int i = 0; i < ENEMIES_NUM; i++)
	{
		if (enemies[i].is_taken)
			continue;
		if (enemies[i].hp > 0) {
			switch (enemies[i].dir)
			{
			case UP:
				render_texture(blue_up, enemies[i].x * CELL_SIZE + X_OFFSET, enemies[i].y * CELL_SIZE + Y_OFFSET, CELL_SIZE, CELL_SIZE);
				break;
			case DOWN:
				render_texture(blue_down, enemies[i].x * CELL_SIZE + X_OFFSET, enemies[i].y * CELL_SIZE + Y_OFFSET, CELL_SIZE, CELL_SIZE);
				break;
			case LEFT:
				render_texture(blue_left, enemies[i].x * CELL_SIZE + X_OFFSET, enemies[i].y * CELL_SIZE + Y_OFFSET, CELL_SIZE, CELL_SIZE);
				break;
			case RIGHT:
				render_texture(blue_right, enemies[i].x * CELL_SIZE + X_OFFSET, enemies[i].y * CELL_SIZE + Y_OFFSET, CELL_SIZE, CELL_SIZE);
				break;
			default:
				break;
			}
		}
		else {
			render_texture(dead_tank, enemies[i].x * CELL_SIZE + X_OFFSET, enemies[i].y * CELL_SIZE + Y_OFFSET, CELL_SIZE, CELL_SIZE);
		}
	}
}

// 子弹纹理缓存（仅加载一次）
SDL_Texture* g_bullet_tex[4] = {NULL, NULL, NULL, NULL};

void GameView_ShowBullet()
{
	// 首次使用时加载子弹纹理
	if (!g_bullet_tex[UP]) {
		g_bullet_tex[UP] = load_texture("images/B_UP_b.png");
		g_bullet_tex[DOWN] = load_texture("images/B_DOWN_b.png");
		g_bullet_tex[LEFT] = load_texture("images/B_LEFT_b.png");
		g_bullet_tex[RIGHT] = load_texture("images/B_RIGHT_b.png");
	}

	for (int i = 0; i < BULLET_NUM; i++) {  //遍历玩家子弹
		if (P_bullets[i].is_live) {
			int x = P_bullets[i].x * CELL_SIZE + X_OFFSET;
			int y = P_bullets[i].y * CELL_SIZE + Y_OFFSET;
			int tex_x = (P_bullets[i].dir > DOWN ? x : x + 10);
			int tex_y = (P_bullets[i].dir > DOWN ? y + 10 : y);
			int bw = (P_bullets[i].dir > DOWN ? CELL_SIZE / 2 : CELL_SIZE / 2 / 2);
			int bh = (P_bullets[i].dir > DOWN ? CELL_SIZE / 2 / 2 : CELL_SIZE / 2);
			render_texture(g_bullet_tex[P_bullets[i].dir], tex_x, tex_y, bw, bh);
		}
	}
	for (int i = 0; i < BULLET_NUM * ENEMIES_NUM; i++) {  //绘制敌方子弹
		if (E_bullets[i].is_live) {
			int x = E_bullets[i].x * CELL_SIZE + X_OFFSET;
			int y = E_bullets[i].y * CELL_SIZE + Y_OFFSET;
			int tex_x = (E_bullets[i].dir > DOWN ? x : x + 10);
			int tex_y = (E_bullets[i].dir > DOWN ? y + 10 : y);
			int bw = (E_bullets[i].dir > DOWN ? CELL_SIZE / 2 : CELL_SIZE / 2 / 2);
			int bh = (E_bullets[i].dir > DOWN ? CELL_SIZE / 2 / 2 : CELL_SIZE / 2);
			render_texture(g_bullet_tex[E_bullets[i].dir], tex_x, tex_y, bw, bh);
		}
	}
}

/*
	创建者：凌零
	功能：显示胜利界面
*/
void GameView_ShowWIN()
{
	clear_screen();
	draw_image("images/胜利.png", 0, 0, 700, 700);
	draw_image("images/返回按钮.jpg", 30, 550, 150, 50);
	present_screen();
	
	bool goto_menu = false;
	while (true)
	{
		int ev = handle_menu_events(goto_menu);
		if (goto_menu) {
			MenuView();
			return;
		}
		if (ev == 1) {
			//鼠标点击 - 判断返回按钮区域
			// 用SDL_GetMouseState获取点击坐标
			int mx, my;
			Uint32 buttons = SDL_GetMouseState(&mx, &my);
			if (buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) {
				if (mx >= 30 && mx <= 180 && my >= 550 && my <= 600)
				{
					MenuView();
					return;
				}
			}
		}
		SDL_Delay(16);
	}
}

/*
	创建者：凌零
	功能：显示失败界面

*/

void GameView_ShowLose()
{
	clear_screen();
	draw_image("images/失败.png", 0, 0, 700, 700);
	draw_image("images/返回按钮.jpg", 30, 550, 150, 50);
	present_screen();
	
	bool goto_menu = false;
	while (true)
	{
		int ev = handle_menu_events(goto_menu);
		if (goto_menu) {
			MenuView();
			return;
		}
		if (ev == 1) {
			int mx, my;
			Uint32 buttons = SDL_GetMouseState(&mx, &my);
			if (buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) {
				if (mx >= 30 && mx <= 180 && my >= 550 && my <= 600)
				{
					MenuView();
					return;
				}
			}
		}
		SDL_Delay(16);
	}
}

//------------------view-------------------

//-------------------service---------------

/*
* 刷新地图
*/
 void Update()
{
	 InitMap();		//把原有的地图数据再赋值一次map

	 map[player.x][player.y] = RED_TANK;	//把玩家、敌人、子弹数组，将位置信息写入到地图
	 
	 for (int i = 0; i < ENEMIES_NUM; i++) {  
		 if (enemies[i].hp > 0) {
			 map[enemies[i].x][enemies[i].y] = BLUE_TANK;
		 }
		 else if (enemies[i].hp <= 0 && enemies[i].is_taken == false) {
			 map[enemies[i].x][enemies[i].y] = BLUE_DEAD_TANK;
		 }
	 }

	 //for (int j = 0; j < BULLET_NUM; j++) {       //玩家子弹
		// if (P_bullets[j].is_live == true) {
		//	 map[enemies[j].x][enemies[j].y] = BULLET;
		// }
	 //}

	 //for (int k = 0; k < BULLET_NUM * ENEMIES_NUM; k++) {       //敌方子弹
		// if (E_bullets[k].is_live == true) {
		//	 map[enemies[k].x][enemies[k].y] = BULLET;
		// }
	 //}
}

/*
	创建者：凌零
	功能：初始化为周围是墙壁的空白地图
*/
void InitMap()
{
	// 初始化地图
	for (int i = 0; i < MAP_CELL_NUM; i++) {
		for (int j = 0; j < MAP_CELL_NUM; j++) {
			// 如果是边缘的位置，设定为 WALL
			if (i == 0 || i == MAP_CELL_NUM - 1 || j == 0 || j == MAP_CELL_NUM - 1) {
				map[i][j] = WALL;
			}
			// 其他位置设定为 BLANK
			else {
				map[i][j] = BLANK;
			}
		}
	}
}

/*
	创建者：凌零
	功能：扩展功能的地图初始化（根据map.h文件预设地图数据）
*/
//void InitMap(const int preset_map[MAP_CELL_NUM][MAP_CELL_NUM]) {
//	for (int i = 0; i < MAP_CELL_NUM; i++) {
//		for (int j = 0; j < MAP_CELL_NUM; j++) {
//			map[i][j] = preset_map[i][j];
//		}
//	}
//}

/*
	创建者：丧丧的咸鱼
	功能：
		根据传入的方向参数判断坦克移动的可行性
		实现坦克移动
*/
void PlayerMove() {
	static clock_t start = clock() - 100;
	if ((clock() - start) < 100)
		return;
	start = clock();
	if (player.dir == UP) {
		switch (TankMoveCheck(player.dir, player)) {	//空地,敌方坦克,子弹,敌方死亡坦克,墙
		case BLANK:
			player.y--;
			break;
		case BULLET:
			player.y--;
			player.hp--;
			for (int i = 0; i <= BULLET_NUM * ENEMIES_NUM; i++) {		//找出并干掉那颗子弹报销
				if (E_bullets[i].x == player.x && E_bullets[i].y == player.y) {
					E_bullets[i].is_live = false;
				}
			}
			break;
		case BLUE_DEAD_TANK:
			player.y--;
			player.attack++;
			if(player.hp < 5) player.hp++;
			for (int i = 0; i < ENEMIES_NUM; i++) {			//循环敌人坦克数组
				if (player.x == enemies[i].x && player.y == enemies[i].y) //找个位置下无敌坦克
					enemies[i].is_taken = true;
			}
			break;
		default:
			break;
		}
		
			
	}
	else if (player.dir == DOWN) {
		switch (TankMoveCheck(player.dir, player)) {	//空地,敌方坦克,子弹,敌方死亡坦克,墙
		case BLANK:
			player.y++;
			break;
		case BULLET:
			player.y++;
			player.hp--;
			for (int i = 0; i <= BULLET_NUM * ENEMIES_NUM; i++) {		//找出并干掉那颗子弹报销
				if (E_bullets[i].x == player.x && E_bullets[i].y == player.y) {
					E_bullets[i].is_live = false;
				}
			}
			break;
		case BLUE_DEAD_TANK:
			player.y++;
			player.attack++;
			if (player.hp < 5) player.hp++;
			for (int i = 0; i < ENEMIES_NUM; i++) {			//循环敌人坦克数组
				if (player.x == enemies[i].x && player.y == enemies[i].y) //找个位置下无敌坦克
					enemies[i].is_taken = true;
			}
			break;
		default:
			break;
		}
	}
	else if (player.dir == LEFT) {
		switch (TankMoveCheck(player.dir, player)) {	//空地,敌方坦克,子弹,敌方死亡坦克,墙
		case BLANK:
			player.x--;
			break;
		case BULLET:
			player.x--;
			player.hp--;
			for (int i = 0; i <= BULLET_NUM * ENEMIES_NUM; i++) {		//找出并干掉那颗子弹报销
				if (E_bullets[i].x == player.x && E_bullets[i].y == player.y) {
					E_bullets[i].is_live = false;
				}
			}
			break;
		case BLUE_DEAD_TANK:
			player.x--;
			player.attack++;
			if (player.hp < 5) player.hp++;
			for (int i = 0; i < ENEMIES_NUM; i++) {			//循环敌人坦克数组
				if (player.x == enemies[i].x && player.y == enemies[i].y) //找个位置下无敌坦克
					enemies[i].is_taken = true;
			}
			break;
		default:
			break;
		}
	}
	else if (player.dir == RIGHT) {
		switch (TankMoveCheck(player.dir, player)) {	//空地,敌方坦克,子弹,敌方死亡坦克,墙
		case BLANK:
			player.x++;
			break;
		case BULLET:
			player.x++;
			player.hp--;
			for (int i = 0; i <= BULLET_NUM * ENEMIES_NUM; i++) {		//找出并干掉那颗子弹报销
				if (E_bullets[i].x == player.x && E_bullets[i].y == player.y) {
					E_bullets[i].is_live = false;
				}
			}
			break;
		case BLUE_DEAD_TANK:
			player.x++;
			player.attack++;
			if (player.hp < 5) player.hp++;
			for (int i = 0; i < ENEMIES_NUM; i++) {			//循环敌人坦克数组
				if (player.x == enemies[i].x && player.y == enemies[i].y) //找个位置下无敌坦克
					enemies[i].is_taken = true;
			}
			break;
		default:
			break;
		}
	}
}//撞墙和敌方坦克坦克不移动将不会修改

/*
	创建者：丧丧的咸鱼
	功能：坦克碰撞检测：检测是否为墙壁、敌方死亡坦克、敌方坦克、空地
	对不同类型进行不同的处理
	0->空地、1->表示墙、2->己方坦克、3->敌方坦克、4->死亡坦克
	返回值为下一个位置的坐标（根据player.dir计算），并返回该位置存储的枚举值
*/
int TankMoveCheck(int dir, tank tank) {	//坦克能否移动检查,返回检测位置存储的枚举值
	int ret = 0; // 默认返回值为 0
	switch (dir) {
	case UP:
		return map[tank.x][tank.y - 1];
		break;
	case DOWN:
		return map[tank.x][tank.y + 1];
		break;
	case LEFT:
		return map[tank.x - 1][tank.y];
		break;
	case RIGHT:
		return map[tank.x + 1][tank.y];
		break;
	default: // 添加默认分支
		break;
	}
	return ret;
}

/*
	创建者：凌零
	功能：遍历子弹数组，对每一个子弹进行处理
	首先肯定要用个外循环遍历所有子弹，分1,2,......1,5. 12,13,14,15,16...
	子弹碰撞检测：检测是否为墙壁、敌方死亡坦克、敌方坦克、玩家子弹、敌方子弹、空地、己方坦克。
*/

/*
	创建者：凌零
*/
int BulletMoveCheck(int dir, bullet bul) //返回当前目标位置的map枚举值
{
	int ret = 0; // 默认返回值为 0
	switch (dir) {
	case UP:
		return map[bul.x][bul.y - 1];
		break;
	case DOWN:
		return map[bul.x][bul.y + 1];
		break;
	case LEFT:
		return map[bul.x - 1][bul.y];
		break;
	case RIGHT:
		return map[bul.x + 1][bul.y];
		break;
	default: // 添加默认分支
		return ret;
		break;
	}
}

/*
	创建者：丧丧的咸鱼
	功能：
		通过随机移动(wasd)和方向取余4取模0123
		生成方向之后-调用检查判断下一个位置的状态然后再进行相应的操作
		同时移动时改变方向判断下一步移动的可行性实现随机移动
*/
void EnemiesMove() { //敌人控制函数
	static clock_t start = clock() - 1000;
	if((clock() - start) < 1000)
		return;
	start = clock();
	for (int i = 0; i < ENEMIES_NUM; ++i) {	//n个敌方坦克移动
		if (enemies[i].hp <= 0)
			continue;
		int dir = rand() % 4;		//随机生成敌方坦克的移动方向
		if (dir == UP) {		//0向上
			enemies[i].dir = UP;	// 更新当前 enemies[i] 的方向为向上
			switch (TankMoveCheck(dir, enemies[i])) {	//空地,敌方坦克,子弹,墙
			case BLANK:
				enemies[i].y--;
				break;
			case BULLET:
				enemies[i].y--;
				for (int i = 0; i < BULLET_NUM; i++) {			//遍历玩家子弹数组
					if (P_bullets[i].x == enemies[i].x && P_bullets[i].y == enemies[i].y) {
						P_bullets[i].is_live = false;
						enemies[i].hp--;
					}
				}
				break;
			}
		}
		else if (dir == DOWN) {		//1向下
			enemies[i].dir = DOWN;
			switch (TankMoveCheck(dir, enemies[i])) {	//空地,敌方坦克,子弹,墙
			case BLANK:
				enemies[i].y++;
				break;
			case BULLET:
				enemies[i].y++;
				for (int i = 0; i < BULLET_NUM; i++) {			//遍历玩家子弹数组
					if (P_bullets[i].x == enemies[i].x && P_bullets[i].y == enemies[i].y) {
						P_bullets[i].is_live = false;
						enemies[i].hp--;
					}
				}
				break;
			}
		}
		else if (dir == LEFT) {		//2向左
			enemies[i].dir = LEFT;
			switch (TankMoveCheck(dir, enemies[i])) {	//空地,敌方坦克,子弹,墙
			case BLANK:
				enemies[i].x--;
				break;
			case BULLET:
				enemies[i].x--;
				for (int i = 0; i < BULLET_NUM; i++) {			//遍历玩家子弹数组
					if (P_bullets[i].x == enemies[i].x && P_bullets[i].y == enemies[i].y) {
						P_bullets[i].is_live = false;
						enemies[i].hp--;
					}
				}
				break;
			}
		}
		else if (dir == RIGHT) {		//3向右
			enemies[i].dir = RIGHT;
			switch (TankMoveCheck(dir, enemies[i])) {	//空地,敌方坦克,子弹,墙
			case BLANK:
				enemies[i].x++;
				break;
			case BULLET:
				enemies[i].x++;
				for (int i = 0; i < BULLET_NUM; i++) {			//遍历玩家子弹数组
					if (P_bullets[i].x == enemies[i].x && P_bullets[i].y == enemies[i].y) {
						P_bullets[i].is_live = false;
						enemies[i].hp--;
					}
				}
				break;
			}
		}
	}
}

/*
	创建者：凌零
	功能：
		根据传入的方向参数调用BulletMoveCheck()
	返回的枚举值判断子弹移动结果
		实现子弹移动
*/

void PlayerBulletMove() {
	static clock_t start = clock() - 100;
	if ((clock() - start) < 100)
		return;
	start = clock();

	int arr[4][2] = {
		{0, -1},
		{0, 1},
		{-1, 0},
		{1, 0},
	};
	for (int i = 0; i < BULLET_NUM; i++)  // 遍历子弹
	{
		if (P_bullets[i].is_live == false)
		{
			continue;
		}
		else
		{
			// 子弹碰撞检测：检测是否碰到空地、墙壁、己方坦克、敌方坦克、敌方死亡坦克、玩家子弹、敌方子弹
				// 0->空地、1->表示墙、2->己方坦克、3->敌方坦克、4->死亡坦克、5->我方子弹、6->敌方子弹
				// 0 空地 1 墙 3 敌方坦克 6 敌方子弹
				int type = BulletMoveCheck(P_bullets[i].dir, P_bullets[i]);
			if (type == BLANK)
			{
				P_bullets[i].x += arr[P_bullets[i].dir][0];
				P_bullets[i].y += arr[P_bullets[i].dir][1];
			}
			else if (type == WALL)
			{
				P_bullets[i].is_live = false;
			}
			else if (type == BLUE_TANK)    //敌方坦克
			{
				P_bullets[i].is_live = false;				//子弹消失
				for (int k = 0; k < ENEMIES_NUM; k++)	//坦克爆炸
				{
					switch (P_bullets[i].dir) {
					case UP:
						if (enemies[k].x == P_bullets[i].x && enemies[k].y == P_bullets[i].y - 1)	//位于子弹上方敌方坦克受到伤害
						{
							enemies[k].hp -= P_bullets[i].damage;
						}
						break;
					case DOWN:
						if (enemies[k].x == P_bullets[i].x && enemies[k].y == P_bullets[i].y + 1)	//位于子弹下方敌方坦克受到伤害
						{
							enemies[k].hp -= P_bullets[i].damage;
						}
						break;
					case LEFT:
						if (enemies[k].x == P_bullets[i].x - 1 && enemies[k].y == P_bullets[i].y)	//位于子弹左方敌方坦克受到伤害
						{
							enemies[k].hp -= P_bullets[i].damage;
						}
						break;
					case RIGHT:
						if (enemies[k].x == P_bullets[i].x + 1 && enemies[k].y == P_bullets[i].y)	//位于子弹右方敌方坦克受到伤害
						{
							enemies[k].hp -= P_bullets[i].damage;
						}
						break;
					default: // 添加默认分支
						break;
					}

				}
			}
			else
			{
				P_bullets[i].is_live = false;
				if (BULLET_NUM == 2)
				{
					for (int k = 3; k <= 8; k++)
					{
						if (P_bullets[k].x == P_bullets[i].x && P_bullets[k].y == P_bullets[i].y)
						{
							P_bullets[k].is_live = false;
							break;
						}
					}
				}
				else
				{
					for (int k = 3; k <= 12; k++)
					{
						if (P_bullets[k].x == P_bullets[i].x && P_bullets[k].y == P_bullets[i].y)
						{
							P_bullets[k].is_live = false;
							break;
						}
					}
				}
				break;
			}
		}
	}
}

void EnemyBulletMove() {
	static clock_t start = clock() - 500;
	if ((clock() - start) < 500)
		return;
	start = clock();

	int arr[4][2] = {
		{0, -1},
		{0, 1},
		{-1, 0},
		{1, 0},
	};
	for (auto& i : E_bullets) {
		if (i.is_live) {
			int type = BulletMoveCheck(i.dir, i);
			if (type == BLANK)
			{
				i.x += arr[i.dir][0];
				i.y += arr[i.dir][1];
			}
			else if (type == WALL)
			{
				i.is_live = false;
			}
			else if (type == RED_TANK)
			{
				i.is_live = false;
				player.hp -= i.damage;
			}
			else {
				i.x += arr[i.dir][0];
				i.y += arr[i.dir][1];
			}
			/*else
			{
				i.is_live = false;
				if (BULLET_NUM == 2)
				{
					for (int k = 3; k <= 8; k++)
					{
						if (P_bullets[k].x == i.x && P_bullets[k].y == i.y)
						{
							P_bullets[k].is_live = false;
							break;
						}
					}
				}
				else
				{
					for (int k = 3; k <= 12; k++)
					{
						if (P_bullets[k].x == i.x && P_bullets[k].y == i.y)
						{
							P_bullets[k].is_live = false;
							break;
						}
					}
				}
				break;
			}*/
		}
	}
}
/*
	创建者：凌零
	功能：初始化玩家坦克
*/
void PlayerInit()
{
	player.x = MAP_CELL_NUM / 2;	// 玩家初始位置
	player.y = MAP_CELL_NUM / 2;
	player.hp = 5;	// 玩家血量初始化
	player.dir = UP;	// 初始化玩家方向
	player.attack = 5;	// 初始化玩家攻击力为 5
	kill = 0;			// 玩家击杀数初始化为 0
	map[player.x][player.y] = RED_TANK;	// 在地图上标记坦克的位置
}

/*
	创建者：凌零
	功能：生成敌方坦克
*/
void EnemyInit()
{
	srand((unsigned int)time(NULL));	 //初始化随机数种子
	// 使用 <random> 库创建随机数生成器
	//default_random_engine generator;
	//uniform_int_distribution<int> distribution(0, 49); // 创建一个均匀分布，生成的随机数范围在1-48

	// 初始化敌方坦克
	for (int i = 0; i < ENEMIES_NUM; i++) {
		enemies[i].x = rand() % (MAP_CELL_NUM - 2) + 1 ; // 使用随机数生成器生成坐标
		enemies[i].y = rand() % (MAP_CELL_NUM - 2) + 1;

		// 如果随机到的位置已经被坦克或者墙壁占据，那么重新生成
		while (map[enemies[i].x][enemies[i].y] != BLANK) {
			enemies[i].x = rand() % (MAP_CELL_NUM - 2) + 1;
			enemies[i].y = rand() % (MAP_CELL_NUM - 2) + 1;
		}

		enemies[i].hp = enemy.hp; // 设置敌人初始血量为5
		enemies[i].attack = enemy.attack; // 设置敌人初始攻击力为1
		enemies[i].dir = LEFT; // 设置敌人初始面朝左
		map[enemies[i].x][enemies[i].y] = BLUE_TANK; // 在地图上标记敌人位置
	}
}

/*
	创建者：凌零
	功能：
		返回值为假:说明失败，己方坦克hp<=0,或者还没有胜利条件：己方坦克hp>0,敌方坦克数量>0
		返回值为真:说明赢了 己方坦克hp==0,敌方坦克数量==0
*/
bool IsWin() {
	bool all_die = true;
	for (auto& i : enemies) {
		if (i.hp > 0)
			all_die = false;
	}
	if (player.hp > 0 && all_die) {
		return true;	// 胜利
	}
	else return false;	// 没胜利或失败。 还在游戏进行中。
}

// 难度选择
void Level()
{
	clear_screen();
	draw_image("images/游戏主界面背景.jpg", 0, 0, 700, 700);

	draw_image("images/简单难度.jpg", 275, 150, 150, 100);
	draw_image("images/中等难度.jpg", 275, 300, 150, 100);
	draw_image("images/困难难度.jpg", 275, 450, 150, 100);
	present_screen();

	while (true)
	{
		SDL_Event e;
		while (SDL_PollEvent(&e)) {
			if (e.type == SDL_QUIT) exit(0);
			if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE) {
				MenuView();
				return;
			}
			if (e.type == SDL_MOUSEBUTTONDOWN) {
				int mx = e.button.x;
				int my = e.button.y;

				//选择简单难度
				if (mx >= 275 && mx <= 425 && my >= 150 && my <= 250)
				{
					enemy.hp = 5;
					enemy.attack = 1;
					MenuView();
					return;
				}
				//选择中等难度
				if (mx >= 275 && mx <= 425 && my >= 300 && my <= 400)
				{
					enemy.hp = 10;
					enemy.attack = 2;
					MenuView();
					return;
				}
				//选择困难难度
				if (mx >= 275 && mx <= 425 && my >= 450 && my <= 550)
				{
					enemy.hp = 15;
					enemy.attack = 3;
					MenuView();
					return;
				}
			}
		}
		SDL_Delay(16);
	}
}

// 开发人员
void MemberView()
{
	clear_screen();
	draw_image("images/开发人员界面.jpg", 0, 0, 700, 700);
	draw_image("images/返回按钮.jpg", 30, 550, 150, 50);
	present_screen();

	while (true)
	{
		SDL_Event e;
		while (SDL_PollEvent(&e)) {
			if (e.type == SDL_QUIT) exit(0);
			if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE) {
				MenuView();
				return;
			}
			if (e.type == SDL_MOUSEBUTTONDOWN) {
				int mx = e.button.x;
				int my = e.button.y;

				//返回主菜单界面
				if (mx >= 30 && mx <= 180 && my >= 550 && my <= 600)
				{
					MenuView();
					return;
				}
			}
		}
		SDL_Delay(16);
	}
}

// 菜单
void MenuView()
{
	InitMap();
	clear_screen();
	draw_image("images/菜单界面.jpg", 0, 0, 700, 700);
	draw_image("images/开始游戏按键.jpg", 50, 250, 150, 50);
	draw_image("images/难度设置按键.jpg", 50, 330, 150, 50);
	draw_image("images/相关人员按键.jpg", 50, 410, 150, 50);
	draw_image("images/退出游戏按键.jpg", 50, 490, 150, 50);
	present_screen();

	while (true)
	{
		SDL_Event e;
		while (SDL_PollEvent(&e)) {
			if (e.type == SDL_QUIT) exit(0);
			if (e.type == SDL_MOUSEBUTTONDOWN) {
				int mx = e.button.x;
				int my = e.button.y;

				//跳转游戏主页面
				if (mx >= 50 && mx <= 200 && my >= 250 && my <= 300)
				{
					GameView();
				}
				//跳转至游戏难度选择
				if (mx >= 50 && mx <= 200 && my >= 330 && my <= 380)
				{
					Level();
					return;
				}
				//跳转至开发人员界面
				if (mx >= 50 && mx <= 200 && my >= 410 && my <= 460)
				{
					MemberView();
					return;
				}
				//退出游戏
				if (mx >= 50 && mx <= 200 && my >= 490 && my <= 540)
				{
					exit(0);
				}
			}
		}
		SDL_Delay(16);
	}
}

void change()
{
	SDL_SetWindowTitle(g_window, "纸牌坦克");
}


//-------------------service---------------

/*
	创建者：丧丧的咸鱼
*/
int main() {
	// 将工作目录设置为可执行文件所在目录，确保相对路径资源（images/、music/）能正确加载
	char* base_path = SDL_GetBasePath();
	if (base_path) {
		chdir(base_path);
		SDL_free(base_path);
	}

	// 初始化SDL
	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
		fprintf(stderr, "SDL初始化失败: %s\n", SDL_GetError());
		return -1;
	}

	// 初始化SDL_image
	int img_flags = IMG_INIT_PNG | IMG_INIT_JPG;
	if (!(IMG_Init(img_flags) & img_flags)) {
		fprintf(stderr, "SDL_image初始化失败: %s\n", IMG_GetError());
		SDL_Quit();
		return -1;
	}

	// 初始化SDL_mixer
	if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0) {
		fprintf(stderr, "SDL_mixer初始化失败: %s\n", Mix_GetError());
		IMG_Quit();
		SDL_Quit();
		return -1;
	}

	// 初始化SDL_ttf
	if (TTF_Init() < 0) {
		fprintf(stderr, "SDL_ttf初始化失败: %s\n", TTF_GetError());
		Mix_CloseAudio();
		IMG_Quit();
		SDL_Quit();
		return -1;
	}

	// 创建窗口和渲染器
	g_window = SDL_CreateWindow("纸牌坦克", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 700, 700, SDL_WINDOW_SHOWN);
	if (!g_window) {
		fprintf(stderr, "窗口创建失败: %s\n", SDL_GetError());
		TTF_Quit();
		Mix_CloseAudio();
		IMG_Quit();
		SDL_Quit();
		return -1;
	}

	g_renderer = SDL_CreateRenderer(g_window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
	if (!g_renderer) {
		fprintf(stderr, "渲染器创建失败: %s\n", SDL_GetError());
		SDL_DestroyWindow(g_window);
		TTF_Quit();
		Mix_CloseAudio();
		IMG_Quit();
		SDL_Quit();
		return -1;
	}

	// 加载字体（尝试多个常用中文字体路径）
	const char* font_paths[] = {
		"/usr/share/fonts/wqy-microhei-fonts/wqy-microhei.ttc",
		"/usr/share/fonts/wqy-zenhei-fonts/wqy-zenhei.ttc",
		"/usr/share/fonts/google-noto-sans-cjk-vf-fonts/NotoSansCJK-VF.ttc",
		"/usr/share/fonts/google-noto-serif-cjk-vf-fonts/NotoSerifCJK-VF.ttc",
		NULL
	};
	for (int i = 0; font_paths[i] != NULL; i++) {
		g_font = TTF_OpenFont(font_paths[i], 30);
		if (g_font) {
			printf("已加载字体: %s\n", font_paths[i]);
			break;
		}
	}
	if (!g_font) {
		fprintf(stderr, "警告: 未找到中文字体，文本将无法显示。请安装 wqy-microhei 或 noto-cjk 字体。\n");
		// 尝试使用任何可用TTF字体
	}

	// 加载BGM
	g_bgm = Mix_LoadMUS("music/bgm.wav");
	if (!g_bgm) {
		fprintf(stderr, "BGM加载失败: %s，将静音运行\n", Mix_GetError());
	} else {
		Mix_PlayMusic(g_bgm, -1); // 循环播放
	}

	// 设置窗口标题
	change();

	// 进入主菜单
	MenuView();

	// 清理资源
	if (g_bgm) {
		Mix_HaltMusic();
		Mix_FreeMusic(g_bgm);
	}
	if (g_font) TTF_CloseFont(g_font);
	SDL_DestroyRenderer(g_renderer);
	SDL_DestroyWindow(g_window);
	Mix_CloseAudio();
	TTF_Quit();
	IMG_Quit();
	SDL_Quit();

	return 0;
}
