dadd14a9a15c04f9b5cf0d0d6e49ce8cc8e4f023
[vms-empire.git] / empire.c
1 /* $Id: empire.c,v 1.4 2000/07/28 05:12:51 esr Exp esr $  - (c) Copyright 1987, 1988 Chuck Simmons */
2
3 /*
4  *    Copyright (C) 1987, 1988 Chuck Simmons
5  * 
6  * See the file COPYING, distributed with empire, for restriction
7  * and warranty information.
8  */
9
10 /*
11 empire.c -- this file contains initialization code, the main command
12 parser, and the simple commands.
13 */
14
15 #include <stdio.h>
16 #include <curses.h>
17 #include "empire.h"
18 #include "extern.h"
19
20 void c_examine(), c_movie();
21
22 void
23 empire () {
24         void do_command();
25         void print_zoom();
26
27         char order;
28         int turn = 0;
29
30         ttinit (); /* init tty */
31         rndini (); /* init random number generator */
32
33         clear_screen (); /* nothing on screen */
34         (void) move (7, 0);
35         version ();
36         pos_str (8, 0, "Detailed directions are in EMPIRE.DOC\n",0,0,0,0,0,0,0,0);
37         (void) refresh ();
38
39         if (!restore_game ()) /* try to restore previous game */
40                 init_game (); /* otherwise init a new game */
41
42         /* Command loop starts here. */
43
44         for (;;) { /* until user quits */
45             if (automove) { /* don't ask for cmd in auto mode */
46                 user_move ();
47                 comp_move (1);
48                 if (++turn % save_interval == 0)
49                         save_game ();
50             }
51             else {
52                 prompt (0,0,0,0,0,0,0,0,0); /* blank top line */
53                 (void) refresh ();
54                 prompt ("Your orders? ",0,0,0,0,0,0,0,0);
55                 order = get_chx (); /* get a command */
56                 do_command (order);
57             }
58         }
59 }
60
61 /*
62 Execute a command.
63 */
64
65 void
66 do_command (orders)
67 char orders;
68 {
69         void c_debug(), c_quit(), c_sector(), c_map();
70         void c_give();
71
72         char e;
73         int ncycle;
74
75         switch (orders) {
76         case 'A': /* turn on auto move mode */
77                 automove = TRUE;
78                 error ("Now in Auto-Mode",0,0,0,0,0,0,0,0);
79                 user_move ();
80                 comp_move (1);
81                 save_game ();
82                 break;
83
84         case 'C': /* give a city to the computer */
85                 c_give ();
86                 break;
87         
88         case 'D': /* display round number */
89                 error ("Round #%d", date,0,0,0,0,0,0,0);
90                 break;
91
92         case 'E': /* examine enemy map */
93                 if (resigned) c_examine ();
94                 else huh (); /* illegal command */
95                 break;
96
97         case 'F': /* print map to file */
98                 c_map ();
99                 break;
100
101         case 'G': /* give one free enemy move */
102                 comp_move (1);
103                 break;
104
105         case 'H': /* help */
106                 help (help_cmd, cmd_lines);
107                 break;
108
109         case 'J': /* edit mode */
110                 ncycle = cur_sector ();
111                 if (ncycle == -1) ncycle = 0;
112                 edit (sector_loc (ncycle));
113                 break;
114
115         case 'M': /* move */
116                 user_move ();
117                 comp_move (1);
118                 save_game ();
119                 break;
120
121         case 'N': /* give enemy free moves */
122                 ncycle = getint ("Number of free enemy moves: ");
123                 comp_move (ncycle);
124                 save_game ();
125                 break;
126
127         case 'P': /* print a sector */
128                 c_sector ();
129                 break;
130
131         case '\026': /* some interrupt */
132         case 'Q': /* quit */
133                 c_quit ();
134                 break;
135
136         case 'R': /* restore game */
137                 clear_screen ();
138                 e = restore_game ();
139                 break;
140
141         case 'S': /* save game */
142                 save_game ();
143                 break;
144         
145         case 'T': /* trace: toggle save_movie flag */
146                 save_movie = !save_movie;
147                 if (save_movie) comment ("Saving movie screens to 'empmovie.dat'.",0,0,0,0,0,0,0,0);
148                 else comment ("No longer saving movie screens.",0,0,0,0,0,0,0,0);
149                 break;
150
151         case 'W': /* watch movie */
152                 if (resigned || debug) replay_movie ();
153                 else error ("You cannot watch movie until computer resigns.",0,0,0,0,0,0,0,0);
154                 break;
155         
156         case 'Z': /* print compressed map */
157                 (void) clear ();
158                 print_zoom (user_map);
159                 (void) refresh ();
160                 break;
161
162         case '\014': /* redraw the screen */
163                 redraw ();
164                 break;
165
166         case '+': /* change debug state */
167                 e = get_chx();
168                 if ( e  ==  '+' ) debug = TRUE;
169                 else if ( e  ==  '-' ) debug = FALSE;
170                 else huh ();
171                 break;
172
173         default:
174                 if (debug) c_debug (orders); /* debug */
175                 else huh (); /* illegal command */
176                 break;
177         }
178         e = e; /* keep lint quiet */
179 }
180
181 /*
182 Give an unowned city (if any) to the computer.  We make
183 a list of unowned cities, choose one at random, and mark
184 it as the computers.
185 */
186
187 void
188 c_give () {
189         int unowned[NUM_CITY];
190         long i, count;
191
192         count = 0; /* nothing in list yet */
193         for (i = 0; i < NUM_CITY; i++) {
194                 if (city[i].owner == UNOWNED) {
195                         unowned[count] = i; /* remember this city */
196                         count += 1;
197                 }
198         }
199         if (count == 0) {
200                 error ("There are no unowned cities.",0,0,0,0,0,0,0,0);
201                 ksend ("There are no unowned cities.",0,0,0,0,0,0,0,0);
202                 return;
203         }
204         i = irand (count);
205         i = unowned[i]; /* get city index */
206         city[i].owner = COMP;
207         city[i].prod = NOPIECE;
208         city[i].work = 0;
209         scan (comp_map, city[i].loc);
210 }
211
212 /*
213 Debugging commands should be implemented here.  
214 The order cannot be any legal command.
215 */
216
217 void
218 c_debug (order)
219 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 () {
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 () {
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 () {
282         FILE *f;
283         int i, j;
284         char line[MAP_HEIGHT+2];
285
286         prompt ("Filename? ",0,0,0,0,0,0,0,0);
287         get_str (jnkbuf, STRSIZE);
288
289         f = fopen (jnkbuf, "w");
290         if (f == NULL) {
291                 error ("I can't open that file.",0,0,0,0,0,0,0,0);
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 () {
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 () {
328         (void) clear ();
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 }