More type cleanliness; introducing count_t.
[vms-empire.git] / empire.c
1 /*
2  *    Copyright (C) 1987, 1988 Chuck Simmons
3  * 
4  * See the file COPYING, distributed with empire, for restriction
5  * and warranty information.
6  */
7
8 /*
9 empire.c -- this file contains initialization code, the main command
10 parser, and the simple commands.
11 */
12
13 #include <stdio.h>
14 #include <curses.h>     /* Ugh...shouldn't be needed here */
15 #include "empire.h"
16 #include "extern.h"
17
18 void c_examine(void), c_movie(void);
19
20 /*
21  * 03a 01Apr88 aml .Hacked movement algorithms for computer.
22  * 02b 01Jun87 aml .First round of bug fixes.
23  * 02a 01Jan87 aml .Translated to C.
24  * 01b 27May85 cal .Fixed round number update bug. Made truename simple.
25  * 01a 01Sep83 cal .Taken from a Decus tape
26  */
27
28 void
29 empire (void) {
30         void do_command();
31         void print_zoom();
32
33         char order;
34         int turn = 0;
35
36         ttinit (); /* init tty */
37         rndini (); /* init random number generator */
38
39         clear_screen (); /* nothing on screen */
40         pos_str (7, 0, "EMPIRE, Version 5.00 site Amdahl 1-Apr-1988",0,0,0,0,0,0,0,0);
41         pos_str (8, 0, "Detailed directions are in EMPIRE.DOC\n",0,0,0,0,0,0,0,0);
42         (void) refresh ();
43
44         if (!restore_game ()) /* try to restore previous game */
45                 init_game (); /* otherwise init a new game */
46
47         /* Command loop starts here. */
48
49         for (;;) { /* until user quits */
50             if (automove) { /* don't ask for cmd in auto mode */
51                 user_move ();
52                 comp_move (1);
53                 if (++turn % save_interval == 0)
54                         save_game ();
55             }
56             else {
57                 prompt (0,0,0,0,0,0,0,0,0); /* blank top line */
58                 void redisplay();
59                 prompt ("Your orders? ",0,0,0,0,0,0,0,0);
60                 order = get_chx (); /* get a command */
61                 do_command (order);
62             }
63         }
64 }
65
66 /*
67 Execute a command.
68 */
69
70 void
71 do_command (orders)
72 char orders;
73 {
74         void c_debug(), c_quit(void), c_sector(void), c_map(void);
75         void c_give(void);
76
77         char e;
78         int ncycle;
79
80         switch (orders) {
81         case 'A': /* turn on auto move mode */
82                 automove = TRUE;
83                 error ("Now in Auto-Mode",0,0,0,0,0,0,0,0);
84                 user_move ();
85                 comp_move (1);
86                 save_game ();
87                 break;
88
89         case 'C': /* give a city to the computer */
90                 c_give ();
91                 break;
92         
93         case 'D': /* display round number */
94                 error ("Round #%d", date,0,0,0,0,0,0,0);
95                 break;
96
97         case 'E': /* examine enemy map */
98                 if (resigned) c_examine ();
99                 else huh (); /* illegal command */
100                 break;
101
102         case 'F': /* print map to file */
103                 c_map ();
104                 break;
105
106         case 'G': /* give one free enemy move */
107                 comp_move (1);
108                 break;
109
110         case 'H': /* help */
111                 help (help_cmd, cmd_lines);
112                 break;
113
114         case 'J': /* edit mode */
115                 ncycle = cur_sector ();
116                 if (ncycle == -1) ncycle = 0;
117                 edit (sector_loc (ncycle));
118                 break;
119
120         case 'M': /* move */
121                 user_move ();
122                 comp_move (1);
123                 save_game ();
124                 break;
125
126         case 'N': /* give enemy free moves */
127                 ncycle = getint ("Number of free enemy moves: ");
128                 comp_move (ncycle);
129                 save_game ();
130                 break;
131
132         case 'P': /* print a sector */
133                 c_sector ();
134                 break;
135
136         case '\026': /* some interrupt */
137         case 'Q': /* quit */
138                 c_quit ();
139                 break;
140
141         case 'R': /* restore game */
142                 clear_screen ();
143                 e = restore_game ();
144                 break;
145
146         case 'S': /* save game */
147                 save_game ();
148                 break;
149         
150         case 'T': /* trace: toggle save_movie flag */
151                 save_movie = !save_movie;
152                 if (save_movie) comment ("Saving movie screens to 'empmovie.dat'.",0,0,0,0,0,0,0,0);
153                 else comment ("No longer saving movie screens.",0,0,0,0,0,0,0,0);
154                 break;
155
156         case 'W': /* watch movie */
157                 if (resigned || debug) replay_movie ();
158                 else error ("You cannot watch movie until computer resigns.",0,0,0,0,0,0,0,0);
159                 break;
160
161         case 'Z': /* print compressed map */
162                 print_zoom (user_map);
163                 break;
164
165         case '\014': /* redraw the screen */
166                 redraw ();
167                 break;
168
169         case '+': /* change debug state */
170                 e = get_chx();
171                 if ( e  ==  '+' ) debug = TRUE;
172                 else if ( e  ==  '-' ) debug = FALSE;
173                 else huh ();
174                 break;
175
176         default:
177                 if (debug) c_debug (orders); /* debug */
178                 else huh (); /* illegal command */
179                 break;
180         }
181         e = e; /* keep lint quiet */
182 }
183
184 /*
185 Give an unowned city (if any) to the computer.  We make
186 a list of unowned cities, choose one at random, and mark
187 it as the computers.
188 */
189
190 void
191 c_give () {
192         int unowned[NUM_CITY];
193         count_t i, count;
194
195         count = 0; /* nothing in list yet */
196         for (i = 0; i < NUM_CITY; i++) {
197                 if (city[i].owner == UNOWNED) {
198                         unowned[count] = i; /* remember this city */
199                         count += 1;
200                 }
201         }
202         if (count == 0) {
203                 error ("There are no unowned cities.",0,0,0,0,0,0,0,0);
204                 ksend ("There are no unowned cities.",0,0,0,0,0,0,0,0);
205                 return;
206         }
207         i = irand (count);
208         i = unowned[i]; /* get city index */
209         city[i].owner = COMP;
210         city[i].prod = NOPIECE;
211         city[i].work = 0;
212         scan (comp_map, city[i].loc);
213 }
214
215 /*
216 Debugging commands should be implemented here.  
217 The order cannot be any legal command.
218 */
219
220 void
221 c_debug (order)
222 char order;
223 {
224         char e;
225
226         switch (order) {
227         case '#' : c_examine (); break;
228         case '%' : c_movie (); break;
229         
230         case '@': /* change trace state */
231                 e = get_chx();
232                 if ( e  ==  '+' ) trace_pmap = TRUE;
233                 else if ( e  ==  '-' ) trace_pmap = FALSE;
234                 else huh ();
235                 break;
236
237         case '$': /* change print_debug state */
238                 e = get_chx();
239                 if ( e  ==  '+' ) print_debug = TRUE;
240                 else if ( e  ==  '-' ) print_debug = FALSE;
241                 else huh ();
242                 break;
243
244         case '&': /* change print_vmap state */
245                 print_vmap = get_chx();
246                 break;
247
248         default: huh (); break;
249         }
250 }
251
252 /*
253 The quit command.  Make sure the user really wants to quit.
254 */
255
256 void
257 c_quit (void) {
258         if (getyn ("QUIT - Are you sure? ")) {
259             empend ();
260         }
261 }
262
263 /*
264 Print a sector.  Read the sector number from the user
265 and print it.
266 */
267
268 void
269 c_sector (void) {
270         int num;
271
272         num = get_range ("Sector number? ", 0, NUM_SECTORS-1);
273         print_sector_u (num);
274 }
275
276 /*
277 Print the map to a file.  We ask for a filename, attempt to open the
278 file, and if successful, print out the user's information to the file.
279 We print the map sideways to make it easier for the user to print
280 out the map.
281 */
282
283 void
284 c_map (void) {
285         FILE *f;
286         int i, j;
287         char line[MAP_HEIGHT+2];
288
289         prompt ("Filename? ",0,0,0,0,0,0,0,0);
290         get_str (jnkbuf, STRSIZE);
291
292         f = fopen (jnkbuf, "w");
293         if (f == NULL) {
294                 error ("I can't open that file.",0,0,0,0,0,0,0,0);
295                 return;
296         }
297         for (i = 0; i < MAP_WIDTH; i++) { /* for each column */
298                 for (j = MAP_HEIGHT-1; j >= 0; j--) { /* for each row */
299                         line[MAP_HEIGHT-1-j] = user_map[row_col_loc(j,i)].contents;
300                 }
301                 j = MAP_HEIGHT-1;
302                 while (j >= 0 && line[j] == ' ') /* scan off trailing blanks */
303                         j -= 1;
304                         
305                 line[++j] = '\n';
306                 line[++j] = 0; /* trailing null */
307                 (void) fputs (line, f);
308         }
309         (void) fclose (f);
310 }
311
312 /*
313 Allow user to examine the computer's map.
314 */
315
316 void
317 c_examine (void) {
318         int num;
319
320         num = get_range ("Sector number? ", 0, NUM_SECTORS-1);
321         print_sector_c (num);
322 }
323
324 /*
325 We give the computer lots of free moves and
326 Print a "zoomed" version of the computer's map.
327 */
328
329 void
330 c_movie (void) {
331         for (;;) {
332                 comp_move (1);
333                 print_zoom (comp_map);
334                 save_game ();
335 #ifdef PROFILE
336                 if (date == 125) empend();
337 #endif
338         }
339 }