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