#pragma once
#include <iostream>
#include "unordered_map_serialization.h"
#include "QState.h"

#define ALPHA 0.01 // Learning rate 0.01
#define GAMMA 0.2 // Future discount 0.02
#define EPSILON 1 // Probability 1 means exploitation only.

#define ACTIONS 2
#define EXIT -1
#define ATTACK 0
#define FLEE 1
#define EXPLORE 2
#define CARRYON 3

class QTable{
private:
	friend std::ostream& operator<<(std::ostream&, const QTable&);
	friend class boost::serialization::access;

	boost::unordered_map<QState, double, StateActionHash> Q;
	//std::vector<double> weights;

	template<class Archive>
	void save(Archive & ar, const unsigned int version) const
	{
		boost::serialization::save(ar, Q, 0);
	}
	template<class Archive>
	void load(Archive & ar, const unsigned int version)
	{
		boost::serialization::load(ar, Q, 0);
	}
	BOOST_SERIALIZATION_SPLIT_MEMBER()

public:
	QTable();
	boost::unordered_map<QState, double, StateActionHash> getQ();

	void insert(QState qState, double value);
	double update(State state, int action, State nextState, double reward, bool isTerminalState);
	double getMaxValue(State state, bool terminalState);
	double getQValue(State state, int action);
	QState getFirstQState();
	
};