Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

CSC112 Spring 2016 Examples

2369 views
1
/*
2
* Implementation of a generic attack alpaca.
3
*/
4
#include <cmath>
5
#include <iostream>
6
#include <cstdlib>
7
#include "alpaca.h"
8
9
using namespace std;
10
11
//a hardened version of log. Returns 0 in the case of any
12
//would-be chicanery
13
static double alpacaLog(double x)
14
{
15
double result;
16
17
//handle 0
18
if(x==0) {
19
return 0;
20
}
21
22
//try to get the log
23
result = log(x);
24
25
//any other wierdness will be dealt with
26
if(!isnormal(x)) {
27
result = 0;
28
}
29
30
return result;
31
}
32
33
34
Alpaca::Alpaca(unsigned int power) {
35
this->power = power;
36
37
//set all the defaults
38
hp=100;
39
attackScore=5;
40
defense=0.05;
41
myTurn = false;
42
status = NONE;
43
statusCounter=0;
44
}
45
46
47
void
48
Alpaca::attack(Alpaca *opponent, unsigned int p) {
49
double damage;
50
51
if(!myTurn) return;
52
53
//limit ourselves to our remaining power
54
if(p > power) {
55
p = power;
56
}
57
58
//we use a O(m lg n) attack rate
59
damage = attackScore * alpacaLog(p);
60
61
//opponents can defend according to
62
damage -= (damage * opponent->defense);
63
64
//make it happen, and report it
65
cout << " " << opponent->name()
66
<< " takes " << damage << " points of damage!" << endl;
67
opponent->hp -= damage;
68
69
//we just used some power
70
power -= p;
71
72
//you get one action!
73
myTurn = false;
74
}
75
76
77
void
78
Alpaca::sleep(Alpaca *opponent, unsigned int p) {
79
int r; //number of rounds for the status counter
80
81
if(!myTurn) return;
82
83
//limit ourselves to our remaining power
84
if(p > power) {
85
p = power;
86
}
87
88
//sleep like a alpacaLog. fnord!
89
r = (int) ceil(alpacaLog(p));
90
91
//if the alpaca is currently asleep, we are adding rounds
92
if(opponent->status == ASLEEP) {
93
r = opponent->statusCounter + r;
94
}
95
96
//put the alpaca to sleep
97
power-=p;
98
opponent->status = ASLEEP;
99
opponent->statusCounter = r;
100
cout << " " << opponent->name() << " goes to sleep." << endl;
101
102
//you get one action!
103
myTurn = false;
104
}
105
106
void
107
Alpaca::stun(Alpaca *opponent, unsigned int p) {
108
if(!myTurn) return;
109
int r; //number of rounds for the status counter
110
111
if(!myTurn) return;
112
113
//limit ourselves to our remaining power
114
if(p > power) {
115
p = power;
116
}
117
118
//sleep like a alpacaLog. fnord!
119
r = (int) ceil(alpacaLog(2*p));
120
121
//if the alpaca is currently asleep, we are adding rounds
122
if(opponent->status == STUNNED) {
123
r = opponent->statusCounter + r;
124
}
125
126
//put the alpaca to sleep
127
opponent->status = STUNNED;
128
opponent->statusCounter = r;
129
power-=p;
130
cout << " " << opponent->name() << " suffers a mild concussion!" << endl;
131
132
//you get one action!
133
myTurn = false;
134
}
135
136
137
void
138
Alpaca::decreaseDefense(Alpaca *opponent, unsigned int p) {
139
double d;
140
if(!myTurn) return;
141
142
//limit ourselves to our remaining power
143
if(p > power) {
144
p = power;
145
}
146
147
//decrease the defense according to the alpacaLog growth rate formula
148
d=opponent->defense * 100;
149
if(d>1) {
150
d-=alpacaLog(d) + alpacaLog(p);
151
} else {
152
d-=alpacaLog(p);
153
}
154
155
//we can't do negative defense
156
if(d<0) d = 0;
157
158
//set the defense
159
opponent->defense = d/100.0;
160
cout << " " << opponent->name() << "'s defense falls!" << endl;
161
power -= p;
162
163
//you get one action!
164
myTurn = false;
165
}
166
167
void
168
Alpaca::decreaseAttack(Alpaca *opponent, unsigned int p) {
169
double a;
170
171
if(!myTurn) return;
172
//limit ourselves to our remaining power
173
if(p > power) {
174
p = power;
175
}
176
177
//make it happen
178
a = opponent->attackScore - alpacaLog(opponent->attackScore) - alpacaLog(p);
179
if(a<0) a = 0;
180
power -= p;
181
opponent->attackScore = a;
182
183
cout << " " << opponent->name() << "'s attack falls!" << endl;
184
185
//you get one action!
186
myTurn = false;
187
188
}
189
190
void
191
Alpaca::increaseAttack(unsigned int p) {
192
if(!myTurn) return;
193
194
//limit ourselves to our remaining power
195
if(p > power) {
196
p = power;
197
}
198
199
//raise our attack
200
attackScore += alpacaLog(attackScore) + alpacaLog(p);
201
power-=p;
202
cout << " " << name() << " is getting pumped!" << endl;
203
204
//you get one action!
205
myTurn = false;
206
}
207
208
void
209
Alpaca::increaseDefense(unsigned int p) {
210
if(!myTurn) return;
211
212
//limit ourselves to our remaining power
213
if(p > power) {
214
p = power;
215
}
216
217
//raise our defense
218
defense *= 100;
219
defense += alpacaLog(defense) + alpacaLog(p);
220
if(defense >= 100) defense = 99;
221
defense /= 100.0;
222
power -= p;
223
cout << " " << name() << " looks a little tougher." << endl;
224
225
//you get one action!
226
myTurn = false;
227
}
228
229
void
230
Alpaca::increaseHp(unsigned int p) {
231
if(!myTurn) return;
232
233
//limit ourselves to our remaining power
234
if(p > power) {
235
p = power;
236
}
237
238
//increase the hp
239
hp += alpacaLog(hp) + alpacaLog(p);
240
power-=p;
241
cout << " " << name() << " looks healthier." << endl;
242
243
//you get one action!
244
myTurn = false;
245
}
246
247
//perform multi-attack moves (Each option multiplies the total point
248
//expendature, so 2 combos cost twice as much as 1 move, 3 cost 3, etc.
249
//put points into each attack category, 0 if you don't want to use that
250
void
251
Alpaca::comboAttack(Alpaca *opponent,
252
unsigned int attackPoints,
253
unsigned int sleepPoints,
254
unsigned int stunPoints,
255
unsigned int decDefensePoints,
256
unsigned int decAttackPoints)
257
{
258
if(!myTurn) return;
259
260
//first, get the multiplier
261
int mult=0;
262
if(attackPoints) mult++;
263
if(sleepPoints) mult++;
264
if(stunPoints) mult++;
265
if(decDefensePoints) mult++;
266
if(decAttackPoints) mult++;
267
268
//if there is no multiplier, return. Nothing to do!
269
if(!mult){ myTurn=false; return; }
270
271
//pay the multi-attack cost
272
int sum = attackPoints + sleepPoints + stunPoints + decDefensePoints + decAttackPoints;
273
sum -= sum/mult;
274
if(sum > power) power = 0; else power-=sum;
275
276
//and perform each action
277
if(attackPoints) {
278
myTurn=true;
279
attack(opponent, attackPoints/mult);
280
}
281
282
if(sleepPoints) {
283
myTurn = true;
284
sleep(opponent, sleepPoints/mult);
285
}
286
287
if(stunPoints) {
288
myTurn = true;
289
stun(opponent, stunPoints/mult);
290
}
291
292
if(decDefensePoints) {
293
myTurn = true;
294
decreaseDefense(opponent, decDefensePoints/mult);
295
}
296
297
if(decAttackPoints) {
298
myTurn = true;
299
decreaseAttack(opponent, decDefensePoints/mult);
300
}
301
302
//regardless, our turn ends here!
303
myTurn = false;
304
}
305
306
307
308
//perform a multi-buf move. (Each option multiplies the total point
309
//expendature, so 2 combos cost twice as much as 1 move, and so on.
310
void
311
Alpaca::comboBuf(unsigned int incAttackPoints,
312
unsigned int incDefensePoints,
313
unsigned int incHpPoints)
314
{
315
if(!myTurn) return;
316
317
//first work out the multiplier
318
int mult=0;
319
if(incAttackPoints) mult++;
320
if(incDefensePoints) mult++;
321
if(incHpPoints) mult++;
322
323
//if there is no multiplier, we are done
324
if(!mult) { myTurn = false; return; }
325
326
//pay the multi-attack cost
327
int sum = incAttackPoints + incDefensePoints + incHpPoints;
328
sum -= sum/mult;
329
if(sum > power) power = 0; else power-=sum;
330
331
//do the buffs
332
if(incAttackPoints) {
333
myTurn = true;
334
increaseAttack(incAttackPoints/mult);
335
}
336
337
if(incDefensePoints) {
338
myTurn = true;
339
increaseDefense(incDefensePoints/mult);
340
}
341
342
if(incHpPoints) {
343
myTurn = true;
344
increaseHp(incHpPoints/mult);
345
}
346
}
347
348
349
//buffs you can apply to allies (or enemies if you are nuts)
350
//this works like the combo buf function
351
void
352
Alpaca::bufAlly(Alpaca *ally,
353
unsigned int incAttackPoints,
354
unsigned int incDefensePoints,
355
unsigned int incHpPoints)
356
{
357
if(!myTurn) return;
358
359
//first work out the multiplier
360
int mult;
361
if(incAttackPoints) mult++;
362
if(incDefensePoints) mult++;
363
if(incHpPoints) mult++;
364
365
//if there is no multiplier, we are done
366
if(!mult) { myTurn = false; return; }
367
368
//work out the total cost
369
int powerCost = (incAttackPoints + incDefensePoints + incHpPoints);
370
371
//transfer the power!
372
if(powerCost > power) powerCost = power;
373
power -= powerCost;
374
ally->power += powerCost;
375
376
//and let the alpaca buf itself
377
ally->myTurn = true;
378
ally->comboBuf(incAttackPoints, incDefensePoints, incHpPoints);
379
ally->myTurn = false;
380
381
myTurn = false;
382
}
383
384
385
//checks the remaining alpaca power
386
unsigned int
387
Alpaca::getPower()
388
{
389
return power;
390
}
391
392
393
//checks the attack score of the alpaca
394
double
395
Alpaca::getAttack()
396
{
397
return attackScore;
398
}
399
400
401
//checks the defense score of the alpaca
402
double
403
Alpaca::getDefense()
404
{
405
return defense;
406
}
407
408
409
//checks the hp of the alpaca
410
double
411
Alpaca::getHp()
412
{
413
return hp;
414
}
415
416
//checks the turn status
417
bool
418
Alpaca::isMyTurn()
419
{
420
return myTurn;
421
}
422
423
424
//checks the alpaca status
425
alpacaStatus
426
Alpaca::getStatus()
427
{
428
return status;
429
}
430
431
432
//checks how long the status will remain in effect
433
unsigned int
434
Alpaca::getStatusCounter()
435
{
436
return statusCounter;
437
}
438
439
440
bool
441
Alpaca::isAlive() {
442
return hp > 0 && power != 0;
443
}
444
445
446
/*
447
* This function runs the alpaca round. It starts by beginning the turn
448
* and then checks the alpaca status. If appropriate, it lets an alpaca
449
* act, or it updates statuses.
450
*/
451
void
452
Alpaca::performRound(Alpaca *opponent) {
453
myTurn = true; //it's my turn!
454
455
//act according to the status
456
switch(status) {
457
case NONE:
458
act(opponent);
459
break;
460
461
case ASLEEP:
462
statusCounter--; //sleep this round
463
if(statusCounter <= 0) {
464
status = NONE;
465
cout << name() << " woke up!" << endl;
466
} else {
467
cout << name() << " is asleep." << endl;
468
}
469
break;
470
471
case STUNNED:
472
statusCounter--; //be stunned this round
473
if(statusCounter <=0) {
474
status = NONE;
475
cout << name() << " can move again!" << endl;
476
} else {
477
cout << name() << " is stunned. It may not attack." << endl;
478
if(rand() % 10 <= 3) act(opponent);
479
}
480
break;
481
}
482
483
//end my turn
484
myTurn = false;
485
}
486
487