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