Added 2021 solutions
Added 2021 solutions for specker (n = new) and polynomial
This commit is contained in:
parent
2c2dd26302
commit
3c44dff236
459
polynomial.cpp
459
polynomial.cpp
|
@ -1,254 +1,243 @@
|
|||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Polynomial {
|
||||
public:
|
||||
class Term {
|
||||
public:
|
||||
int exponent;
|
||||
int coefficient;
|
||||
Term *next;
|
||||
protected:
|
||||
class Term {
|
||||
protected:
|
||||
Term(int exp, int coeff, Term *n) : exponent(exp), coefficient(coeff), next(n){};
|
||||
friend class Polynomial;
|
||||
};
|
||||
int exponent;
|
||||
int coefficient;
|
||||
Term *next;
|
||||
|
||||
Term *head;
|
||||
int degree;
|
||||
int size;
|
||||
|
||||
Polynomial():head(nullptr), degree(0), size(0) {}
|
||||
Polynomial(const Polynomial &p): head(nullptr), degree(0), size(0) {copy(p);};
|
||||
~Polynomial() {purge();}
|
||||
|
||||
Polynomial & operator =(const Polynomial &p) {clear(); copy(p); return *this;}
|
||||
|
||||
void purge() {
|
||||
Term *l=head;
|
||||
degree=0;
|
||||
size=0;
|
||||
while(l!=nullptr) {
|
||||
Term *q=l;
|
||||
l=l->next;
|
||||
delete q;
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
purge();
|
||||
head=nullptr;
|
||||
degree=0;
|
||||
size=0;
|
||||
}
|
||||
|
||||
void remove(int exp) /* AFAIREI STOIXEIO*/ {
|
||||
Term* temp=head;
|
||||
Term* prev;
|
||||
if(head==nullptr) return;
|
||||
else {
|
||||
if(head->exponent==exp) {
|
||||
head=head->next;
|
||||
delete temp;
|
||||
}
|
||||
else {
|
||||
for(temp = head;temp->next!=nullptr && temp->exponent !=exp;temp = temp->next) {
|
||||
prev=temp;
|
||||
Term(int e, int c, Term *n) {
|
||||
exponent = e;
|
||||
coefficient = c;
|
||||
next = n;
|
||||
}
|
||||
if(temp->exponent==exp) {
|
||||
prev->next = temp->next;
|
||||
delete temp;
|
||||
}
|
||||
else return;
|
||||
}
|
||||
--size;
|
||||
}
|
||||
}
|
||||
|
||||
friend class Polynomial;
|
||||
friend Polynomial operator + (const Polynomial &p, const Polynomial &q);
|
||||
friend Polynomial operator * (const Polynomial &p, const Polynomial &q);
|
||||
friend ostream & operator << (ostream &out, const Polynomial &p);
|
||||
};
|
||||
|
||||
Term *head;
|
||||
|
||||
void addTerm(int expon, int coeff) {
|
||||
if(coeff==0 || expon<0) return;
|
||||
Term *newTerm = new Term(expon,coeff,nullptr);
|
||||
Term *temp = head;
|
||||
if(expon>degree) degree=expon;
|
||||
if(head==nullptr) {
|
||||
newTerm->next=nullptr;
|
||||
head=newTerm;
|
||||
++size;
|
||||
return;
|
||||
void purge() {
|
||||
Term *p = head;
|
||||
while(p != nullptr) {
|
||||
Term *q = p;
|
||||
p = p->next;
|
||||
delete q;
|
||||
}
|
||||
}
|
||||
if(expon>head->exponent) {
|
||||
newTerm->next=head;
|
||||
head=newTerm;
|
||||
++size;
|
||||
return;
|
||||
}
|
||||
if(expon==head->exponent) /* HERE */ {
|
||||
head->coefficient=head->coefficient+newTerm->coefficient;
|
||||
if(head->coefficient==0) remove(head->exponent);
|
||||
return;
|
||||
}
|
||||
while(temp->next!=nullptr) {
|
||||
if(expon==temp->exponent) /*here*/ {
|
||||
temp->coefficient=temp->coefficient+newTerm->coefficient;
|
||||
if(temp->coefficient==0)
|
||||
remove(temp->exponent);
|
||||
return;
|
||||
}
|
||||
if(expon>temp->next->exponent) {
|
||||
newTerm->next = temp->next;
|
||||
temp->next = newTerm;
|
||||
return;
|
||||
}
|
||||
temp = temp->next;
|
||||
}
|
||||
if(newTerm->exponent==temp->exponent) /*HERE*/ {
|
||||
temp->coefficient=temp->coefficient + newTerm->coefficient;
|
||||
if(temp->coefficient==0) remove(temp->exponent);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
newTerm->next=nullptr;
|
||||
temp->next=newTerm;
|
||||
//temp->coefficient=temp->coefficient+newTerm->coefficient;
|
||||
++size;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
double evaluate(double x) {
|
||||
double sum=0;
|
||||
int exp;
|
||||
for(Term *l=head; l!=nullptr; l=l->next) {
|
||||
exp=l->exponent;
|
||||
double expvalue=1;
|
||||
if (exp==0) expvalue=1;
|
||||
else {
|
||||
for(int i=0; i<exp; ++i) {
|
||||
expvalue*=x;
|
||||
}
|
||||
}
|
||||
sum+=(l->coefficient)*expvalue;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
void push_back(const int &e, const int &c) {
|
||||
Term *n = new Term(e, c, nullptr);
|
||||
Term *p;
|
||||
|
||||
friend Polynomial operator+ (const Polynomial &p, const Polynomial &q) {
|
||||
Polynomial r;
|
||||
Polynomial::Term *temp_p = p.head;
|
||||
Polynomial::Term *temp_q = q.head;
|
||||
while(!(temp_p==nullptr && temp_q ==nullptr)) {
|
||||
if(temp_p==nullptr && temp_q!=nullptr) {
|
||||
r.addTerm(temp_q->exponent,temp_q->coefficient);
|
||||
temp_q=temp_q->next;
|
||||
continue;
|
||||
}
|
||||
if(temp_q==nullptr && temp_p!=nullptr) {
|
||||
r.addTerm(temp_p->exponent,temp_p->coefficient);
|
||||
temp_p=temp_p->next;
|
||||
continue;
|
||||
}
|
||||
if(temp_p->exponent == temp_q->exponent) {
|
||||
r.addTerm(temp_p->exponent,temp_p->coefficient + temp_q ->coefficient);
|
||||
temp_p=temp_p->next;
|
||||
temp_q=temp_q->next;
|
||||
}
|
||||
else if(temp_p->exponent > temp_q ->exponent ) {
|
||||
r.addTerm(temp_p->exponent, temp_p->coefficient);
|
||||
temp_p=temp_p->next;
|
||||
}
|
||||
else if(temp_p->exponent < temp_q->exponent) {
|
||||
r.addTerm(temp_q->exponent,temp_q->coefficient);
|
||||
temp_q = temp_q->next;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
friend Polynomial operator* (const Polynomial &p, const Polynomial &q) {
|
||||
Polynomial r[p.size+q.size+30];
|
||||
Polynomial product;
|
||||
int counter=0;
|
||||
for(Polynomial :: Term *i = p.head; i!=nullptr; i = i->next) {
|
||||
for(Polynomial :: Term * j= q.head; j!=nullptr; j = j->next) {
|
||||
r[counter].addTerm(i->exponent+j->exponent, (i->coefficient)*(j->coefficient));
|
||||
}
|
||||
//cout<<r[counter];
|
||||
++counter;
|
||||
}
|
||||
product = r[0];
|
||||
for(int i=1;i<counter;i++) {
|
||||
product = product + r[i];
|
||||
}
|
||||
return product;
|
||||
}
|
||||
if(head == nullptr) {
|
||||
head = n;
|
||||
return;
|
||||
}
|
||||
|
||||
friend ostream & operator << (ostream &out, const Polynomial &p) {
|
||||
if(p.head==nullptr) {
|
||||
out<<"0";
|
||||
return out;
|
||||
p = head;
|
||||
while(p->next != nullptr) {
|
||||
p = p->next;
|
||||
}
|
||||
p->next = n;
|
||||
}
|
||||
for(Polynomial::Term *i = p.head;i!=nullptr;i=i->next) {
|
||||
if(i==p.head) {
|
||||
if(i->exponent==0) {
|
||||
if(i->coefficient < 0) out<<"- "<<-(i->coefficient);
|
||||
else if(i->coefficient > 0) out<<i->coefficient;
|
||||
}
|
||||
else if(i->exponent==1) {
|
||||
if(i->coefficient < 0) {
|
||||
if(i->coefficient==-1) out<<"- "<<"x";
|
||||
else out<<"- "<<-(i->coefficient)<<"x";
|
||||
}
|
||||
else if(i->coefficient > 0) {
|
||||
if(i->coefficient==1) out<<"x";
|
||||
else out<<i->coefficient<<"x";
|
||||
}
|
||||
}
|
||||
else if(i->exponent > 1) {
|
||||
if(i->coefficient < 0) {
|
||||
if(i->coefficient==-1) out<<"- "<<"x^"<<i->exponent;
|
||||
else out<<"- "<<-(i->coefficient)<<"x^"<<i->exponent;
|
||||
}
|
||||
else if(i->coefficient > 0) {
|
||||
if(i->coefficient==1) out<<"x^"<<i->exponent;
|
||||
else out<<i->coefficient<<"x^"<<i->exponent;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(i->exponent==0) {
|
||||
if(i->coefficient < 0) out<<" - "<<-(i->coefficient);
|
||||
else if(i->coefficient > 0) out<<" + "<<i->coefficient;
|
||||
}
|
||||
else if(i->exponent==1) {
|
||||
if(i->coefficient < 0) {
|
||||
if(i->coefficient==-1) out<<" - "<<"x";
|
||||
else out<<" - "<<-(i->coefficient)<<"x";
|
||||
}
|
||||
else if(i->coefficient > 0) {
|
||||
if(i->coefficient==1) out<<" + "<<"x";
|
||||
else out<<" + "<<i->coefficient<<"x";
|
||||
}
|
||||
}
|
||||
else if(i->exponent > 1) {
|
||||
if(i->coefficient < 0) {
|
||||
if(i->coefficient==-1) out<<" - "<<"x^"<<i->exponent;
|
||||
else out<<" - "<<-(i->coefficient)<<"x^"<<i->exponent;
|
||||
}
|
||||
else if(i->coefficient > 0) {
|
||||
if(i->coefficient==1) out<<" + "<<"x^"<<i->exponent;
|
||||
else out<<" + "<<i->coefficient<<"x^"<<i->exponent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//out<<"\n";
|
||||
return out;
|
||||
}
|
||||
|
||||
private:
|
||||
void copy(const Polynomial &p) {
|
||||
for(Term *l=p.head; l!=nullptr; l=l->next) addTerm(l->exponent, l->coefficient);
|
||||
}
|
||||
void copy(const Polynomial &p) {
|
||||
for(Term *i = p.head; i != nullptr; i = i->next) {
|
||||
push_back(i->exponent, i->coefficient);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
Polynomial() {
|
||||
head = nullptr;
|
||||
}
|
||||
|
||||
Polynomial(const Polynomial &p) {
|
||||
head = nullptr;
|
||||
copy(p);
|
||||
}
|
||||
|
||||
~Polynomial() {
|
||||
purge();
|
||||
};
|
||||
|
||||
Polynomial & operator = (const Polynomial &p) {
|
||||
purge();
|
||||
head = nullptr;
|
||||
copy(p);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void addTerm(int e, int c) {
|
||||
Term *n = new Term(e, c, nullptr);
|
||||
Term *p, *q;
|
||||
|
||||
if(c == 0) {
|
||||
delete n;
|
||||
return;
|
||||
}
|
||||
|
||||
if(head == nullptr) {
|
||||
head = n;
|
||||
head->next = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if(head->exponent == e) {
|
||||
head->coefficient += c;
|
||||
if(head->coefficient == 0) {
|
||||
p = head;
|
||||
head = head->next;
|
||||
delete p;
|
||||
}
|
||||
delete n;
|
||||
return;
|
||||
}
|
||||
|
||||
p = head;
|
||||
q = p->next;
|
||||
while(q != nullptr && q->exponent > e) {
|
||||
p = q;
|
||||
q = q->next;
|
||||
}
|
||||
if(q != nullptr && q->exponent == e) {
|
||||
q->coefficient += c;
|
||||
if(q->coefficient == 0) {
|
||||
p->next = q->next;
|
||||
delete q;
|
||||
}
|
||||
delete n;
|
||||
} else {
|
||||
if(n->exponent < p->exponent) {
|
||||
n->next = p->next;
|
||||
p->next = n;
|
||||
} else {
|
||||
n->next = p;
|
||||
head = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
double evaluate(double x) {
|
||||
double result = 0;
|
||||
Term *p = head;
|
||||
while(p != nullptr) {
|
||||
result += (double) p->coefficient * pow(x, p->exponent);
|
||||
p = p->next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
friend Polynomial operator + (const Polynomial &p, const Polynomial &q) {
|
||||
Polynomial result;
|
||||
Term *i, *j, *k;
|
||||
|
||||
i = p.head;
|
||||
j = q.head;
|
||||
|
||||
while(i != nullptr && j != nullptr) {
|
||||
if(i->exponent > j->exponent) {
|
||||
result.addTerm(i->exponent, i->coefficient);
|
||||
i = i->next;
|
||||
}
|
||||
else if(j->exponent > i->exponent) {
|
||||
result.addTerm(j->exponent,j->coefficient);
|
||||
j = j->next;
|
||||
}
|
||||
else {
|
||||
result.addTerm(i->exponent, i->coefficient + j->coefficient);
|
||||
i = i->next;
|
||||
j = j->next;
|
||||
}
|
||||
}
|
||||
|
||||
if(i == nullptr) {
|
||||
k = j;
|
||||
}
|
||||
else if(j == nullptr) {
|
||||
k = i;
|
||||
}
|
||||
|
||||
while(k != nullptr){
|
||||
result.addTerm(k->exponent, k->coefficient);
|
||||
k = k->next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
friend Polynomial operator * (const Polynomial &p, const Polynomial &q) {
|
||||
Polynomial result;
|
||||
|
||||
for(Term *i = p.head; i != nullptr; i = i->next) {
|
||||
for(Term *j = q.head; j != nullptr; j = j->next) {
|
||||
result.addTerm(i->exponent + j->exponent, i->coefficient * j-> coefficient);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
friend ostream & operator << (ostream &out, const Polynomial &p) {
|
||||
Term *n = p.head;
|
||||
|
||||
if(n == nullptr) {
|
||||
out << "0";
|
||||
return out;
|
||||
}
|
||||
|
||||
if(n->coefficient < 0)
|
||||
out << "- ";
|
||||
if(abs(n->coefficient) != 1)
|
||||
out << abs(n->coefficient);
|
||||
if(n->exponent == 0 && abs(n->coefficient) == 1)
|
||||
out << "1";
|
||||
if(n->exponent == 1)
|
||||
out << "x";
|
||||
else if(n->exponent != 0)
|
||||
out << "x^" << n->exponent;
|
||||
n = n->next;
|
||||
while(n != nullptr) {
|
||||
if(n->coefficient < 0) {
|
||||
out << " - ";
|
||||
}
|
||||
else {
|
||||
out << " + ";
|
||||
}
|
||||
if(abs(n->coefficient) != 1 || n->exponent == 0) {
|
||||
out << abs(n->coefficient);
|
||||
}
|
||||
if(n->exponent == 1) {
|
||||
out << "x";
|
||||
}
|
||||
else if(n->exponent != 0) {
|
||||
out << "x^" << n->exponent;
|
||||
}
|
||||
n = n->next;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int main() {
|
||||
Polynomial p;
|
||||
p.addTerm(1, 3);
|
||||
p.addTerm(2, 1);
|
||||
p.addTerm(0, -1);
|
||||
Polynomial q(p);
|
||||
q.addTerm(1, -3);
|
||||
q.addTerm(3, -12);
|
||||
cout << "P(X) = " << p << endl;
|
||||
cout << "P(1) = " << p.evaluate(1) << endl;
|
||||
cout << "Q(X) = " << q << endl;
|
||||
cout << "Q(1) = " << q.evaluate(1) << endl;
|
||||
cout << "(P+Q)(X) = " << p+q << endl;
|
||||
cout << "(P*Q)(X) = " << p*q << endl;
|
||||
}
|
||||
|
|
130
specker1n.cpp
Normal file
130
specker1n.cpp
Normal file
|
@ -0,0 +1,130 @@
|
|||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Move {
|
||||
public:
|
||||
|
||||
// Take sc coins from heap sh and put tc coins to heap th.
|
||||
|
||||
Move(int sh, int sc, int th, int tc) {
|
||||
sourceHeap = sh;
|
||||
sourceCoins = sc;
|
||||
targetHeap = th;
|
||||
targetCoins = tc;
|
||||
}
|
||||
|
||||
int getSource() const { return sourceHeap; }
|
||||
int getSourceCoins() const { return sourceCoins; }
|
||||
int getTarget() const { return targetHeap; }
|
||||
int getTargetCoins() const { return targetCoins; }
|
||||
|
||||
friend ostream & operator << (ostream &out, Move &move) {
|
||||
|
||||
if (move.getTargetCoins() != 0) {
|
||||
out << "takes " << move.getSourceCoins() << " coins from heap " << move.getSource() << " and puts " << move.getTargetCoins() << " coins to heap " << move.getTarget();
|
||||
}
|
||||
else {
|
||||
out << "takes " << move.getSourceCoins() << " coins from heap " << move.getSource() << " and puts nothing";
|
||||
}
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
int sourceHeap, sourceCoins, targetHeap, targetCoins;
|
||||
|
||||
};
|
||||
|
||||
class State {
|
||||
public:
|
||||
|
||||
// State with h heaps, where the i-th heap starts with c[i] coins.
|
||||
// A total of n players are in the game, numbered from 0 to n-1,
|
||||
// and player 0 is the first to play.
|
||||
|
||||
State(int h, const int c[], int n) {
|
||||
|
||||
maxHeaps = h;
|
||||
coins = new int[maxHeaps];
|
||||
for (int i = 0; i < maxHeaps; i++) {
|
||||
coins[i] = c[i];
|
||||
}
|
||||
maxPlayers = n;
|
||||
playing = 0;
|
||||
}
|
||||
|
||||
State(const State &s) {
|
||||
maxHeaps = s.maxHeaps;
|
||||
coins = new int[maxHeaps];
|
||||
for (int i = 0; i < maxHeaps; i++) {
|
||||
coins[i] = s.coins[i];
|
||||
}
|
||||
maxPlayers = s.maxPlayers;
|
||||
playing = s.playing;
|
||||
}
|
||||
|
||||
~State() {
|
||||
delete[] coins;
|
||||
}
|
||||
|
||||
int getHeaps() const { return maxHeaps; }
|
||||
int getCoins(int h) const throw(logic_error) {
|
||||
if (h < 0 || h >= maxHeaps) {
|
||||
throw logic_error("Invalid heap");
|
||||
}
|
||||
else {
|
||||
return coins[h];
|
||||
}
|
||||
}
|
||||
|
||||
int getPlayers() const { return maxPlayers; }
|
||||
int getPlaying() const { return playing; }
|
||||
|
||||
void next(const Move &move) throw(logic_error) {
|
||||
if ((move.getSource() < 0 || move.getSource() >= maxHeaps) || (move.getTarget() < 0 || move.getTarget() >= maxHeaps)) {
|
||||
throw logic_error("Heaps go from 0 to " + maxHeaps);
|
||||
}
|
||||
else if (move.getSourceCoins() < 1 || move.getTargetCoins() < 0) {
|
||||
throw logic_error("Invalid move");
|
||||
}
|
||||
else if (move.getSourceCoins() <= move.getTargetCoins() || move.getSourceCoins() > getCoins(move.getSource())) {
|
||||
throw logic_error("Not enough coins");
|
||||
}
|
||||
else {
|
||||
|
||||
|
||||
coins[move.getSource()] -= move.getSourceCoins();
|
||||
coins[move.getTarget()] += move.getTargetCoins();
|
||||
|
||||
if (playing == maxPlayers - 1) playing = 0;
|
||||
else playing++;
|
||||
|
||||
}
|
||||
}
|
||||
bool winning() const {
|
||||
int total;
|
||||
for (int i = 0; i < maxHeaps; i++) {
|
||||
total += coins[i];
|
||||
}
|
||||
if (total != 0) return false;
|
||||
else return true;
|
||||
}
|
||||
|
||||
|
||||
friend ostream & operator << (ostream &out, const State &state) {
|
||||
out << state.getCoins(0);
|
||||
for (int i = 1; i < state.getHeaps(); i++) {
|
||||
out << ", " << state.getCoins(i);
|
||||
}
|
||||
out << " with " << state.getPlaying() << "/" << state.getPlayers() << " playing next";
|
||||
return out;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
int maxHeaps, maxPlayers, playing;
|
||||
int *coins;
|
||||
};
|
129
specker2n.cpp
Normal file
129
specker2n.cpp
Normal file
|
@ -0,0 +1,129 @@
|
|||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Player {
|
||||
public:
|
||||
Player(const string &n) {
|
||||
playerName = n;
|
||||
}
|
||||
virtual ~Player() {
|
||||
playerName.clear();
|
||||
}
|
||||
|
||||
virtual const string & getType() const = 0;
|
||||
virtual Move play(const State &s) = 0;
|
||||
|
||||
friend ostream & operator << (ostream &out, const Player &player) {
|
||||
out << player.getType() << " player " << player.playerName;
|
||||
return out;
|
||||
}
|
||||
|
||||
protected:
|
||||
string playerName;
|
||||
};
|
||||
|
||||
class GreedyPlayer: public Player {
|
||||
public:
|
||||
GreedyPlayer(const string &n) : Player(n) {
|
||||
playerType = "Greedy";
|
||||
}
|
||||
|
||||
virtual const string & getType() const override { return playerType; }
|
||||
|
||||
virtual Move play(const State &s) override {
|
||||
int mostCoins = 0;
|
||||
for (int i = 0; i < s.getHeaps(); i++) {
|
||||
if (s.getCoins(i) > s.getCoins(mostCoins)) {
|
||||
mostCoins = i;
|
||||
}
|
||||
}
|
||||
return Move (mostCoins, s.getCoins(mostCoins), 0, 0);
|
||||
}
|
||||
|
||||
private:
|
||||
string playerType;
|
||||
};
|
||||
|
||||
class SpartanPlayer: public Player {
|
||||
public:
|
||||
SpartanPlayer(const string &n) : Player(n) {
|
||||
playerType = "Spartan";
|
||||
}
|
||||
|
||||
virtual const string & getType() const override { return playerType; }
|
||||
|
||||
virtual Move play(const State &s) override {
|
||||
int mostCoins = 0;
|
||||
for (int i = 0; i < s.getHeaps(); i++) {
|
||||
if (s.getCoins(i) > s.getCoins(mostCoins)) {
|
||||
mostCoins = i;
|
||||
}
|
||||
}
|
||||
return Move (mostCoins, 1, 0, 0);
|
||||
}
|
||||
|
||||
private:
|
||||
string playerType;
|
||||
};
|
||||
|
||||
class SneakyPlayer: public Player {
|
||||
public:
|
||||
SneakyPlayer(const string &n) : Player(n) {
|
||||
playerType = "Sneaky";
|
||||
}
|
||||
|
||||
virtual const string & getType() const override { return playerType; }
|
||||
|
||||
virtual Move play(const State &s) override {
|
||||
int i = 0;
|
||||
while(s.getCoins(i) == 0) { i++; }
|
||||
|
||||
int leastCoins = i;
|
||||
|
||||
for (int i = leastCoins + 1; i < s.getHeaps(); i++) {
|
||||
if (s.getCoins(i) != 0 && s.getCoins(i) < s.getCoins(leastCoins)) {
|
||||
leastCoins = i;
|
||||
}
|
||||
}
|
||||
return Move(leastCoins, s.getCoins(leastCoins), 0, 0);
|
||||
}
|
||||
|
||||
private:
|
||||
string playerType;
|
||||
};
|
||||
|
||||
class RighteousPlayer: public Player {
|
||||
public:
|
||||
RighteousPlayer(const string &n) : Player(n) {
|
||||
playerType = "Righteous";
|
||||
}
|
||||
|
||||
virtual const string & getType() const override { return playerType; }
|
||||
|
||||
virtual Move play(const State &s) override {
|
||||
int mostCoins = 0, leastCoins = 0, coins;
|
||||
for (int i = 0; i < s.getHeaps(); i++) {
|
||||
if (s.getCoins(i) > s.getCoins(mostCoins)) {
|
||||
mostCoins = i;
|
||||
}
|
||||
if (s.getCoins(i) < s.getCoins(leastCoins)) {
|
||||
leastCoins = i;
|
||||
}
|
||||
}
|
||||
if (s.getCoins(mostCoins) % 2 == 0) {
|
||||
coins = s.getCoins(mostCoins) / 2;
|
||||
}
|
||||
else {
|
||||
coins = (s.getCoins(mostCoins) / 2) + 1;
|
||||
}
|
||||
return Move(mostCoins, coins, leastCoins, coins - 1);
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
string playerType;
|
||||
};
|
||||
|
80
specker3n.cpp
Normal file
80
specker3n.cpp
Normal file
|
@ -0,0 +1,80 @@
|
|||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Game {
|
||||
public:
|
||||
Game(int h, int p) {
|
||||
maxHeaps = h; maxPlayers = p;
|
||||
heapCounter = 0;
|
||||
playerCounter = 0;
|
||||
heaps = new int[maxHeaps];
|
||||
players = new Player*[maxPlayers];
|
||||
}
|
||||
~Game() {
|
||||
delete[] heaps;
|
||||
delete[] players;
|
||||
}
|
||||
|
||||
void addHeap(int c) throw(logic_error) {
|
||||
if (c < 0) {
|
||||
throw logic_error("Coins can't be less than zero");
|
||||
}
|
||||
else if (heapCounter == maxHeaps) {
|
||||
throw logic_error("Cannot add more heaps");
|
||||
}
|
||||
else {
|
||||
heaps[heapCounter] = c;
|
||||
heapCounter++;
|
||||
}
|
||||
|
||||
}
|
||||
void addPlayer(Player *p) throw(logic_error) {
|
||||
if (playerCounter == maxPlayers) {
|
||||
throw logic_error("Cannot add more players");
|
||||
}
|
||||
else {
|
||||
players[playerCounter] = p;
|
||||
playerCounter++;
|
||||
}
|
||||
}
|
||||
void play(ostream &out) throw(logic_error) {
|
||||
if (playerCounter != maxPlayers || heapCounter != maxHeaps) {
|
||||
throw logic_error("Not enough players/heaps");
|
||||
}
|
||||
else {
|
||||
State s(maxHeaps, heaps, maxPlayers);
|
||||
while (!s.winning()) {
|
||||
out << "State: " << s << endl;
|
||||
out << *getPlayer(s.getPlaying()) << " " << players[s.getPlaying()]->play(s) << endl;
|
||||
s.next(players[s.getPlaying()]->play(s));
|
||||
|
||||
}
|
||||
out << "State: " << s << endl;
|
||||
int winner;
|
||||
if (s.getPlaying() == 0) winner = maxPlayers - 1;
|
||||
else winner = s.getPlaying() - 1;
|
||||
out << *players[winner] << " wins" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int getPlayers() const { return maxPlayers; }
|
||||
|
||||
const Player *getPlayer(int p) const throw(logic_error) {
|
||||
if (p < 0 || p > maxPlayers) {
|
||||
throw logic_error("No such player");
|
||||
}
|
||||
else {
|
||||
return players[p];
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
int maxHeaps, maxPlayers, heapCounter, playerCounter;
|
||||
int *heaps;
|
||||
Player **players;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in a new issue