-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPlayer.cpp
469 lines (368 loc) · 12.7 KB
/
Player.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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
//Kanellaki Maria Anna - 1115201400060
//Matanis Panagiotis - 1115201400297
#include <iostream>
#include "Player.hpp"
#include "DeckBuilder.hpp"
Player::Player(int min, int max)
{
stronghold = GenerateRandomStronghold();
honour = stronghold->getHonour();
minCards = min;
maxCards = max;
numberOfProvinces = 4;
maxHand = 6;
int count = 0;
//creates general decks with all the cards and shuffles them
DeckBuilder *build = new DeckBuilder();
list<GreenCard*> *green = build->createFateDeck();
list<GreenCard*>::iterator it = green->begin();
build->deckShuffler(green);
list<BlackCard*> *black = build->createDynastyDeck();
list<BlackCard*>::iterator it1 = black->begin();
build->deckShuffler(black);
//creates fateDeck with num E[minCards, maxCards] cards from green
for (it=green->begin(); it!=green->end(); it++)
{
if (count == maxCards)
break;
GreenCard *newCard = *it;
fateDeck.pushCard(newCard);
green->remove(*it);
count++;
newCard = nullptr;
delete newCard;
it=green->begin();
}
if (count < minCards) //if deck too small creates a new green deck and adds more
{
green = build->createFateDeck();
build->deckShuffler(green);
for (it=green->begin(); it!=green->end(); it++)
{
if (count == maxCards)
break;
GreenCard *newCard = *it;
fateDeck.pushCard(newCard);
green->remove(*it);
count++;
delete newCard;
it=green->begin();
}
}
//creates dynDeck with num E[minCards, maxCards] cards from black
for (it1=black->begin(); it1!=black->end(); it1++)
{
if (count == maxCards)
break;
BlackCard *newCard = *it1;
dynDeck.pushCard(newCard);
black->remove(*it1);
count++;
delete newCard;
it1=black->begin();
}
if (count < minCards) //if deck too small creates a new green deck and adds more
{
black = build->createDynastyDeck();
build->deckShuffler(black);
for (it1=black->begin(); it1!=black->end(); it1++)
{
if (count == maxCards)
break;
BlackCard *newCard = *it1;
dynDeck.pushCard(newCard);
black->remove(*it1);
count++;
delete newCard;
it1=black->begin();
}
}
//creates provinces with first 4 cards of black
while (provinces.getDynDeck().size() < 5)//4 cards + list.end()
{
build->deckShuffler(black);
if (black->empty()) //if it empties generate a new black deck and shuffle it
{
black = build->createDynastyDeck();
build->deckShuffler(black);
it1 = black->begin();
}
BlackCard *newCard = *it1;
provinces.pushCard(newCard);
black->remove(*it1);
it1=black->begin();
}
//builds hand with first 3 cards of green deck
int i;
for (i=0; i<3; i++) //players start with 3 cards in their hand
{
build->deckShuffler(green);
if (green->empty()) //if it empties generate a new green deck and shuffle it
{
green = build->createFateDeck();
build->deckShuffler(green);
it = green->begin();
}
GreenCard *newCard = *it;
hand.pushCard(newCard);
green->remove(*it);
it = green->begin();
}
delete build;
}
Stronghold * Player::GenerateRandomStronghold() //generates a stronghold with unique name and random values between limits
{
//gets a random name from vector and removes it to avoid doubles
int random = rand()%(names.size()-1)+1;
string name = names[random];
names.erase(names.begin() + random-1);
//random nums within limits for the rest of the values
honour = rand()%4 + 10; //get a random number from [10, 13]
int money = rand()%5 + 8; //get a random number from [8, 12]
int initialDefense = rand()%6 + 10; //get a random number from [10, 15]
//create and return stronghold
Stronghold * strong = new Stronghold(name, 0, honour, money, initialDefense);
return strong;
}
void Player::PrintPlayerStats() //print player's data and decks
{
cout << "Stronghold name: " << stronghold->getName() << endl;
cout << "Honour: " << honour << endl;
cout << "Provinces: " << numberOfProvinces << endl<<endl;
provinces.PrintCards();
cout << endl;
if (hand.isEmpty())
cout << "Hand Empty"<<endl;
else
{
cout << "Hand Cards: " << endl;
hand.PrintCards();
}
if (holdings.isEmpty())
cout << "Holdings: 0"<<endl;
else
{
cout <<"Holdings:" << endl;
holdings.PrintCards();
}
if (army.isEmpty())
cout << "No army" << endl;
else
{
cout <<"Army:" << endl;
army.PrintCards();
}
cout << endl;
}
void Player::untapEverything() //untap every deck of player
{
fateDeck.untapDeck();
provinces.untapDeck();
hand.untapDeck();
holdings.untapDeck();
army.untapDeck();
}
void Player::drawFateCard() //draw a card from fateDeck and add it to hand
{
hand.getCardFrom(fateDeck);
}
void Player::revealProvinces() //reveal all provinces of player
{
provinces.tapDeck();
provinces.revealDeck();
}
void Player::equipCards() //player can equip any green cards from his hand to his provinces and personalities if he wants to
{
string equip, pers;
char ans;
if (hand.isEmpty())
{
cout << "Hand empty. Can't equip cards now" <<endl<<endl;
return;
}
if (army.getDynDeck().empty())
{
cout << "No army. Can't equip cards now" <<endl<<endl;
return;
}
cout << "Do you want to equip a card?"<<endl<<"Enter y for yes, n for no"<<endl;
cin >> ans;
while (ans == 'y' && !hand.isEmpty())
{
cout << "Enter name of card to equip and which personality will equip it" << endl;
cin >> equip >> pers;
GreenCard *bought = reinterpret_cast<GreenCard*>(hand.searchDeck(equip));
BlackCard *location = reinterpret_cast<BlackCard*>(provinces.searchDeck(pers));
if (!bought)
cout << "Invalid hand card"<<endl;
else if (!location)
cout << "Invalid personality"<<endl;
else if (location->getType() != Card::PERSONALITY)
cout << "Invalid card, not a personality"<<endl;
else if (stronghold->getMoney() < bought->getCost())
cout << "Not enough money"<<endl;
else if (location->isTapped())
cout <<"Personality tapped"<<endl;
else
{
stronghold->setMoney(stronghold->getMoney() - bought->getCost()); //pay
stronghold->setMoney(bought->addBonus(stronghold->getMoney(), honour)); //add bonus if player wants
reinterpret_cast<Personality*>(location)->PushGreenCard(bought); //add it to personality's followers or items
cout << "Card successfully equiped"<<endl;
}
delete bought;
delete location;
cout << "Do you want to equip more cards?"<<endl<<"Enter y for yes, n for no"<<endl;
cin >> ans;
}
cout<<endl;
}
void Player::buyCards() //player can buy holdings or personalities from his provinces if he wants to
{
string buy;
char ans;
cout << "Do you want to buy a card?"<<endl<<"Enter y for yes, n for no"<<endl;
cin >> ans;
//buys selected province if enough money and honour and replaces it with an unrevealed card from dynDeck
while (ans == 'y')
{
cout << "Enter name of province to buy" << endl;
cin >> buy;
BlackCard *bought = provinces.searchDeck(buy); //searches from province with name = buy
if (bought)
{
if (!bought->isRevealed())
cout <<"Invalid province"<<endl;
else if (stronghold->getMoney() < bought->getCost())
cout << "Not enough money" << endl;
else if (honour < bought->getHonour())
cout << "Not enough honour" << endl;
else
{
stronghold->setMoney(bought->effectBonus(stronghold->getMoney(), honour)); //pay
//add it to player's holdings or army
if (bought->getType() == Card::HOLDING)
{
holdings.pushCard(bought);
bought->ChainHoldings(holdings.getDeck(), reinterpret_cast<Holding *>(bought)); //check for chains
}
else
army.pushCard(bought);
//replace it with new unrevealed province from dynDeck
provinces.pushCard(dynDeck.popCard(*dynDeck.getDynDeck().begin()));
cout << "Bought card " << bought->getName() << endl;
}
}
else
cout << "Invalid province"<<endl;
delete bought;
cout << "Do you want to buy more cards?"<<endl<<"Enter y for yes, n for no"<<endl;
cin.clear();
cin >> ans;
}
cout<<endl;
}
void Player::prepareForBattle() //activates any untapped personalities the player wants for attack
{
char ans;
list<BlackCard*> arm = army.getDynDeck();
list<BlackCard*>::iterator it;
for (it=arm.begin(); it!=arm.end(); it++)
{
if ((*it)->isTapped()) //tapped means busy somewhere else
continue;
(*it)->PrintCardStats();
cout << "Do you want to use this personality?"<<endl<<"y for yes, n for no"<<endl;
cin >> ans;
if (ans == 'y')
(*it)->setTapped(true); //every tapped personality will attack
}
}
void Player::Attack(Player * target, string prov)
{
list<BlackCard*>::iterator it;
Personality * pers;
Item * item;
BlackCard *prTarget = target->provinces.findTarget(prov);
if (!prTarget)
{
cout << "Invalid target province"<<endl;
return;
}
int ap = army.calculateAttackPoints();
int dp = target->army.calculateDefensePoints(); //without provinces initial defense
if (prTarget->getType() == Card::PERSONALITY) //all followers and items associated with personalities are deleted by their constructor
{
pers = reinterpret_cast<Personality *>(prTarget);
dp += pers->getDefense();
}
if (ap > dp)
{
cout << "Attack successful"<<endl;
//destroy province of target
target->provinces.popCard(prTarget);
if (prTarget->getType() == Card::PERSONALITY)
delete pers;
else
delete item;
target->army.BattleConsequences(false, false, ap, dp); //destroy associated army of target
this->army.BattleConsequences(true, true, ap, dp); //change attacking army
delete prTarget;
cout << "Province destroyed"<<endl;
}
else if (ap == dp)
{
//destroy all attacking and defending armies
target->army.BattleConsequences(false, false, ap, dp);
this->army.BattleConsequences(true, false, ap, dp);
cout << "Draw"<<endl;
}
else
{
target->army.BattleConsequences(false, true, ap, dp); //change associated army of target
this->army.BattleConsequences(true, false, ap, dp); //destroy attacking army
cout << "Attack unsuccessful"<<endl;
}
}
void Player::discardSurplusFateCards() //discards cards from player's hand until it is within its limits
{
int count = 0;
while (hand.getDeck().size() > maxHand)
{
delete hand.popCard(*hand.getDeck().begin());
count++;
}
if (count)
cout << "Discarded "<<count<<" cards"<<endl;
else
cout << "Didn't discard any cards"<<endl;
}
Player::~Player()
{
//delete stronghold;
}
//getters
int Player::getHonour() const
{
return honour;
}
int Player::getNumberOfProvinces() const
{
return numberOfProvinces;
}
Deck &Player::getHand()
{
return hand;
}
DynastyDeck &Player::getProvinces()
{
return provinces;
}
Stronghold *Player::getStronghold() const
{
return stronghold;
}
DynastyDeck &Player::getArmy()
{
return army;
}