-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathempire.h
284 lines (231 loc) · 9.18 KB
/
empire.h
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
/*
* Copyright (C) 1987, 1988 Chuck Simmons
*
* See the file COPYING, distributed with empire, for restriction
* and warranty information.
*/
/*
empire.h -- type and constant declarations
*/
#include <stdbool.h>
#ifndef NULL
#define NULL 0
#endif
typedef unsigned char uchar;
typedef long loc_t; /* represent a board location in 4-digit form */
typedef long count_t; /* for iterating over or counting board locations */
#define ASSERT(x) \
if (!(x)) assert("x", __FILE__, __LINE__);
#define ABORT assert("aborting", __FILE__, __LINE__)
/* directions one can move */
#define NORTH 0
#define NORTHEAST 1
#define EAST 2
#define SOUTHEAST 3
#define SOUTH 4
#define SOUTHWEST 5
#define WEST 6
#define NORTHWEST 7
#define NUMTOPS 3 /* number of lines at top of screen for messages */
#define NUMSIDES 6 /* number of lines at side of screen */
/*
* This used to be 80, and that was appropriate back when this game was
* played on hardware terminals. Nowadays it's almost certain to be running
* on a software terminal emulator that would have been considered
* dizzyingly huge back in the day. Memory is cheap, we'll leave some
* headroom.
*/
#define STRSIZE 400 /* number of characters in a string */
/* Information we maintain about cities. */
#define UNOWNED 0
#define USER 1
#define COMP 2
/* Piece types. */
#define ARMY 0
#define FIGHTER 1
#define PATROL 2
#define DESTROYER 3
#define SUBMARINE 4
#define TRANSPORT 5
#define CARRIER 6
#define BATTLESHIP 7
#define SATELLITE 8
#define NUM_OBJECTS 9 /* number of defined objects */
#define NOPIECE ((char)255) /* a 'null' piece */
#define LIST_SIZE 5000 /* max number of pieces on board */
typedef struct city_info {
loc_t loc; /* location of city */
uchar owner; /* UNOWNED, USER, COMP */
long func[NUM_OBJECTS]; /* function for each object */
long work; /* units of work performed */
char prod; /* item being produced */
} city_info_t;
/*
Types of programmed movement. Use negative numbers for special
functions, use positive numbers to move toward a specific location.
*/
#define NOFUNC -1 /* no programmed function */
#define RANDOM -2 /* move randomly */
#define SENTRY -3 /* sleep */
#define FILL -4 /* fill transport */
#define LAND -5 /* land fighter at city */
#define EXPLORE -6 /* piece explores nearby */
#define ARMYLOAD -7 /* army moves toward and boards a transport */
#define ARMYATTACK -8 /* army looks for city to attack */
#define TTLOAD -9 /* transport moves toward loading armies */
#define REPAIR -10 /* ship moves toward port */
#define WFTRANSPORT -11 /* army boards a transport */
#define MOVE_N -12 /* move north */
#define MOVE_NE -13 /* move northeast */
#define MOVE_E -14 /* move east */
#define MOVE_SE -15 /* move southeast */
#define MOVE_S -16 /* move south */
#define MOVE_SW -17 /* move southwest */
#define MOVE_W -18 /* move west */
#define MOVE_NW -19 /* move northwest */
/* Index to list of function names. */
#define FUNCI(x) (-(x)-1)
/*
Macro to convert a movement function into a direction.
*/
#define MOVE_DIR(a) (-(a) + MOVE_N)
/*
Information we maintain about each piece.
*/
typedef struct { /* ptrs for doubly linked list */
struct piece_info *next; /* pointer to next in list */
struct piece_info *prev; /* pointer to prev in list */
} link_t;
typedef struct piece_info {
link_t piece_link; /* linked list of pieces of this type */
link_t loc_link; /* linked list of pieces at a location */
link_t cargo_link; /* linked list of cargo pieces */
int owner; /* owner of piece */
int type; /* type of piece */
loc_t loc; /* location of piece */
long func; /* programmed type of movement */
short hits; /* hits left */
int moved; /* moves made */
struct piece_info *ship; /* pointer to containing ship */
struct piece_info *cargo; /* pointer to cargo list */
short count; /* count of items on board */
short range; /* current range (if applicable) */
} piece_info_t;
/*
Macros to link and unlink an object from a doubly linked list.
*/
#define LINK(head, obj, list) \
{ \
obj->list.prev = NULL; \
obj->list.next = head; \
if (head) head->list.prev = obj; \
head = obj; \
}
#define UNLINK(head, obj, list) \
{ \
if (obj->list.next) obj->list.next->list.prev = obj->list.prev; \
if (obj->list.prev) \
obj->list.prev->list.next = obj->list.next; \
else \
head = obj->list.next; \
obj->list.next = NULL; /* encourage mem faults in buggy code */ \
obj->list.prev = NULL; \
}
/* macros to set map and list of an object */
#define MAP(owner) ((owner) == USER ? user_map : comp_map)
#define LIST(owner) ((owner) == USER ? user_obj : comp_obj)
/* macro to step through adjacent cells */
#define FOR_ADJ(loc, new_loc, i) \
for (i = 0; (i < 8 ? new_loc = loc + dir_offset[i], 1 : 0); i++)
#define FOR_ADJ_ON(loc, new_loc, i) \
FOR_ADJ(loc, new_loc, i) if (map[new_loc].on_board)
/*
We maintain attributes for each piece. Attributes are currently constant,
but the way has been paved to allow user's to change attributes at the
beginning of a game.
*/
#define INFINITY 10000000 /* a large number */
typedef struct piece_attr {
char sname; /* eg 'C' */
char name[20]; /* eg "aircraft carrier" */
char nickname[20]; /* eg "carrier" */
char article[20]; /* eg "an aircraft carrier" */
char plural[20]; /* eg "aircraft carriers" */
char terrain[4]; /* terrain piece can pass over eg "." */
uchar build_time; /* time needed to build unit */
uchar strength; /* attack strength */
uchar max_hits; /* number of hits when completely repaired */
uchar speed; /* number of squares moved per turn */
uchar capacity; /* max objects that can be held */
long range; /* range of piece */
} piece_attr_t;
/*
There are 3 maps. 'map' describes the world as it actually
exists; it tells whether each map cell is land, water or a city;
it tells whether or not a square is on the board.
'user_map' describes the user's view of the world. 'comp_map' describes
the computer's view of the world.
As of the 1.7 version, MAP_WIDTH and MAP_HEIGHT are now free paramaters.
You can change them and the code will adjust properly.
*/
#define MAP_WIDTH 100
#define MAP_HEIGHT 60
#define MAP_SIZE (MAP_WIDTH * MAP_HEIGHT)
/* #define NUM_CITY 70 */
/* #define NUM_CITY (MAP_SIZE / 85) */
#define NUM_CITY ((100 * (MAP_WIDTH + MAP_HEIGHT)) / 228)
typedef struct real_map { /* a cell of the actual map */
char contents; /* MAP_LAND, MAP_SEA, or MAP_CITY */
bool on_board; /* TRUE iff on the board */
city_info_t *cityp; /* ptr to city at this location */
piece_info_t *objp; /* list of objects at this location */
} real_map_t;
typedef struct view_map { /* a cell of one player's world view */
char contents; /* MAP_LAND, MAP_SEA, MAP_CITY, 'A', 'a', etc */
long seen; /* date when last updated */
} view_map_t;
/* Define information we maintain for a pathmap. */
typedef struct {
int cost; /* total cost to get here */
int inc_cost; /* incremental cost to get here */
char terrain; /* T_LAND, T_WATER, T_UNKNOWN, T_PATH */
} path_map_t;
#define T_UNKNOWN 0
#define T_PATH 1
#define T_LAND 2
#define T_WATER 4
#define T_AIR (T_LAND | T_WATER)
/* A record for counts we obtain when scanning a continent. */
typedef struct {
int user_cities; /* number of user cities on continent */
int user_objects[NUM_OBJECTS];
int comp_cities;
int comp_objects[NUM_OBJECTS];
int size; /* size of continent in cells */
int unowned_cities; /* number of unowned cities */
int unexplored; /* unexplored territory */
} scan_counts_t;
/* Define useful constants for accessing sectors. */
#define SECTOR_ROWS 5 /* number of vertical sectors */
#define SECTOR_COLS 2 /* number of horizontal sectors */
#define NUM_SECTORS (SECTOR_ROWS * SECTOR_COLS) /* total sectors */
#define ROWS_PER_SECTOR ((MAP_HEIGHT + SECTOR_ROWS - 1) / SECTOR_ROWS)
#define COLS_PER_SECTOR ((MAP_WIDTH + SECTOR_COLS - 1) / SECTOR_COLS)
/* Information we need for finding a path for moving a piece. */
typedef struct {
char city_owner; /* char that represents home city */
char *objectives; /* list of objectives */
int weights[11]; /* weight of each objective */
} move_info_t;
/* special weights */
#define W_TT_BUILD -1 /* special cost for city building a tt */
/* List of cells in the perimeter of our searching for a path. */
typedef struct {
long len; /* number of items in list */
long list[MAP_SIZE]; /* list of locations */
} perimeter_t;
enum win_t { no_win, wipeout_win, ratio_win };
#define MAP_LAND '+'
#define MAP_SEA '.'
#define MAP_CITY '*'
/* end */