Add files via upload
This commit is contained in:
parent
b6a9a7577f
commit
1f6b16832e
107
specker1.txt
Normal file
107
specker1.txt
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class Move {
|
||||||
|
public:
|
||||||
|
Move(int sh, int sc, int th, int tc) ;
|
||||||
|
|
||||||
|
int getSource() const;
|
||||||
|
int getSourceCoins() const;
|
||||||
|
int getTarget() const;
|
||||||
|
int getTargetCoins() const;
|
||||||
|
|
||||||
|
friend ostream & operator << (ostream &out, const Move &move);
|
||||||
|
|
||||||
|
int a;
|
||||||
|
int b;
|
||||||
|
int c;
|
||||||
|
int d;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
Move::Move(int sh, int sc, int th, int tc) {
|
||||||
|
a=sh;
|
||||||
|
b=sc;
|
||||||
|
c=th;
|
||||||
|
d=tc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Move::getSource() const {return a;}
|
||||||
|
|
||||||
|
int Move::getSourceCoins() const {return b;}
|
||||||
|
|
||||||
|
int Move::getTarget() const {return c;}
|
||||||
|
|
||||||
|
int Move::getTargetCoins() const {return d;}
|
||||||
|
|
||||||
|
ostream & operator << (ostream &out, const Move &move) {
|
||||||
|
out<<"takes "<<move.b<<" coins from heap "<<move.a<<" and puts ";
|
||||||
|
if(move.d>0) out<<move.d<<" coins to heap "<<move.c;
|
||||||
|
else out<<"nothing";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
class State {
|
||||||
|
public:
|
||||||
|
//state with h heaps, where the i-th heaps starts with c[i] coins.
|
||||||
|
State(int h, const int c[]);
|
||||||
|
~State();
|
||||||
|
|
||||||
|
void next(const Move &move) throw(logic_error);
|
||||||
|
bool winning() const;
|
||||||
|
|
||||||
|
int getHeaps() const;
|
||||||
|
int getCoins(int h) const throw(logic_error);
|
||||||
|
|
||||||
|
friend ostream & operator << (ostream &out, const State &state);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int *heap;
|
||||||
|
int heapsum;
|
||||||
|
};
|
||||||
|
|
||||||
|
State::State(int h, const int c[]) {
|
||||||
|
heap=new int[h];
|
||||||
|
heapsum=h;
|
||||||
|
for(int i=0; i<heapsum; i++) heap[i]=c[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
State::~State() {delete[] heap; }
|
||||||
|
|
||||||
|
void State::next(const Move &move) throw(logic_error) {
|
||||||
|
|
||||||
|
if(move.a<0 || move.a>=heapsum || move.c<0 || move.c>=heapsum)throw logic_error("invalid heap");
|
||||||
|
|
||||||
|
else if(move.b<=0 || move.d<0 || heap[move.a]<move.b || move.d>=move.b)
|
||||||
|
throw logic_error("invalid coin quantity");
|
||||||
|
|
||||||
|
else {
|
||||||
|
heap[move.a]-=move.b;
|
||||||
|
heap[move.c]+=move.d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool State::winning() const {
|
||||||
|
bool win=true;
|
||||||
|
for(int i=0; i<heapsum; i++)
|
||||||
|
if(heap[i]!=0) win=false;
|
||||||
|
return win;
|
||||||
|
}
|
||||||
|
|
||||||
|
int State::getHeaps() const {
|
||||||
|
return heapsum;
|
||||||
|
}
|
||||||
|
|
||||||
|
int State::getCoins(int h) const throw(logic_error) {
|
||||||
|
if(h<0 || h>=heapsum) throw logic_error("invalid heap");
|
||||||
|
else return heap[h];
|
||||||
|
}
|
||||||
|
|
||||||
|
ostream & operator << (ostream &out, const State &state) {
|
||||||
|
out << state.heap[0];
|
||||||
|
for (int i = 1; i < state.heapsum; i++)
|
||||||
|
out << ", " << state.heap[i];
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
143
specker2.cpp
Normal file
143
specker2.cpp
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class Player {
|
||||||
|
public:
|
||||||
|
Player(const string &n){
|
||||||
|
name=n;
|
||||||
|
};
|
||||||
|
virtual ~Player();
|
||||||
|
|
||||||
|
virtual const string & getType() const=0;
|
||||||
|
virtual Move play(const State &s) =0;
|
||||||
|
|
||||||
|
friend ostream & operator << (ostream &out, const Player &player);
|
||||||
|
|
||||||
|
protected:string name;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class GreedyPlayer :public Player {
|
||||||
|
public:
|
||||||
|
|
||||||
|
GreedyPlayer(const string &n): Player(n) {
|
||||||
|
playertype="Greedy";
|
||||||
|
}
|
||||||
|
|
||||||
|
const string & getType() const override {
|
||||||
|
return playertype;
|
||||||
|
}
|
||||||
|
Move play(const State &s) override {
|
||||||
|
int sHeap=0;
|
||||||
|
int sCoins=0;
|
||||||
|
for(int i=0; i<s.getHeaps(); i++)
|
||||||
|
if(s.getCoins(i)>sCoins) {
|
||||||
|
sHeap=i;
|
||||||
|
sCoins=s.getCoins(i);
|
||||||
|
}
|
||||||
|
Move Greedyplay(sHeap, sCoins, 0, 0);
|
||||||
|
return Greedyplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
string playertype;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SpartanPlayer: public Player {
|
||||||
|
public:
|
||||||
|
SpartanPlayer(const string &n): Player(n) {
|
||||||
|
playertype="Spartan";
|
||||||
|
}
|
||||||
|
|
||||||
|
const string & getType() const override {
|
||||||
|
return playertype;
|
||||||
|
}
|
||||||
|
|
||||||
|
Move play(const State &s) override {
|
||||||
|
int sHeap=0;
|
||||||
|
int sCoins=0;
|
||||||
|
for(int i=0; i<s.getHeaps(); i++)
|
||||||
|
if(s.getCoins(i)>sCoins) {
|
||||||
|
sHeap=i;
|
||||||
|
sCoins=s.getCoins(i);
|
||||||
|
}
|
||||||
|
Move Spartanplay(sHeap, 1, 0, 0);
|
||||||
|
return Spartanplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
string playertype;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SneakyPlayer:public Player {
|
||||||
|
public:
|
||||||
|
SneakyPlayer(const string &n): Player(n) {
|
||||||
|
playertype="Sneaky";
|
||||||
|
}
|
||||||
|
|
||||||
|
const string & getType() const override {
|
||||||
|
return playertype;
|
||||||
|
}
|
||||||
|
|
||||||
|
Move play(const State &s) override {
|
||||||
|
int sHeap=0;
|
||||||
|
int sCoins;
|
||||||
|
if(s.getCoins(0)>0) sCoins=s.getCoins(0);
|
||||||
|
else sCoins=100;
|
||||||
|
for(int i=1; i<s.getHeaps(); i++) {
|
||||||
|
if(s.getCoins(i)<sCoins && s.getCoins(i)>0) {
|
||||||
|
sHeap=i;
|
||||||
|
sCoins=s.getCoins(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Move Sneakyplay(sHeap, sCoins, 0, 0);
|
||||||
|
return Sneakyplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
string playertype;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RighteousPlayer: public Player {
|
||||||
|
public:
|
||||||
|
RighteousPlayer(const string &n): Player(n){
|
||||||
|
playertype="Righteous";
|
||||||
|
}
|
||||||
|
|
||||||
|
const string & getType() const override {
|
||||||
|
return playertype;
|
||||||
|
}
|
||||||
|
|
||||||
|
Move play(const State &s) override {
|
||||||
|
int sHeap=0;
|
||||||
|
int tHeap=0;
|
||||||
|
int maxCoins=0;
|
||||||
|
int minCoins=s.getCoins(0);
|
||||||
|
for(int i=0; i<s.getHeaps(); i++) {
|
||||||
|
if(s.getCoins(i)>maxCoins) {
|
||||||
|
sHeap=i;
|
||||||
|
maxCoins=s.getCoins(i);
|
||||||
|
}
|
||||||
|
if(s.getCoins(i)<minCoins ){
|
||||||
|
tHeap=i;
|
||||||
|
minCoins=s.getCoins(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Move Righteousplay(sHeap, (maxCoins+1)/2, tHeap, ((maxCoins+1)/2)-1);
|
||||||
|
return Righteousplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
string playertype;
|
||||||
|
};
|
||||||
|
|
||||||
|
ostream & operator << (ostream &out, const Player &player) {
|
||||||
|
out<<player.getType()<<" player "<<player.name;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player::~Player() {name.clear();}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
62
specker3.cpp
Normal file
62
specker3.cpp
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class Game{
|
||||||
|
public:
|
||||||
|
Game(int heaps, int players);
|
||||||
|
~Game();
|
||||||
|
|
||||||
|
void addHeap(int coins) throw(logic_error);
|
||||||
|
void addPlayer(Player *player) throw(logic_error);
|
||||||
|
void play(ostream &out) throw(logic_error);
|
||||||
|
|
||||||
|
int heapnum;
|
||||||
|
int playernum;
|
||||||
|
int *c;
|
||||||
|
int currentheap;
|
||||||
|
int currentplayer;
|
||||||
|
Player **playerlist;
|
||||||
|
};
|
||||||
|
|
||||||
|
Game::Game(int heaps, int players) {
|
||||||
|
currentheap=0;
|
||||||
|
currentplayer=0;
|
||||||
|
heapnum=heaps;
|
||||||
|
playernum=players;
|
||||||
|
c=new int[heaps];
|
||||||
|
playerlist= new Player*[players];
|
||||||
|
}
|
||||||
|
|
||||||
|
Game::~Game() {
|
||||||
|
delete[] c;
|
||||||
|
delete[] playerlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::addHeap(int coins) throw(logic_error) {
|
||||||
|
if(coins<0) throw logic_error("negative coins");
|
||||||
|
else if(currentheap>heapnum) throw logic_error("heap overflow");
|
||||||
|
else c[currentheap++]=coins;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::addPlayer(Player *player) throw(logic_error) {
|
||||||
|
if(currentplayer>playernum) throw logic_error("Player overflow");
|
||||||
|
else playerlist[currentplayer++]=player;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::play(ostream &out) throw(logic_error) {
|
||||||
|
if(currentplayer!=playernum || currentheap!=heapnum) throw logic_error("Not filled player or heap positions");
|
||||||
|
else {
|
||||||
|
int y=0;
|
||||||
|
State state(heapnum, c);
|
||||||
|
while(!state.winning()) {
|
||||||
|
out<<"State: "<<state<<endl;
|
||||||
|
out<<*playerlist[y%playernum]<<" "<<playerlist[y%playernum]->play(state)<<endl;
|
||||||
|
state.next(playerlist[y%playernum]->play(state));
|
||||||
|
y++;
|
||||||
|
}
|
||||||
|
out<<"State: "<<state<<endl;
|
||||||
|
out<<*playerlist[(y-1)%playernum]<<" wins"<<endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
62
specker3b.cpp
Normal file
62
specker3b.cpp
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class Game{
|
||||||
|
public:
|
||||||
|
Game(int heaps, int players);
|
||||||
|
~Game();
|
||||||
|
|
||||||
|
void addHeap(int coins) throw(logic_error);
|
||||||
|
void addPlayer(Player *player) throw(logic_error);
|
||||||
|
void play(ostream &out) throw(logic_error);
|
||||||
|
|
||||||
|
int heapnum;
|
||||||
|
int playernum;
|
||||||
|
int *c;
|
||||||
|
int currentheap;
|
||||||
|
int currentplayer;
|
||||||
|
Player **playerlist;
|
||||||
|
};
|
||||||
|
|
||||||
|
Game::Game(int heaps, int players) {
|
||||||
|
currentheap=0;
|
||||||
|
currentplayer=0;
|
||||||
|
heapnum=heaps;
|
||||||
|
playernum=players;
|
||||||
|
c=new int[heaps];
|
||||||
|
playerlist= new Player*[players];
|
||||||
|
}
|
||||||
|
|
||||||
|
Game::~Game() {
|
||||||
|
delete[] c;
|
||||||
|
delete[] playerlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::addHeap(int coins) throw(logic_error) {
|
||||||
|
if(coins<0) throw logic_error("negative coins");
|
||||||
|
else if(currentheap>heapnum) throw logic_error("heap overflow");
|
||||||
|
else c[currentheap++]=coins;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::addPlayer(Player *player) throw(logic_error) {
|
||||||
|
if(currentplayer>playernum) throw logic_error("Player overflow");
|
||||||
|
else playerlist[currentplayer++]=player;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::play(ostream &out) throw(logic_error) {
|
||||||
|
if(currentplayer!=playernum || currentheap!=heapnum) throw logic_error("Not filled player or heap positions");
|
||||||
|
else {
|
||||||
|
int y=0;
|
||||||
|
State state(heapnum, c);
|
||||||
|
while(!state.winning()) {
|
||||||
|
out<<"State: "<<state<<endl;
|
||||||
|
out<<*playerlist[y%playernum]<<" "<<playerlist[y%playernum]->play(state)<<endl;
|
||||||
|
state.next(playerlist[y%playernum]->play(state));
|
||||||
|
y++;
|
||||||
|
}
|
||||||
|
out<<"State: "<<state<<endl;
|
||||||
|
out<<*playerlist[(y-1)%playernum]<<" wins"<<endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue