#pragma once
#include "Block.h"
#include "Back.h"
#include <limits.h>

#define LANDINGHEIGHT		-45
#define ROWSELIMINATED		34
#define ROWTRANSITIONS		-32
#define COLUMNTRANSITIONS	-93 
#define NUMBEROFHOLES		-79
#define WELLSUMS			-34


//value = -landingHeight + erodedPieceCellsMetric - boardRowTransitions - boardColTransitions - (4 * boardBuriedHoles) - boardWells
//根据各指标的权重的经验值修改评估函数为:value = -45 × landingHeight + 34 × erodedPieceCellsMetric - 32 × boardRowTransitions - 93 × boardColTransitions - (79 × boardBuriedHoles) - 34 × boardWells
//value值大的为最优位置,你没看错就是大的是最优,即使所有数都会是负数

typedef struct
{
	int m_nShapeIndex;	//当前形状旋转几次
	size_t m_nY;		//移动到哪一个位置y
	size_t m_nX;		//移动到哪一个位置x

	int m_nLandingHeight;			//下落后的高度
	int m_nErodedPieceCellsMetric;	//消除贡献值
	int m_nRowTransitions;			//行变换数
	int m_nBoardColTransitions;		//列变换数
	int m_nBoardBuriedHoles;		//空洞数
	int m_nBoardWells;				//井数

	int m_nScore;					//分数
	int m_nPriority;

}BLOCKRECORD;


class CTetrisAI
{
public:
	CTetrisAI();
	CTetrisAI(CBack& Back, CBlock& Block);
	~CTetrisAI();

public:
	void SetBlock(const CBlock& Block);
	void SetBack(const CBack& Back);
	void SetBestPoint(CBack& Back, CBlock& Block,size_t nRow,size_t nCol);

	bool IsBlockCanWrite(int nRow, int nCol);	//是否能进行操作

	//计算每一个变量值
	int PierreDellacherie(int nRow, int nCol);
	int LandingHeight(int nRow);				//下落后的高度
	int ErodedPieceCellsMetric(int nRow, int nCol);	//消除贡献值
	int RowTransitions();			//行变换数
	int BoardColTransitions();		//列变换数
	int BoardBuriedHoles();			//空洞数
	int BoardWells();				//井数
	int Priority(int nIndex, int nCol);

	//对比得到最佳的,如果相同的话还有算法,可以得到最佳的是哪一个
	void Cmp2SetBest();
	BLOCKRECORD GetBestPoint();

	//旋转算法,是把shape--  为0的时候就不减了
	void RotateBlock();
	int GetIndexShape();

private:
	size_t m_nRow;	//记录出现的行
	size_t m_nCol;	//记录出现的列

	CBlock m_CBlock;
	CBack m_CBack;
	BLOCKRECORD m_BlockPoint = {};
	BLOCKRECORD m_aryBlockRecord[4][COL - 2] = {};
};