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