Full ANSIfication with prototypes.
[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(char);
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(char orders)
72 {
73         void c_debug(char order), c_quit(void), c_sector(void), c_map(void);
74         void c_give(void);
75
76         char e;
77         int ncycle;
78
79         switch (orders) {
80         case 'A': /* turn on auto move mode */
81                 automove = TRUE;
82                 error ("Now in Auto-Mode",0,0,0,0,0,0,0,0);
83                 user_move ();
84                 comp_move (1);
85                 save_game ();
86                 break;
87
88         case 'C': /* give a city to the computer */
89                 c_give ();
90                 break;
91         
92         case 'D': /* display round number */
93                 error ("Round #%d", date,0,0,0,0,0,0,0);
94                 break;
95
96         case 'E': /* examine enemy map */
97                 if (resigned) c_examine ();
98                 else huh (); /* illegal command */
99                 break;
100
101         case 'F': /* print map to file */
102                 c_map ();
103                 break;
104
105         case 'G': /* give one free enemy move */
106                 comp_move (1);
107                 break;
108
109         case 'H': /* help */
110                 help (help_cmd, cmd_lines);
111                 break;
112
113         case 'J': /* edit mode */
114                 ncycle = cur_sector ();
115                 if (ncycle == -1) ncycle = 0;
116                 edit (sector_loc (ncycle));
117                 break;
118
119         case 'M': /* move */
120                 user_move ();
121                 comp_move (1);
122                 save_game ();
123                 break;
124
125         case 'N': /* give enemy free moves */
126                 ncycle = getint ("Number of free enemy moves: ");
127                 comp_move (ncycle);
128                 save_game ();
129                 break;
130
131         case 'P': /* print a sector */
132                 c_sector ();
133                 break;
134
135         case '\026': /* some interrupt */
136         case 'Q': /* quit */
137                 c_quit ();
138                 break;
139
140         case 'R': /* restore game */
141                 clear_screen ();
142                 e = restore_game ();
143                 break;
144
145         case 'S': /* save game */
146                 save_game ();
147                 break;
148         
149         case 'T': /* trace: toggle save_movie flag */
150                 save_movie = !save_movie;
151                 if (save_movie) comment ("Saving movie screens to 'empmovie.dat'.",0,0,0,0,0,0,0,0);
152                 else comment ("No longer saving movie screens.",0,0,0,0,0,0,0,0);
153                 break;
154
155         case 'W': /* watch movie */
156                 if (resigned || debug) replay_movie ();
157                 else error ("You cannot watch movie until computer resigns.",0,0,0,0,0,0,0,0);
158                 break;
159
160         case 'Z': /* print compressed map */
161                 print_zoom (user_map);
162                 break;
163
164         case '\014': /* redraw the screen */
165                 redraw ();
166                 break;
167
168         case '+': /* change debug state */
169                 e = get_chx();
170                 if ( e  ==  '+' ) debug = TRUE;
171                 else if ( e  ==  '-' ) debug = FALSE;
172                 else huh ();
173                 break;
174
175         default:
176                 if (debug) c_debug (orders); /* debug */
177                 else huh (); /* illegal command */
178                 break;
179         }
180         e = e; /* keep lint quiet */
181 }
182
183 /*
184 Give an unowned city (if any) to the computer.  We make
185 a list of unowned cities, choose one at random, and mark
186 it as the computers.
187 */
188
189 void
190 c_give(void) {
191         int unowned[NUM_CITY];
192         count_t i, count;
193
194         count = 0; /* nothing in list yet */
195         for (i = 0; i < NUM_CITY; i++) {
196                 if (city[i].owner == UNOWNED) {
197                         unowned[count] = i; /* remember this city */
198                         count += 1;
199                 }
200         }
201         if (count == 0) {
202                 error ("There are no unowned cities.",0,0,0,0,0,0,0,0);
203                 ksend ("There are no unowned cities.",0,0,0,0,0,0,0,0);
204                 return;
205         }
206         i = irand (count);
207         i = unowned[i]; /* get city index */
208         city[i].owner = COMP;
209         city[i].prod = NOPIECE;
210         city[i].work = 0;
211         scan (comp_map, city[i].loc);
212 }
213
214 /*
215 Debugging commands should be implemented here.  
216 The order cannot be any legal command.
217 */
218
219 void
220 c_debug(char order)
221 {
222         char e;
223
224         switch (order) {
225         case '#' : c_examine (); break;
226         case '%' : c_movie (); break;
227         
228         case '@': /* change trace state */
229                 e = get_chx();
230                 if ( e  ==  '+' ) trace_pmap = TRUE;
231                 else if ( e  ==  '-' ) trace_pmap = FALSE;
232                 else huh ();
233                 break;
234
235         case '$': /* change print_debug state */
236                 e = get_chx();
237                 if ( e  ==  '+' ) print_debug = TRUE;
238                 else if ( e  ==  '-' ) print_debug = FALSE;
239                 else huh ();
240                 break;
241
242         case '&': /* change print_vmap state */
243                 print_vmap = get_chx();
244                 break;
245
246         default: huh (); break;
247         }
248 }
249
250 /*
251 The quit command.  Make sure the user really wants to quit.
252 */
253
254 void
255 c_quit(void) {
256         if (getyn ("QUIT - Are you sure? ")) {
257             empend ();
258         }
259 }
260
261 /*
262 Print a sector.  Read the sector number from the user
263 and print it.
264 */
265
266 void
267 c_sector(void) {
268         int num;
269
270         num = get_range ("Sector number? ", 0, NUM_SECTORS-1);
271         print_sector_u (num);
272 }
273
274 /*
275 Print the map to a file.  We ask for a filename, attempt to open the
276 file, and if successful, print out the user's information to the file.
277 We print the map sideways to make it easier for the user to print
278 out the map.
279 */
280
281 void
282 c_map(void) {
283         FILE *f;
284         int i, j;
285         char line[MAP_HEIGHT+2];
286
287         prompt ("Filename? ",0,0,0,0,0,0,0,0);
288         get_str (jnkbuf, STRSIZE);
289
290         f = fopen (jnkbuf, "w");
291         if (f == NULL) {
292                 error ("I can't open that file.",0,0,0,0,0,0,0,0);
293                 return;
294         }
295         for (i = 0; i < MAP_WIDTH; i++) { /* for each column */
296                 for (j = MAP_HEIGHT-1; j >= 0; j--) { /* for each row */
297                         line[MAP_HEIGHT-1-j] = user_map[row_col_loc(j,i)].contents;
298                 }
299                 j = MAP_HEIGHT-1;
300                 while (j >= 0 && line[j] == ' ') /* scan off trailing blanks */
301                         j -= 1;
302                         
303                 line[++j] = '\n';
304                 line[++j] = 0; /* trailing null */
305                 (void) fputs (line, f);
306         }
307         (void) fclose (f);
308 }
309
310 /*
311 Allow user to examine the computer's map.
312 */
313
314 void
315 c_examine(void) {
316         int num;
317
318         num = get_range ("Sector number? ", 0, NUM_SECTORS-1);
319         print_sector_c (num);
320 }
321
322 /*
323 We give the computer lots of free moves and
324 Print a "zoomed" version of the computer's map.
325 */
326
327 void
328 c_movie(void) {
329         for (;;) {
330                 comp_move (1);
331                 print_zoom (comp_map);
332                 save_game ();
333 #ifdef PROFILE
334                 if (date == 125) empend();
335 #endif
336         }
337 }