*暂未完成,因为无尽BUG滚滚来。
好长时间没写完,一是能力不够,二是我还得给老板写WEB的代码。可是我不会WEB!js和PHP简直就是世界上最好的语言,因为它们能够让人更快地进入极乐世界。
让我写一个gm后台,他说好不好看无所谓,能用就行。于是,我就写了一个根据JSON数据自动生成页面的代码……哈哈,平均15分钟完成一个功能,简直不要太爽。懒人自然有懒办法。当然,之前写工具花费了大量时间。
回家还要玩激战2刷每日,还挺忙的……
好吧,我已经没有力气给自己吐槽了。。。所以,直接上代码吧,不废话了。
以下代码为C++代码。
简直通俗易懂。
接下来(预计实现):
1.结构改造:在代码中定义一个对象的属性关联以及拥有属性是不太方便的,应该将这种关系和数据放置于配置表中。甚至是接下来的事件类和故事(story)类也应当如此。
1.1 首先,需要定义基本动作,
1.2 定义动作指令
1.3 需要一个虚拟机,基于栈的或者是基于寄存器的。还是栈虚拟机实现更简单一点,尽管效率稍差。
1.3.1 图形界面或者脚本程序。前者对于设计师来说更加友好。
1.4 协议。应当将虚拟机生成的字节码翻译成数据发送给主程序处理。
1.5 存储。生成的字节码应该被存储在配置表或者数据库中。
1.6 处理。主程序应该有足够通用、健壮和效率的算法来处理这个字节码。
看来这是一个大工程。
2.集中测试(2018.11.1 19:25)
LunaObject.h
#pragma once #include "stdinc.h"
#include "Location.h"
#include "QualitiesManager.h"
#include "QualInc.h" namespace Lunacia
{
class ObjectInfo final
{
private:
//info name: value pointer
std::unordered_map<std::string, void*> _infos;
std::unordered_map<std::string, std::function<void(const std::string&)>> _destory; public:
ObjectInfo();
ObjectInfo(std::unordered_map<std::string, void*>& infos);
~ObjectInfo(); public:
template<typename T>
T& Get(const std::string& name)
{
if (!IsExist(name))
{
ErrorThrow("The data is not exist what name is " + name);
} return *(static_cast<T*>(_infos.find(name)->second));
} template<typename T>
void Set(const std::string& name, T& val)
{
auto itFound = _infos.find(name);
void* pFound = nullptr;
if (itFound == _infos.end())
{
Add(name, val);
return;
} pFound = itFound->second;
T* pVal = static_cast<T*>(pFound);
*pVal = val;
} template<typename T>
void Replace(const std::string& name, const T& value)
{
Delete<T>(name);
Add(name, value);
} template<typename T>
bool Add(const std::string& name, const T& value)
{
T* pValue = new T();
*pValue = value; std::function<void(const std::string&)> destoryFunc = [this](const std::string& n)->void
{
this->Delete<T>(n);
}; _destory.insert(std::make_pair(name, destoryFunc));
return _infos.insert(std::make_pair(name, static_cast<void*>(pValue))).second;
} template<typename T>
bool Delete(const std::string& name)
{
auto itFound = _infos.find(name);
if (itFound == _infos.end())
{
return false;
}
void* pVal = itFound->second; T* pDel = static_cast<T*>(pVal);
delete pDel;
pVal = nullptr; _destory.erase(name);
return _infos.erase(name) == ;
} bool IsExist(const std::string& name) const;
}; //////////LunaObject//////////
class LunaObject
{
public:
LunaObject();
virtual ~LunaObject(); public:
virtual void QualitiesCorrelation() = ; public:
virtual ObjectInfo& Info();
virtual void Destory(); #ifdef __Debug
public:
#else
protected:
#endif // __Debug
ObjectInfo m_info;
QualitiesManager m_qualManager;
}; ///////////NullObject///////////
class NullObject: public LunaObject
{
private:
static NullObject* _instance; private:
NullObject(); public:
friend class ObjectManager;
void Destory() override;
ObjectInfo& Info() override; static NullObject* const GetInstance(); private:
void QualitiesCorrelation() override;
}; extern NullObject NULL_OBJECT;
extern NullObject* const NULLPTR_OBJECT;
}; //#define ADDOBJ(className) g_ObjectManager.AddObject(#className,new className)
LunaObject.cpp
#include "LunaObject.h" namespace Lunacia
{
LunaObject::LunaObject()
{
} LunaObject::~LunaObject()
{
Destory();
} ObjectInfo & LunaObject::Info()
{
return m_info;
} void LunaObject::Destory()
{
m_qualManager.Clear();
} /**
* @class: NullObject.
* @lazy initializate: false.
* @thread safe: true.
*
*/
NullObject* NullObject::_instance = new NullObject(); static NullObject* const NULLPTR_OBJECT = NullObject::GetInstance();
static NullObject NULL_OBJECT = *NULLPTR_OBJECT; NullObject::NullObject()
{
} NullObject* const NullObject::GetInstance()
{
return _instance;
} void NullObject::Destory()
{
ErrorThrow("Destory Function: It is null object!");
} ObjectInfo & NullObject::Info()
{
ErrorThrow("GetObjectInfo Function: It is null object!");
return m_info;
} void NullObject::QualitiesCorrelation()
{
ErrorThrow("QualitiesCorrelation Function: It is null object!");
} //////////////ObjectInfo//////////////
ObjectInfo::ObjectInfo()
{
} ObjectInfo::ObjectInfo(std::unordered_map<std::string, void*>& infos):
_infos(infos)
{
} ObjectInfo::~ObjectInfo()
{
std::unordered_map<std::string, void*>::iterator it;
while (!_infos.empty())
{
it = _infos.begin(); const std::string& name = it->first;
(_destory[name])(name);
} _infos.clear();
_destory.clear();
} bool ObjectInfo::IsExist(const std::string & name) const
{
if (_infos.find(name) == _infos.end())
{
return false;
}
return true;
}
};
ObjectManager.h
#pragma once #include "LunaObject.h"
#include "UniqueID.h" namespace Lunacia
{
class ObjectManager final
{
public:
ObjectManager();
~ObjectManager(); void Clear(); public:
int Add(LunaObject * obj); template<class T, typename std::enable_if <std::is_base_of<LunaObject, T>::value, T> ::type * = nullptr >
int Add(); template<class T, typename std::enable_if <std::is_base_of<LunaObject, T>::value, T> ::type * = nullptr >
LunaObject* Create(); void Remove(int id);
LunaObject*const Find(int id);
const LunaObject*const Find(int id) const; private:
std::map<int, LunaObject*> m_objects;
};
/////////////// template<class T, typename std::enable_if <std::is_base_of<LunaObject, T>::value, T> ::type *>
inline int ObjectManager::Add()
{
LunaObject* pObj = Create<T>();
return Add(pObj);
} template<class T, typename std::enable_if <std::is_base_of<LunaObject, T>::value, T> ::type *>
inline LunaObject * ObjectManager::Create()
{
return new T();
} };
ObjectManager.cpp
#include "ObjectManager.h" namespace Lunacia
{
ObjectManager::ObjectManager()
{
} ObjectManager::~ObjectManager()
{
} void ObjectManager::Clear()
{
for (auto& itEach : m_objects)
{
LunaObject* lo = itEach.second;
lo->Destory(); delete lo;
lo = NULLPTR_OBJECT;
}
} int ObjectManager::Add(LunaObject * obj)
{
int id = static_cast<int>(UniqueID::Get());
obj->Info().Set("id", id); return m_objects.insert(std::make_pair(id, obj)).second ? id : -;
} void ObjectManager::Remove(int id)
{
auto itFound = m_objects.find(id);
if (itFound != m_objects.end())
{
return;
}
LunaObject* & pObjFound = itFound->second;
pObjFound->Destory(); delete pObjFound;
pObjFound = NULLPTR_OBJECT;
} LunaObject * const ObjectManager::Find(int id)
{
const ObjectManager* pSelf = this; return const_cast<LunaObject * const>(pSelf->Find(id));
} const LunaObject * const ObjectManager::Find(int id) const
{
auto itFound = m_objects.find(id);
if (itFound == m_objects.end())
{
return NULLPTR_OBJECT;
}
return itFound->second;
}
};
Human.h(测试用) (将会被宏代替(一句宏生成一个类))
#pragma once
#include "LunaObject.h" namespace Lunacia
{
class Human : public LunaObject
{
public:
Human();
~Human(); public:
void QualitiesCorrelation() override;
};
};
Human.cpp(测试用)
#include "Human.h" namespace Lunacia
{
Human::Human()
{
} Human::~Human()
{
} void Human::QualitiesCorrelation()
{
//TODO: rebuild at config file.
PtrQuality ptrHeal = m_qualManager.AddQuality<QualHealth>();
PtrQuality ptrLifeIn = m_qualManager.AddQuality<QualLifeInstinct>();
PtrQuality ptrCour = m_qualManager.AddQuality<QualCourage>(); ptrHeal->SetLimit();
ptrHeal->SetValue(ptrHeal->GetLimit()); ptrLifeIn->SetLimit();
ptrHeal->SetValue(ptrLifeIn->GetLimit()); ptrCour->SetLimit();
ptrHeal->SetValue(ptrCour->GetLimit()); ptrLifeIn->AddPassive(ptrHeal);
ptrHeal->AddPassive(ptrCour); return;
} }
UniqueID.h(初版,用于测试)
#pragma once
#include "stdinc.h" namespace Lunacia
{
//Unique ID Local, not global.
class UniqueID final
{
public:
static int64_t Get(int8_t suffix_8bit = );
static void Load(void* pData); private:
static void ReInitPool(); private:
static const size_t _count = ; //TODO: Rebuild it. //The larger the number, the more uniform the distribution.
static int _curSize;
static int _curMax; //TODO: Rebuild it.
static std::array<int64_t, _count> _idsPool;
};
};
UniqueID.cpp
#include "UniqueID.h"
#include "Random.h" namespace Lunacia
{
int UniqueID::_curMax = ;
std::array<int64_t, UniqueID::_count> UniqueID::_idsPool;
int UniqueID::_curSize = UniqueID::_count; int64_t UniqueID::Get(int8_t suffix_8bit)
{
if (_curSize >= _idsPool.size() - )
{
ReInitPool();
} return (_idsPool[_curSize++] << ) | suffix_8bit;
} void UniqueID::Load(void* pData)
{ } void UniqueID::ReInitPool()
{
int curMin = _curMax;
_curMax += _count;
for (int i = ; i < _count; ++i)
{
_idsPool[i] = i + curMin;
} for (int n = ; n < _count - ; ++n)
{
uint64_t ran = RandomAvg::GetRandNum(n + , _count);
std::swap(_idsPool[n], _idsPool[ran]);
} _curSize = ;
}
};
Encounter.h(测试类)
#include "stdinc.h"
#include "QualDefine.h" #pragma once namespace Lunacia
{
class Encounter
{
public:
struct QualInfluence
{
QualityType type;
int32_t influence;
}; public:
Encounter();
~Encounter(); private:
QualityType GetRandomType() const;
int32_t GetRamdomInfluence() const; public:
void GetRandomInfluence(QualInfluence& __out res) const;
}; };
Encounter.cpp
#include <bitset> #include "Encounter.h"
#include "Random.h" namespace Lunacia
{ Encounter::Encounter()
{ } Encounter::~Encounter()
{ } QualityType Encounter::GetRandomType() const
{
int rand = static_cast<int>(RandomAvg::GetRandNum(, static_cast<uint32_t>(QualityType::__QualityType_MAX)));
return static_cast<QualityType>(rand);
} int32_t Encounter::GetRamdomInfluence() const
{ return g_rn.GetRandNum<int32_t>() * static_cast<int>(std::pow(-, RandomAvg::GetRandNum() % ));
} void Encounter::GetRandomInfluence(QualInfluence& res) const
{
res.type = GetRandomType();
res.influence = GetRamdomInfluence();
}
};
_main.cpp(测试用主函数)
#include "Tilee.h"
#include "Location.h"
#include "stdinc.h"
#include "Random.h"
#include "Rational.h" #include "ObjectManager.h"
#include "QualHealth.h"
#include "QualLifeInstinct.h" #include "LunaObject.h"
#include "Human.h"
#include "UniqueID.h"
#include "UClock.h" #include "Encounter.h" using namespace Lunacia; ObjectManager* pOm = new ObjectManager();
std::vector<LunaObject*> g_objs; RandomItem<LunaObject*> * g_ri;
Encounter g_ec; const std::function<uint64_t(const LunaObject* const &)>& GetWeightFunc = [](const LunaObject*const & obj) -> uint64_t
{
const Quality* const res = obj->m_qualManager.GetQuality(QualityType::HEALTH);
if (res == nullptr)
{
return 0l;
} return res->GetValue();
}; void loop()
{
Encounter::QualInfluence eqi;
g_ec.GetRandomInfluence(eqi); LunaObject* const pObj = g_ri->GetRandItem();
Quality* const res = pObj->m_qualManager.FindQuality(eqi.type); if (res == nullptr)
{
return;
}
res->AddValue(eqi.influence); std::cout<<"ID: " << pObj->Info().Get<int>("id") << " " << static_cast<int64_t>(eqi.type) << " : "<< eqi.influence << std::endl;
} void init(int count)
{
for (size_t i = ; i < count; i++)
{
LunaObject* h = pOm->Create<Human>();
h->QualitiesCorrelation(); int id = pOm->Add(h); g_objs.push_back(h);
} g_ri = new RandomItem<LunaObject*>(g_objs, GetWeightFunc);
} int main(void)
{
init();
const int64_t RateBase = ; int64_t Rate = RateBase / ;
UClock uck; int64_t pre = GetCurrentTime();
int64_t e = ;
int64_t cur = ;
uint64_t i = ; //TEST: Loop
while (true)
{
cur = GetCurrentTime();
e += cur - pre;
pre = cur; while (e >= Rate)
{
loop();
e -= Rate;
i++;
//std::cout << e << std::endl;
} if (i >= )
{
i = ;
delete g_ri;
g_ri = new RandomItem<LunaObject*>(g_objs, GetWeightFunc);
system("cls");
}
} system("pause");
return ;
}