-
Notifications
You must be signed in to change notification settings - Fork 0
/
game.cpp
145 lines (124 loc) · 3.08 KB
/
game.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <iostream>
#include <vector>
#include "card.h"
#include "game.h"
#include "player.h"
using std::cout;
using std::endl;
using std::vector;
Game::Game(int num_players) {
player_on_turn = 0;
vector<CardName> kingdom;
kingdom.push_back(COPPER);
kingdom.push_back(SILVER);
kingdom.push_back(GOLD);
kingdom.push_back(ESTATE);
kingdom.push_back(DUCHY);
kingdom.push_back(PROVINCE);
kingdom.push_back(SMITHY);
kingdom.push_back(VILLAGE);
std::random_device rd;
std::mt19937 g(rd());
for (int i = 0; i < num_players; ++i) {
cout << "i: " << i << endl;
Player player;
player.Shuffle(g);
player.DrawToHand(g);
players.push_back(player);
}
MakePiles(kingdom, num_players);
}
void Game::PlayGame(const vector<const Strategy*>& strategies,
std::mt19937& g) {
turn_number = 0;
FinishGame(strategies, g);
}
void Game::FinishGame(const vector<const Strategy*>& strategies,
std::mt19937& g) {
while(PlayTurn(strategies, g));
}
void Game::PlayGame(const vector<const Strategy*>& strategies) {
std::random_device rd;
std::mt19937 g(rd());
PlayGame(strategies, g);
}
bool Game::PlayTurn(const vector<const Strategy*>& strategies,
std::mt19937& g) {
cout << "turn_number: " << turn_number << endl;
cout << "player_on_turn: " << player_on_turn << endl;
ShowPiles();
Player* player = &(players[player_on_turn]);
player->PlayTurn(this, strategies[player_on_turn], g);
return FinishTurn(strategies, g);
}
bool Game::FinishTurn(const vector<const Strategy*>& strategies,
std::mt19937& g) {
if (IsOver()) {
HandleGameOver();
return false;
}
++player_on_turn;
if (player_on_turn >= players.size()) {
player_on_turn = 0;
++turn_number;
}
return true;
}
void Game::HandleGameOver() {
cout << "Game over!" << endl;
ShowPiles();
}
bool Game::IsOver() {
// true if Provinces empty or three piles empty
const Pile* provinces = FindPile(PROVINCE);
if (provinces != nullptr &&
provinces->IsEmpty()) {
return true;
}
if (NumEmptyPiles() >= 3) {
return true;
}
return false;
}
// Eventually needs to handle split/mixed piles.
Pile* Game::FindPile(CardName card_name) {
for (int i = 0; i < piles.size(); ++i) {
Pile* pile = &(piles[i]);
if (pile->contents == card_name) {
return pile;
}
}
return nullptr;
}
int Game::NumEmptyPiles() const {
int num_empty_piles = 0;
for (const Pile& pile : piles) {
if (pile.IsEmpty()) {
++num_empty_piles;
}
}
return num_empty_piles;
}
void Game::MakePiles(const vector<CardName>& kingdom, int num_players) {
for (CardName card_name : kingdom) {
int num_cards = Card::NumInPile(card_name, num_players);
Pile pile(card_name, num_cards);
piles.push_back(pile);
}
}
void Game::ShowPiles() const {
for (const Pile& pile : piles) {
pile.ShowPile();
}
}
vector<Card> Game::CardsAtopPiles() const {
vector<Card> cards;
for (const Pile& pile : piles) {
const Card* card = pile.TopCard();
if (card != nullptr) {
cards.push_back(*card);
delete(card);
}
}
return cards;
}