-
Notifications
You must be signed in to change notification settings - Fork 0
/
Action.hh
134 lines (108 loc) · 2.47 KB
/
Action.hh
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
#ifndef Action_hh
#define Action_hh
#include "Structs.hh"
/**
* A movement is defined by a unit id and a direction.
*/
struct Movement {
int id;
Dir dir;
/**
* Constructor, given a unit identifier and movement direction.
*/
Movement (int id, Dir dir) : id(id), dir(dir) { }
};
/**
* Class that stores the actions requested by a player in a round.
*/
class Action {
friend class Game;
friend class SecGame;
friend class Board;
/**
* Maximum number of movements allowed for a player during one round.
*/
static const int MAX_MOVEMENTS = 1000;
/**
* Number of movements tried so far.
*/
int q_;
/**
* Set of units that have already performed a movement.
*/
set<int> u_;
/**
* List of movements to be performed during this round.
*/
vector<Movement> v_;
/**
* Read/write movements to/from a stream.
*/
Action (istream& is);
static void print_actions (const vector<Movement>& actions, ostream& os);
/**
* Conversion from char to Dir.
*/
static inline Dir c2d (char c) {
switch (c) {
case 'b': return Bottom;
case 'w': return BR;
case 'r': return Right;
case 'x': return RT;
case 't': return Top;
case 'y': return TL;
case 'l': return Left;
case 'z': return LB;
case 'n': return None;
}
_unreachable();
}
/**
* Conversion from Dir to char.
*/
static inline char d2c (Dir d) {
switch (d) {
case Bottom: return 'b';
case BR: return 'w';
case Right: return 'r';
case RT: return 'x';
case Top: return 't';
case TL: return 'y';
case Left: return 'l';
case LB: return 'z';
case None: return 'n';
default: assert(false);
}
_unreachable();
}
public:
/**
* Desert constructor.
*/
Action () : q_(0) { }
/**
* Adds a movement to the action list.
* Fails if a movement is already present for this unit.
*/
inline void command (Movement m) {
_my_assert(++q_ <= MAX_MOVEMENTS, "Too many commands.");
if (u_.find(m.id) != u_.end()) {
cerr << "warning: action already requested for unit " << m.id << endl;
return;
}
int num = int(m.dir);
if (num < 0 or num > 8) {
cerr << "warning: wrong direction " << num << endl;
return;
}
u_.insert(m.id);
v_.push_back(m);
}
/**
* Alias.
*/
inline void command (int id, Dir dir) {
command(Movement(id, dir));
}
};
#endif