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