【程设作业】 魔兽世界三 开战

是大模拟啦(本文没有任何值得看的点,仅此记录一次作业)

solver

总体写得还是挺舒服的,不用动脑子真是太快乐了。

还是有不少可以改进的地方
有几个小地方偷懒设成共有变量了
protected好像不能给传进来的同一个类来用,友元又不会,有点糟糕
bool fight(Warrior* opponent) 这里,opponent的私有变量和保护变量并不知道怎么去调用

有一个可以mark的点,大概是并不会用类的成员变量的指针
尝试了一些都会CE:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class A{
void func1(){}
void func2(){}
public:
void main(){
static void (A::*func[2])() = {func1,func2};
//static void (*func[2])() = {func1,func2}; 会 CE
//func[0]() 会CE
//this -> func[0]() 会CE
//(this -> func[0])() 会CE
//(this -> *func[0])() 会CE
//暂且不知道什么情况下不会CE
}
}

程设课后在张老师和大佬的帮助下解决了这个问题。
->* 是一个不能重载的保留字,专门用来调用指针指向的函数指针,和.* 是一样的,
所以正确的方法是 (this ->* func[0])()
然后再次被安利 $\lambda$ 表达式,以及若干C++11~ C++14~ C++17~ C++20特性。
现在觉得我的代码好丑啊~
希望在魔兽四的时候试图用上包括 $\lambda$ 表达式,然后用一些高版本C++语法糖和特性让代码更美化一些
C++好难sigh

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
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
#include<iomanip>
#include<cstdlib>
#include<assert.h>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<string>
using std::cout;
using std::string;
using std::endl;
using std::to_string;
using std::swap;
using std::vector;
using std::min;
#define DRAGON 0
#define NINJA 1
#define ICEMAN 2
#define LION 3
#define WOLF 4
#define RED 0
#define BLUE 1
int initHP[5],initATK[5],N,K;
bool gameover;
const string warriors_name[5] = {"dragon","ninja","iceman","lion","wolf"};
const string weapon_name[3] = {"sword","bomb","arrow"};
const int L[2][5] = {{ICEMAN,LION,WOLF,NINJA,DRAGON},{LION,DRAGON,NINJA,ICEMAN,WOLF}};
int timeclock;//全局变量 时间戳
#define out_time() printf("%03d:%02d ",timeclock/60,timeclock%60)
class Warrior{
int cnt,warriors_id,type;
int curcity,color;
string scolor,stype;
static int total;
//private:
protected:
int HP,ATK;
public:
int weapon[4] = {0,0,0,0};
int weapon_total;
//sword,bomb,用过的arrow,没用过的arrow
Warrior(string scolor,int type,int warriors_id,int weapon1 = -1,int weapon2 = -1)
:warriors_id(warriors_id),type(type),color((scolor == (string)"red") ? RED : BLUE),
scolor(scolor),stype(warriors_name[type]),
HP(initHP[type]),ATK(initATK[type]),weapon_total(0)
{
curcity = color == RED ? 0 : N+1;
if(weapon1 != -1) weapon[weapon1] = 1;//表示武器的cnt有多少
if(weapon2 != -1) weapon[weapon2] = 1;//表示武器的cnt有多少
swap(weapon[2],weapon[3]);
update_weapon();
out_time();
cout << this -> outstr() << " born" << endl;
}
virtual ~Warrior(){}
virtual void Forward(){};
virtual bool runaway(){return false;};
string outstr(){return scolor + " " + stype + " " + to_string(warriors_id);}
int get_curcity(){return curcity;}
bool dead(){return HP<=0;}

vector<int> weapon_list;
int cur_weapon;
void prefight(){
weapon_list.clear();
cur_weapon = 0;
weapon_total = weapon[0] + weapon[1] + weapon[2] + weapon[3];
//有一说一还是python的sum和列表生成式写得舒服
for(int d=0;d<4;++d)
for(int i=0;i<weapon[d];++i)
weapon_list.push_back(d);
}

void snatch(Warrior* opponent,bool OUTPUT = false){//夺取武器
if (OUTPUT) out_time();
int lim = 10 - (this -> weapon_total);
if(opponent -> weapon[0]){
lim = min(lim,opponent -> weapon[0]);
opponent -> weapon[0] -= lim;
this -> weapon[0] += lim;
if(OUTPUT) cout << this -> outstr() << " took " << lim << " sword from " << opponent -> outstr() << " in city " << this -> curcity << endl;
} else
if(opponent -> weapon[1]){
lim = min(lim,opponent -> weapon[1]);
opponent -> weapon[1] -= lim;
this -> weapon[1] += lim;
if(OUTPUT)cout << this -> outstr() << " took " << lim << " bomb from " << opponent -> outstr() << " in city " << this -> curcity << endl;
} else{
lim = min(lim,opponent -> weapon[2] + opponent -> weapon[3]);
int tmp = min(lim,opponent -> weapon[3]);
opponent -> weapon[3] -= tmp;
opponent -> weapon[2] -= lim - tmp;
this -> weapon[3] += tmp;
this -> weapon[2] += lim - tmp;
if(OUTPUT) cout << this -> outstr() << " took " << lim << " arrow from " << opponent -> outstr() << " in city " << this -> curcity << endl;
}
this -> update_weapon();
opponent -> update_weapon();
}

void report_dead(Warrior* a,Warrior* b){
a -> prefight();
b -> prefight();
out_time();
if(b -> HP <= 0 && a -> HP > 0){
cout << a -> outstr() << " killed " << b -> outstr() << " in city " << a -> curcity << " remaining " << a -> HP << " elements" << endl;
//考虑a要夺取b的武器!
a -> snatch(b);
a -> snatch(b);
a -> snatch(b);
return ;//000:40 red iceman 1 killed blue lion 12 in city 2 remaining 20 elements
}
if(a -> color == BLUE) swap(a,b);
if(b -> HP <= 0 && a -> HP <= 0)
cout << "both " << a -> outstr() << " and " << b -> outstr() << " died in city " << a -> curcity << endl;
//000:40 both red iceman 1 and blue lion 12 died in city 2
else
cout << "both " << a -> outstr() << " and " << b -> outstr() << " were alive in city " << a -> curcity << endl;
//000:40 both red iceman 1 and blue lion 12 were alive in city 2
}

bool fight_zero(){
if(weapon_total == 0) return true;//打不动了
if(weapon_total == weapon[0] && ATK / 5 == 0) return true;//只有剑,但是攻击力为0
return false;
}

void update_weapon(){
weapon_total = weapon[0] + weapon[1] + weapon[2] + weapon[3];
}

void be_fighten(int delta){
HP -= delta;
}

virtual bool fight(Warrior* opponent){
if(this -> weapon_total){
int ttype = weapon_list[cur_weapon];
if(ttype == 0){
int val = (this -> ATK / 5);
opponent -> be_fighten(val);
}//sword
if(ttype == 1){
int val = (this -> ATK * 2 / 5);
opponent -> be_fighten(val);
this -> be_fighten(val/2);
weapon[ttype]--;
}//bomb
if(ttype == 2){
int val = (this -> ATK * 3 / 10);
opponent -> be_fighten(val);
weapon[ttype]--;
}//arrow
if(ttype == 3){
int val = (this -> ATK * 3 / 10);
opponent -> be_fighten(val);
weapon[3]--;
weapon[2]++;
}//arrow
this -> update_weapon();
if(opponent -> dead() || this -> dead()){
if(opponent -> HP <= 0)
return report_dead(this,opponent),true;
return report_dead(opponent,this),true;
}
cur_weapon += 1;
if((unsigned)cur_weapon == weapon_list.size()){
this -> prefight();//cur_weapon = 0
if(this -> fight_zero() && opponent -> fight_zero())
return report_dead(this,opponent),true;
}
} else {
if(this -> fight_zero() && opponent -> fight_zero())
return report_dead(this,opponent),true;
}
return false;
}//主要是看是否结束

void report(){
out_time();
cout << this -> outstr() << " has " << weapon[0] << " sword " << weapon[1] << " bomb " << weapon[2]+weapon[3] << " arrow and " << HP << " elements" << endl;
//000:55 blue wolf 2 has 2 sword 3 bomb 0 arrow and 7 elements
}

virtual void cheering(){
};
#define opp(x) (((x) == RED) ? "blue" : "red")
virtual void forward(){
if(this -> color == RED) curcity ++; else curcity--;

if(1 <= curcity && curcity <= N){
out_time();
cout << this -> outstr() << " marched to city " << this -> curcity << " with " << this -> HP << " elements and force " << this -> ATK << endl;
}else{
assert((this -> color == RED && curcity == N+1) || (this -> color == BLUE && curcity == 0));
out_time();
cout << this -> outstr() << " reached " << opp(this -> color) << " headquarter with " << this -> HP << " elements and force " << this -> ATK << endl;
out_time();
cout << opp(this -> color) << " headquarter was taken" << endl;
}
}

void debug(){
cout << "--------------------debug------------------" << endl;
cout << outstr() << endl;
cout << weapon_total << endl;
cout << weapon[0] << " " << weapon[1] << " " << weapon[2] << " " << weapon[3] << endl;
cout << "ATK/HP:" << ATK << " " << HP << endl;
cout << "-------------------------------------------" << endl;
}

virtual bool iswolf(){
return false;
}
};

class Dragon : public Warrior{
public:
Dragon(string color,int warriors_id):
Warrior(color,DRAGON,warriors_id,warriors_id%3){
}
void cheering(){
out_time();
cout << this -> outstr() << " yelled in city " << this -> get_curcity() << endl;
//003:40 blue dragon 2 yelled in city 4
}
};
class Ninja : public Warrior{
public:
Ninja(string color,int warriors_id):
Warrior(color,NINJA,warriors_id,warriors_id%3,(warriors_id+1)%3){
}

virtual bool fight(Warrior* opponent){
if(this -> weapon_total && weapon_list[cur_weapon] == 1){
int val = (this -> ATK * 2 / 5);
opponent -> be_fighten(val);
// opponent -> HP -= val;
weapon[1]--;
this -> update_weapon();
if(opponent -> dead() || this -> dead())
return report_dead(this,opponent),true;
cur_weapon += 1;
if((unsigned)cur_weapon == weapon_list.size()){
this -> prefight();//cur_weapon = 0
if(this -> fight_zero() && opponent -> fight_zero())
return report_dead(this,opponent),true;
}
return false;
}//炸弹不伤人
return this -> Warrior::fight(opponent);
}//主要是看是否结束

};
class Iceman : public Warrior{
public:
Iceman(string color,int warriors_id):
Warrior(color,ICEMAN,warriors_id,warriors_id%3){
}
void forward(){
int delta = HP / 10;
this -> Warrior::be_fighten(delta);
// HP -= delta;
this -> Warrior::forward();
//000:10 red iceman 1 marched to city 1 with 20 elements and force 30
}//会减血
};
class Lion : public Warrior{
private:
int loyalty;
public:
Lion(string color,int warriors_id,int loyalty):
Warrior(color,LION,warriors_id,warriors_id%3),loyalty(loyalty){
cout << "Its loyalty is " << loyalty << endl;
}
void forward(){
this -> Warrior::forward();
loyalty -= K;
}
bool runaway(){
//到了终点看上去就不会调用这个了
if(loyalty <= 0){
out_time();
cout << outstr() << " ran away" << endl;
return true;
}
return false;
}//虚函数,runaway
};

class Wolf : public Warrior{
public:
Wolf(string color,int warriors_id):Warrior(color,WOLF,warriors_id){
}
bool iswolf(){return true;}
};

class Factory{
private:
int cnt[5],total;
string scolor;
public:
Factory(string scolor):scolor(scolor){
memset(cnt,0,sizeof(cnt));
total = 0;
}
~Factory(){}

Warrior* operator () (const int type,const int rem){
cnt[type] += 1;
total++;
int warriors_id = get_total();
Warrior* cur = 0;
if(type==DRAGON) cur = new Dragon(scolor,warriors_id);
if(type==NINJA) cur = new Ninja(scolor,warriors_id);
if(type==ICEMAN) cur = new Iceman(scolor,warriors_id);
if(type==LION) cur = new Lion(scolor,warriors_id,rem);
if(type==WOLF) cur = new Wolf(scolor,warriors_id);
return cur;
}
int get_total(){
return total;
}
int get_cnt(int x){
return cnt[x];
}
};//工厂类

class Headquarter{
private:
const int *lis;
Factory myfactory;
string scolor;
int curCreate,M;//当前要造那个,司令部血量
bool flag_End_Create = false;
public:
Warrior* vec[22];//要么就是NULL,要么就是有,有的话就可以前进
Headquarter(int id,int M0):
lis(id==0?L[0]:L[1]),myfactory(Factory(id==0?"red":"blue")),scolor(id==0?"red":"blue"),M(M0){
curCreate = 0;
for(int i=0;i<22;++i) vec[i] = NULL;
}
~Headquarter(){
for(int i=0;i<=N+1;++i) if(vec[i]){
delete vec[i];
vec[i] = NULL;
}
// delete myfactory;
}
void Create_main(int cur,int rem){
vec[scolor=="red"?0:N+1] = myfactory(cur,rem);
}
bool Create(){
// printf("Try to Create");
if(M >= initHP[lis[curCreate]]){
int cur = lis[curCreate];
assert( M >= initHP[cur]);
M -= initHP[cur];//开始制造?
curCreate = (curCreate + 1) % 5;
Create_main(cur,M);
return true;
}
return false;
}
void report(){
out_time();
cout << M << " elements in " << scolor << " headquarter" << endl;
//000:50 100 elements in red headquarter
}
};


namespace War3{
Headquarter *Red,*Blue;
void Create(){
Red -> Create();
Blue -> Create();
}//武士降生

void Runaway(){
for(int i=0;i<=N+1;++i){
if(Red -> vec[i] && Red -> vec[i] -> runaway()){
delete Red -> vec[i];
Red -> vec[i] = NULL;
}
if(Blue -> vec[i] && Blue -> vec[i] -> runaway()){
delete Blue -> vec[i];
Blue -> vec[i] = NULL;
}
}
}; // lion逃跑
void Forward(){
for(int i=0;i<=N+1;++i){
//目的地是i的城市
if(i >= 1 && Red -> vec[i-1])
Red -> vec[i-1] -> forward();
if(i <= N+1 && Blue -> vec[i+1])
Blue -> vec[i+1] -> forward();
}
for(int i=N;i>=0;i--)
Red -> vec[i+1] = Red -> vec[i];
Red -> vec[0] = NULL;
for(int i=1;i<=N+1;++i)
Blue -> vec[i-1] = Blue -> vec[i];
Blue -> vec[N+1] = NULL;
//出现了敌人就gg了
//前进的武士按照目的地作为时间序列


if(Red -> vec[N+1] || Blue -> vec[0]){
gameover = true;
}//不错啊,占领了
}; // 武士前进到某一城市

void Greedisgood(){
for(int i=1;i<=N;++i){
if(Red -> vec[i] && Blue -> vec[i]){
Warrior* p0 = Red -> vec[i],*p1 = Blue -> vec[i];
if(p0 -> iswolf() && p1 -> iswolf()) continue;
if(!p0 -> iswolf() && !p1 -> iswolf()) continue;
if(p0 -> iswolf()) swap(p0,p1);
if(p1 -> weapon_total < 10 && p0 -> weapon_total >= 1){
p1 -> snatch(p0,true);
}
//抢走了多少是需要知道的
}
}
}//wolf抢敌人的武器

void Attack(){
for(int i=1;i<=N;++i){
if(Red -> vec[i] && Blue -> vec[i]){
Warrior *p0 = Red -> vec[i],*p1 = Blue -> vec[i];
if(i % 2 == 0) swap(p0,p1);
p0 -> prefight();//武器列表大概清空一下
p1 -> prefight();
for(;;){
// cout << p0->outstr << " " << p1 -> outstr << endl;
if(p0 -> fight(p1)) break;
if(p1 -> fight(p0)) break;
}//打来打去,打到没救
if(Red -> vec[i] -> dead()){
delete Red -> vec[i];
Red -> vec[i] = NULL;
}
if(Blue -> vec[i] -> dead()){
delete Blue -> vec[i];
Blue -> vec[i] = NULL;
}
//编号为奇数的城市,红色的打蓝色的
//战斗结束后看看要不要yelling
if(Red -> vec[i]) Red -> vec[i] -> cheering();
if(Blue -> vec[i]) Blue -> vec[i] -> cheering();
}
}
}
void Report1(){
Red -> report();
Blue -> report();
}
void Report2(){
for(int i=0;i<=N+1;++i){
if(Red -> vec[i]) Red -> vec[i] -> report();
if(Blue -> vec[i]) Blue -> vec[i] -> report();
}
}

void main(){
gameover = false;
void (*func[7])() = {
Create,Runaway,Forward,
Greedisgood,
Attack,
Report1,Report2
};
static const int addtime[7] = {
5,5,25,5,10,5,5
};
//func1 是一个 指向War3::void的指针?
static int M,T;
scanf("%d%d%d%d",&M,&N,&K,&T);
for(int i=0;i<5;++i) scanf("%d",&initHP[i]);
for(int i=0;i<5;++i) scanf("%d",&initATK[i]);
Red = new Headquarter(0,M);
Blue = new Headquarter(1,M);
timeclock = 0;
int cur = 0;
while(timeclock <= T){
func[cur]();
timeclock += addtime[cur];
cur = (cur + 1) % 7;
if(gameover){
delete Red;
delete Blue;
break;
}
}
}
}

int main(){
#ifdef LOCAL
freopen("datapub.in","r",stdin);
freopen("myout.out","w",stdout);
#endif
int T;
scanf("%d",&T);
for(int i=1;i<=T;++i){
printf("Case %d:\n",i);
War3::main();
}
}

嘿嘿,代码到这里就结束了!

今天程设课坐在zjl右边,看他在刷一致收敛那一章的课后作业。听他说应大师已经把抽代学完了,在卷数分三和实分析了。(想想快期中考了,自己除了老师作业就没做过别的东西)

应大师对此十分谦虚,表示张教授卷爆了,卷出天际,自己整的超前的东西并不多。还表示认识的同学已经科研开题。

北大附的卷王的卷度超乎天际,想就是由传说中的宽松氛围的佐料吧。

诶,自己又浪费了一个寒假~但是看番看小说还是很快乐的!