// 2012/9/23 By s3748679
// xAxBGame_1 : xAxB Game Level 1 (xAxB遊戲第一層架構)
// * 特性
// 1. 將4位數字組的設定解釋成 xAxBGame_1<int>(4, {0,1,2,3,4,5,6,7,8,9}),
// 換句話說就是從{0,1,2,3,4,5,6,7,8,9}挑4個的意思。
// 2. {0,1,2,3,4,5,6,7,8,9} 被解釋成SampleSpace(樣本空間),
// 4 被解釋成sampleLength(樣本長度),
// 而遊戲所使用的數字組被解釋成Sample(樣本),
// PS: SampleSpace與Sample都由std::vector<TSampleElement>定義而成。
// 3. 在決定遊戲相關參數後提供相對應的工具: sampleChecker、sampleComparer
// sampleChecker負責(由已知的sampleLength與sampleSpace)檢查Sample是否合法,
// 而sampleComparer則是負責比對二Sample並產生xAxB的結果。
// 4. 提供xAxB的型別用以放置sampleComparer的比對結果。
// * 備註
// 適用發展於 AI 與 一般化xAxBGame遊戲模型(例如提供 guest, isWin, guestTimes, reset..) // 應該吧.. (汗
//==================================================================
// xAxBGame_1.h
#include <vector>
template <typename TSampleElement>
class xAxBGame_1 { // level 1
public: // typedefs
typedef std::vector<TSampleElement> SampleSpace;
typedef std::vector<TSampleElement> Sample;
public: // classes
class xAxB;
class _SampleChecker; // result's type: bool
class _SampleComparer; // result's type: xAxB
public: // functions
// ctor
xAxBGame_1(int sampleLength, const SampleSpace&);
// info
const SampleSpace& sampleSpace() const {return _sampleSpace;}
int sampleLength() const {return _sampleLength;}
// tools
const _SampleChecker& sampleChecker() const {return __sampleChecker;}
const _SampleComparer& sampleComparer() const {return __sampleComparer;}
private: // data
SampleSpace _sampleSpace;
int _sampleLength;
_SampleChecker __sampleChecker;
_SampleComparer __sampleComparer;
};
template <typename TSampleElement>
class xAxBGame_1<TSampleElement>::xAxB{
public: // functions
// ctor
xAxB(int a, int b) : _a(a), _b(b) {}
// operator
bool operator!=(const xAxB& xAB) const {
if (_a != xAB.a()) return true;
if (_b != xAB.b()) return true;
return false;
}
bool operator==(const xAxB& xAB) const {return !(*this != xAB);}
// info
int a() const {return _a;}
int b() const {return _b;}
private: // data
int _a, _b;
};
template <typename TSampleElement>
class xAxBGame_1<TSampleElement>::_SampleChecker{
friend class xAxBGame_1<TSampleElement>;
public: // typedefs
typedef xAxBGame_1<TSampleElement> ParentType;
typedef typename ParentType::Sample _Sample;
typedef typename ParentType::SampleSpace _SampleSpace;
public: // functions
// method
bool check(const _Sample& s) const {
if (s.size() != _parent->sampleLength()) return false;
if (!_isInSampleSpace(s, _parent->sampleSpace())) return false;
if (_isRepeat(s)) return false;
return true;
}
// info
const ParentType* parent() const {return _parent;}
private: // functions
static bool _isInSampleSpace(const _Sample& s, const _SampleSpace& space){
for (auto it_s=s.begin(); it_s!=s.end(); it_s++){
bool isFind = false;
for (auto it_space=space.begin(); it_space!=space.end(); it_space++){
if (*it_s != *it_space)
continue;
isFind = true;
break;
}
if (!isFind)
return false;
}
return true;
}
static bool _isRepeat(const _Sample& s){
for (auto it_s=s.begin(); it_s!=s.end(); it_s++){
for (auto it2_s=(it_s+1); it2_s!=s.end(); it2_s++){
if (*it_s == *it2_s)
return true;
}
}
return false;
}
private: // data
_SampleChecker(){}
ParentType *_parent;
};
template <typename TSampleElement>
class xAxBGame_1<TSampleElement>::_SampleComparer{
friend class xAxBGame_1<TSampleElement>;
public: // typedefs
typedef xAxBGame_1<TSampleElement> ParentType;
typedef typename ParentType::xAxB _xAxB;
typedef typename ParentType::Sample _Sample;
public: // functions
// method
const _xAxB compare(const _Sample& s1, const _Sample& s2) const{
int a=0, b=0;
for (std::size_t i_s1=0; i_s1<s1.size(); i_s1++){
for (std::size_t i_s2=0; i_s2<s2.size(); i_s2++){
if (s1[i_s1] == s2[i_s2]){
if (i_s1 != i_s2)
b++;
else
a++;
}
}
}
return _xAxB(a, b);
}
// info
const ParentType* parent() const {return _parent;}
private: // data
// ctor
_SampleComparer(){}
ParentType *_parent;
};
//==================================================================
//==================================================================
// xAxBGame.tcc
template <typename TSampleElement>
xAxBGame_1<TSampleElement>::
xAxBGame_1(int sampleLength, const SampleSpace& sampleSpace)
: _sampleLength(sampleLength), _sampleSpace(sampleSpace)
{
__sampleChecker._parent = this;
__sampleComparer._parent = this;
}
//==================================================================
//==================================================================
// main.cpp
#include <iostream>
#include <sstream>
#include <string>
// ---------------------------------------------------------------
// -declaration---------------------------------------------------
template<typename TxAxB>
const std::string toString_xAxB(const TxAxB&);
template<typename TxAxBGameSample>
const std::string toString_xAxBGameSample(const TxAxBGameSample&);
int main();
// ---------------------------------------------------------------
// -definition----------------------------------------------------
template<typename TxAxB>
const std::string toString_xAxB(const TxAxB& xAB){
std::stringstream ss;
ss << xAB.a() << "A" << xAB.b() << "B";
std::string s;
ss >> s;
return s;
}
template<typename TxAxBGameSample>
const std::string toString_xAxBGameSample(const TxAxBGameSample& sample){
std::stringstream ss;
for (auto it=sample.begin(); it!=sample.end(); it++)
ss << *it;
std::string s;
ss >> s;
return s;
}
int main(){
using namespace std;
auto const game = (
[]() -> xAxBGame_1<int> {
int sampleSpace[] = {0,1,2,3,4,5,6,7,8,9};
int sampleLength = 4;
return xAxBGame_1<int>(
sampleLength,
xAxBGame_1<int>::SampleSpace(&sampleSpace[0], &sampleSpace[10])
);
}
)();
auto const createGameSample = (
[](int e1, int e2, int e3, int e4) -> xAxBGame_1<int>::Sample{
int sampleElements[4];
sampleElements[0] = e1; sampleElements[1] = e2;
sampleElements[2] = e3; sampleElements[3] = e4;
return xAxBGame_1<int>::Sample(&sampleElements[0], &sampleElements[4]);
}
);
auto sample1_error = createGameSample(0,1,2,-3);
cout << "check(" << toString_xAxBGameSample(sample1_error) << "): "
<< game.sampleChecker().check(sample1_error) << endl;
auto sample2_error = createGameSample(0,2,2,3);
cout << "check(" << toString_xAxBGameSample(sample2_error) << "): "
<< game.sampleChecker().check(sample2_error) << endl;
cout << endl;
auto sample1 = createGameSample(0,1,2,3);
cout << "check(" << toString_xAxBGameSample(sample1) << "): "
<< game.sampleChecker().check(sample1) << endl;
auto sample2 = createGameSample(0,2,4,5);
cout << "check(" << toString_xAxBGameSample(sample2) << "): "
<< game.sampleChecker().check(sample2) << endl;
cout << "compare(" << toString_xAxBGameSample(sample1) << "," << toString_xAxBGameSample(sample2) << "): "
<< toString_xAxB(game.sampleComparer().compare(sample1, sample2)) << endl;
#ifdef _DEBUG
system("pause");
#endif
return 0;
}
//==================================================================