Code:
namespace gamelogic
{
#include "logic/cField.cpp"
#include "logic/cPlayer.cpp"
#include "logic/cBoard.cpp"
#include "logic/cRule.cpp"
#include "logic/cRuleBook.cpp"
};
class cField
{
private:
void setOwner(const bool o);
void move();
protected:
bool ownerIsNotPlayer1;
sn stonesIn = 6; // Standardinitialisierung
public:
bool getOwner();
sn getContent();
void add(const sn x=1);
cField(const sn baseval,const bool o);
cField(){};
};
class cPreyField : cField
{
public:
explicit cPreyField(const bool o);
};
class cPlayer
{
private:
const string name;
bool active;
const cPreyField &winField;
public:
bool getActive();
void changeActive();
void chat(const string t);
cPlayer(const string& n, const cPreyField& k);
~cPlayer();
};
class cBoard
{
private:
const cPreyField& PreyField_0; // 0=Self/winFieldPlayer1, 1=Other/winFieldPlayer2
const cPreyField& PreyField_1;
//std::vector< cField > fields = {cField()};
std::vector< std::unique_ptr<cField > > fields;
public:
cField &getField(int id);
cBoard(const cPreyField& winFieldPlayer1, const cPreyField& winFieldPlayer2, const sn startFill, const sn fieldSize); // to fill, fieldsize
};
class cBoardRule
{
private:
const bool ROR; // Has the side of a player one or two rows?
const sn start_Pa; // Starting amount of Fields per player
const sn start_PeK; // Starting amount of stones per PreyField per player
const sn start_PePa; // Starting amount of stones per Field per player
public:
void sadd_PaP(bool const first ...); // Use exampe: for first 4 Fields of player 1 at the left side, and equal condition for player 2 sadd_PaP(1,1,1,1,0,0, 0,0,1,1,1,1);
cBoardRule(const bool a, const sn b, const sn c, const sn d);
const sn getFields();
const sn getRows();
const sn getFieldsPerPlayer();
const sn getStartSmountOfstonesPerPreyField();
const sn getStartAmountOfstonesPerField();
};
class cRuleDraw // Regeln für das Ziehen von Steinen
{
private:
const sn chooseableField; // 0 = only own, 1 = only enemy, 2 = both
const sn moveDirection; // 0 = anti clockwise, 1 = clockwise, 2 both allowed
const sn amountstonesPerAction; // Schildkröten, die je Mulde abgelegt werden.
const sn broodingPet; // Schildkröte ist grüblerisch oder schwanger und
const bool simplePreyField; // PreyField wie normale Mulde während des Ziehens befüllen?
const sn minstonesToDraw; // Mindesanzahl Schildkröten, um Mulde als Auswahl zuzulassen
const sn maxstonesToDraw; // Maximalanzahl Schildkröten, um Mulde als Auswahl zuzulassen
public:
/// [Anmerkung: es folgen call by value getter…]
cRuleDraw(const sn a, const bool b, const sn c, const sn d, const bool e, const sn f, const sn g);
};
class cRuleCatch
{
private:
const sn lessThanToCatch; // Sind wenider als diese Anzahl Schildkröten in ihrer Kuhle, können sie genommen werden.
const sn mustNotBeMine; // 0 = muss feindliche Mulde sein, 1 = muss eigene Mulde sein, 2 = kann beides sein
const bool PreyFieldEnding; // gibt es Gewinn, wenn der letzte Stein im PreyField eines Spielers landete?
const sn onlyModuloTwo; // 0 = ungerade(x%2==true) 1 = gerade(x/2==true) = egal
const sn areaNextMinimumAmount; // Im nächsten Feld müssen wenigstens soviele Schildkröten sein
const sn areaNextMaximumAmount; // Im nächsten Feld dürfen höchstens soviele Schildkröten sein
const bool areaInFaceOfLootable;// Vom Feld gegenüber dürfen Tiere entwendet werden. -
const sn areaInFaceOfHas; // … wenn mindestens soviele Tiere enthalten sind.
const bool areInFaceOfEnemyToo; // … auch wenn es feindlich ist?
const sn recursiveCatch; // Können die Felder rekursiv ausgeräubert werden? (Felder dahinter == !moveDirection) 0 = nein, 1 = dahinter, 2 = davor
const sn drawAgain; // Wie oft danachnochmal gezogen und geschlagen werden kann
public:
/// [Anmerkung: es folgen call by value getter…]
cRuleCatch(const sn aC, const sn bC, const bool cC, const sn cC2, const sn dC, const sn eC, const bool fC, const sn gC, const bool hC, const sn iC,const sn jC);
};
class cRuleBook//: cRuleDraw
{
private:
const std::string name;
cBoardRule BoardInit;
cRuleDraw Drawing;
cRuleCatch Catching;
public:
cRuleCatch& getCR(){return Catching;};
cRuleDraw& getDR(){return Drawing;};
cBoardRule& getBR(){return BoardInit;};
std::string getName();
bool canChooseField(const cPlayer &pl, const cField &pa);
int check();
void doMove(const cPlayer &pl, const cField &pa);
cRuleBook(const string na,
// cBoardRule parameter
const sn aR, // One row
const sn bR, // Starting amount of Fields per player
const sn cR, // Starting amount of stones per PreyField per player
const sn dR, // Starting amount of stones per Field per player
// cRuleDraw parameter
const sn aD,
const bool bD,
const sn cD,
const sn dD,
const bool eD,
const sn fD,
const sn gD,
// RuleCatch parameters
const sn aC,
const sn bC,
const bool cC,
const sn cC2, //
const sn dC,
const sn eC,
const bool fC,
const sn gC,
const bool hC,
const bool iC,
const sn jC
//Catching
):name(na),BoardInit(aR,bR,cR,dR), Drawing(aD,bD,cD,dD,eD, fD, gD), Catching(aC, bC, cC, cC2, dC, eC, fC, gC, hC, iC, jC)
{
}
void sayRules();
};
cBoard::cBoard(const cPreyField& winFieldPlayer1, const cPreyField& winFieldPlayer2, const sn startFill, const sn fieldSize):PreyField_0(winFieldPlayer1),PreyField_1(winFieldPlayer2)
{
fields.reserve(startFill);
const size_t offset = startFill / 2; // offset ist hier 6
for(size_t i=0; i<offset; i++)
fields.push_back(unique_ptr<cField>(new cField(fieldSize,false)));
for(int i=0; i<offset; ++i)
fields.push_back(unique_ptr<cField>(new cField(fieldSize,true)));
int j=0; int k;
for(auto i = std::begin(fields),k=std::end(fields); i != k; ++i)
{
std::cout << ++j <<") Spieler " << i->get()->getOwner() << " mit " << i->get()->getContent() << " Punkten" << std::endl;
/// Schau dir das mal bitte an, wenn ich dieses if auskommentiere, erhalte ich diese Meldung:
//if(j==k-1);
// error: no match for ‘operator==’ (operand types are ‘int’ and ‘__gnu_cxx::__normal_iterator<std::unique_ptr<gamelogic::cField>*, std::vector<std::unique_ptr<gamelogic::cField> > >’)|
}
j=0;
/// hier wird keine Fehlermeldung ausgespruckt. Warum?
if(j==k-1);
/// Warum kann ich fields nicht in einem oder 2 Rutschs belegen? Warum scheint das nur über einzelne push_back zu gehen?
//std::fill(fields.begin(), fields.end()-offset, unique_ptr<cField>(new cField(s,0)));
//std::fill(fields.begin(), fields.end()-offset, std::move(unique_ptr<cField>(new cField(s,0))));
//std::generate(fields.begin()+offset, fields.end(), unique_ptr<cField>(new cField(s,1)));
fields[2].get()->add(15);
std::cout << endl;
for(auto i = std::begin(fields); i != std::end(fields); ++i)
std::cout << ++j <<") Spieler " << i->get()->getOwner() << " mit " << i->get()->getContent() << " Punkten" << std::endl;
}
gamelogic::cField& cBoard::getField(int id)
{
return *fields.at(id).get();
}
cGameManager::cGameManager(const string& na,const string& nb, const int ac):currentRules({&x::RW_Hunters, &x::RW_Hunted, &x::RW_FireAndIce})
/// Der Syntax ist eine Kurzgeschreibweise, siehe unabhängigen Codeschnippsel am Ende des Beitrags
{
activeRule->sayRules();
board=std::make_shared<gamelogic::cBoard>(kSteffi,kOther,activeRule->getBR().getFieldsPerPlayer(),activeRule->getBR().getStartAmountOfstonesPerField());
gamelogic::cField temp(false,0);
initPlayers(na,nb);
}
cBoardRule::cBoardRule(const bool a, const sn b, const sn c, const sn d):
ROR(a),
start_Pa(b),
start_PeK(c),
start_PePa(d)
{
//
}
const sn cBoardRule::getRows(){return ROR;};
/// …
Falls es dir nicht sofort ersichtlich ist, wie das mit den Regeln funktioniert:
Code:
#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
#define sn signed short
enum class cRuleCondSort{exact, more, moreorequal, less, lessorequal};
/*
struct funktionszeiger{
//public:
//funktionszeiger operator(){return this;};
int operator(int a)const{return a;};
bool operator[]const{};
sn operator<>const{};
};
*/
struct Funktionszeiger {
int w,h;
int area() const { return w*h; }
};
struct funktionszeiger { // definiert einen Funktor
bool operator()(const int&a, const int&b) const {
return a <= b;
}
};
class cRuleCond
{
private:
signed int operatorContact; // 0 = && 1 == || 2 == !
std::vector<cRuleCond*> inContactWith;
signed int haveToBe;
sn& argVal;
cRuleCondSort sic;
public:
void addContactCond(cRuleCond& i, signed int o)
{
operatorContact=o;
inContactWith.push_back(&i);
i.operatorContact=o;
i.inContactWith.push_back(this);
};
bool check(const sn targetVal)
{
bool tmp;
switch (sic)
{
case cRuleCondSort::exact:
tmp= (targetVal == haveToBe); return tmp;
case cRuleCondSort::more:
tmp=(targetVal > haveToBe); return tmp;
case cRuleCondSort::moreorequal:
tmp=(targetVal >= haveToBe); return tmp;
case cRuleCondSort::less:
tmp=(targetVal < haveToBe); return tmp;
case cRuleCondSort::lessorequal:
tmp=(targetVal <= haveToBe); return tmp;
default:return false;
};
for(auto i=std::begin(inContactWith); i!=std::end(inContactWith); i++)
{
tmp=this->check(targetVal);
}
/*
for_each(inContactWith.cbegin(), inContactWith.cend(),
[targetVal,tmp,this]() mutable { tmp=this->check(targetVal);});
*/
}
cRuleCond(const sn h, const cRuleCondSort s, sn &tv):haveToBe(h),sic(s),argVal(tv){};
};
class cRule
{
private:
std::vector<cRuleCond*> conditions;
void* pointerToTarget;
funktionszeiger doFunc;
public:
void addCond(cRuleCond& c) {conditions.push_back(&c);}
void tryDo()
{
bool tryIt;/*
for(auto i=std::begin(cRuleCond); i!=std::end(cRuleCond); i++)
{
tryIt=i->check();
}*/
if (tryIt)
{
std::cout << "Es klappt!" << std::endl;
doFunc(conditions[0]->check(2), conditions[1]->check(5));
}
else
std::cout << "Regelverstoß!" << std::endl;
}
/* cRule(void* pt, void* pf):pointerToTarget(pt),doFunc(pf){std::cout << "CTor a"<<std::endl;};*/
cRule(){std::cout << "CTor b"<<std::endl;};
};
Funktionszeiger afaf;
Funktionszeiger ffa;
int main()
{
sn stones_in_A = 10;
sn stones_in_B = 15;
bool playerAAtTurn=false;
cRule canDraw();
cRuleCond cond_MoreThanFifeStonesIn(10,cRuleCondSort::moreorequal,stones_in_A);
cRuleCond cond_StonesBelongsPlayerB((sn)false,cRuleCondSort::exact,(sn&)playerAAtTurn);
cRule DrawNormal();
DrawNormal.addCond(cond_MoreThanFifeStonesIn);
DrawNormal.tryToDo();
}
Der Codeschnippsel:
Code:
namespace x{gamelogic::cRuleBook RW_Hunters("Jägerspiel",
false, 6, 0, 6,
0, 0, 1, 0, false, 0,0,
0,2,false,1,2,6,false,0,false,1,0);}