diff options
Diffstat (limited to 'gtnw.c')
| -rw-r--r-- | gtnw.c | 382 |
1 files changed, 382 insertions, 0 deletions
@@ -0,0 +1,382 @@ +#include "gtnw.h" +#include "location.h" +#include "map.h" +#include "util.h" +#include <curses.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +static bool surrender=false; +static int winner=0; /* on surrender */ +static unsigned int max(long long a, long long b) +{ + return a>b?a:b; +} +static void fire_missile(struct location_t* city) +{ + int random=rand()%100; + int x=city->x, y=city->y; + if(random>=90) /* crit */ + { + map[y][x]='!'; + city->population=0; + } + else if(random>=60) /* major */ + { + map[y][x]='X'; + city->population=max((double)city->population*(double).4-400, 0); + } + else if(random>=30) /* minor */ + { + map[y][x]='*'; + city->population=max((double)city->population*(double).6-200, 0); + } + else if(random>=10) /* marginal */ + { + map[y][x]='x'; + city->population=max((double)city->population*(double).8-100, 0); + } + else + { + map[y][x]='O'; + } +} +static void calc_pops(long long* us_pop, long long* ussr_pop) +{ + *us_pop=0; + *ussr_pop=0; + /* calculate populations */ + for(int i=0;i<sizeof(world)/sizeof(struct location_t);++i) + { + if(world[i].owner==USSR) + *ussr_pop+=world[i].population; + else + *us_pop+=world[i].population; + } +} +static void print_map_with_pops(void) +{ + for(int i=0;i<sizeof(map)/sizeof(char*);++i) + { + print_string(map[i]); + print_string("\n"); + } + long long us_pop=0, ussr_pop=0; + calc_pops(&us_pop, &ussr_pop); + /* now sort into US and USSR cities */ + struct location_t us_cities[sizeof(world)/sizeof(struct location_t)+1], ussr_cities[sizeof(world)/sizeof(struct location_t)+1]; + int us_back=0, ussr_back=0; + for(int i=0;i<sizeof(world)/sizeof(struct location_t);++i) + { + if(world[i].owner==USSR) + { + ussr_cities[ussr_back]=world[i]; + ++ussr_back; + } + else + { + us_cities[us_back]=world[i]; + ++us_back; + } + } + if(us_back<ussr_back) + { + while(us_back!=ussr_back) + { + us_cities[us_back].print=false; + ++us_back; + } + } + else if(us_back>ussr_back) + { + while(us_back!=ussr_back) + { + ussr_cities[ussr_back].print=false; + ++ussr_back; + } + } + us_cities[us_back].print=true; + us_cities[us_back].print_name="Total"; + us_cities[us_back].population=us_pop; + ussr_cities[ussr_back].print=true; + ussr_cities[ussr_back].print_name="Total"; + ussr_cities[ussr_back].population=ussr_pop; + ++us_back; + ++ussr_back; + print_string("\n\n"); + char buf[512]; + for(int i=0;i<us_back;++i) + { + if(us_cities[i].print && ussr_cities[i].print) + { + char buf_2[32]; + snprintf(buf_2, 31, "%u", us_cities[i].population); + snprintf(buf, 512, "%s: %u %*s: %u", us_cities[i].print_name, us_cities[i].population, 64-strlen(us_cities[i].print_name)-strlen(buf_2), ussr_cities[i].print_name, ussr_cities[i].population); + } + else if(us_cities[i].print && !ussr_cities[i].print) + snprintf(buf, 512, "%s: %u", us_cities[i].print_name, us_cities[i].population); + else + { + memset(buf, ' ', 255); + buf[255]=0; + snprintf(buf+64, 512-64, "%s: %u", ussr_cities[i].print_name, ussr_cities[i].population); + } + print_string(buf); + print_string("\n"); + } +} +static void do_first_strike(int side) +{ + attr_on(WA_UNDERLINE, 0); + print_string("AWAITING FIRST STRIKE COMMAND"); + attr_off(WA_UNDERLINE, 0); + print_string("\n\n\nPLEASE LIST PRIMARY TARGETS BY\nCITY AND/OR COUNTY NAME:\n\n"); + char target_names[32][129]; + bool good=true; + int num_targets=0; + struct location_t *targets[32]; + int num_targets_found=0; + int max_targets=side==USA?4:6; + for(int i=0;num_targets_found<max_targets && good;++i) + { + getnstr(target_names[i], 128); + if(strcmp(target_names[i],"")==0) + { + good=false; + } + else + { + ++num_targets; + allLower(target_names[i]); + remove_punct(target_names[i]); + bool found=false; + for(int j=0;j<sizeof(world)/sizeof(struct location_t);++j) + { + if(strcmp(world[j].name, target_names[i])==0) + { + found=true; + if(world[j].owner!=side) + { + targets[num_targets_found]=&world[j]; + ++num_targets_found; + } + else + { + print_string("\n\nATTEMPTING TO FIRE AT OWN CITY.\nPLEASE CONFIRM (YES OR NO): "); + char response[17]; + getnstr(response, 16); + allLower(response); + remove_punct(response); + if(strcmp(response, "yes")==0 || strcmp(response, "y")==0) + { + print_string("\n\nATTEMPTING TO FIRE AT OWN CITY.\nARE YOU SURE (YES OR NO): "); + response[0]=0; + getnstr(response, 16); + allLower(response); + remove_punct(response); + if(strcmp(response, "yes")==0 || strcmp(response, "y")==0) + { + print_string("\nTARGET CONFIRMED.\n\n"); + targets[num_targets_found]=&world[j]; + ++num_targets_found; + } + } + } + } + } + if(!found) + { + print_string("TARGET NOT FOUND: "); + print_string(target_names[i]); + print_string("\n"); + } + } + } + for(int i=0;i<num_targets_found;++i) + { + fire_missile(targets[i]); + } + clear(); + print_map_with_pops(); +} +static void do_missile_launch(int side) +{ + clear(); + attr_on(WA_UNDERLINE, 0); + print_string("AWAITING STRIKE COMMAND"); + attr_off(WA_UNDERLINE, 0); + print_string("\n\n\nPLEASE LIST PRIMARY TARGETS BY\nCITY AND/OR COUNTY NAME:\n\n"); + char target_names[32][129]; + bool good=true; + int num_targets=0; + struct location_t *targets[32]; + int num_targets_found=0; + int max_targets=side==USA?4:6; + for(int i=0;num_targets_found<max_targets && good;++i) + { + getnstr(target_names[i], 128); + if(strcmp(target_names[i],"")==0) + { + good=false; + } + else + { + ++num_targets; + allLower(target_names[i]); + remove_punct(target_names[i]); + bool found=false; + for(int j=0;j<sizeof(world)/sizeof(struct location_t);++j) + { + if(strcmp(world[j].name, target_names[i])==0) + { + found=true; + if(world[j].owner!=side) + { + targets[num_targets_found]=&world[j]; + ++num_targets_found; + } + else + { + print_string("\n\nATTEMPTING TO FIRE AT OWN CITY.\nPLEASE CONFIRM (YES OR NO): "); + char response[17]; + getnstr(response, 16); + allLower(response); + remove_punct(response); + if(strcmp(response, "yes")==0 || strcmp(response, "y")==0) + { + print_string("\n\nATTEMPTING TO FIRE AT OWN CITY.\nARE YOU SURE (YES OR NO): "); + response[0]=0; + getnstr(response, 16); + allLower(response); + remove_punct(response); + if(strcmp(response, "yes")==0 || strcmp(response, "y")==0) + { + print_string("\nTARGET CONFIRMED.\n\n"); + targets[num_targets_found]=&world[j]; + ++num_targets_found; + } + } + } + } + } + if(!found) + { + print_string("TARGET NOT FOUND: "); + print_string(target_names[i]); + print_string("\n"); + } + } + } + for(int i=0;i<num_targets_found;++i) + { + fire_missile(targets[i]); + } + clear(); + print_map_with_pops(); +} +enum ai_strategy_t { AGGRESSIVE, PASSIVE, PEACEFUL }; +static void init_ai(int side) +{ + +} +static void do_ai_move(int side) +{ + +} +static void do_peace_talks(int side) +{ +} +static void do_human_move(int side) +{ + bool good=false; + print_string("\nWHAT ACTION DO YOU WISH TO TAKE?\n\n 1. MISSILE LAUNCH\n 2. PEACE TALKS\n 3. SURRENDER\n 4. NOTHING\n\n"); + int move=0; + while(!good) + { + print_string("PLEASE CHOOSE ONE: "); + scanw("%u", &move); + if(move>0 && move<5) + good=true; + } + switch(move) + { + case 1: + do_missile_launch(side); + break; + case 2: + do_peace_talks(side); + break; + case 3: + surrender=true; + winner=side==1?2:1; + break; + case 4: + break; + } +} + +void global_thermonuclear_war(void) +{ + srand(time(0)); + surrender=false; + clear(); + for(int i=0;i<sizeof(map)/sizeof(const char*);++i) + { + print_string(map[i]); + print_string("\n"); + } + print_string("\nWHICH SIDE DO YOU WANT?\n\n 1. UNITED STATES\n 2. SOVIET UNION\n\n"); + bool good=false; + unsigned int side=0; + while(!good) + { + print_string("PLEASE CHOOSE ONE: "); + scanw("%u", &side); + if(side==1 || side==2) + good=true; + } + clear(); + do_first_strike(side); + long long us_pop=0, ussr_pop; + calc_pops(&us_pop, &ussr_pop); + init_ai(side); + while(us_pop!=0 && ussr_pop!=0 && !surrender) + { + do_human_move(side); + calc_pops(&us_pop, &ussr_pop); + if(us_pop!=0 && ussr_pop!=0 && !surrender) + { + do_ai_move(side); + calc_pops(&us_pop, &ussr_pop); + } + } + print_string("\n\n"); + if(!surrender) + { + if(us_pop==0 && ussr_pop==0) + { + print_string("WINNER: NONE\n\n"); + } + else if(us_pop==0) + { + print_string("WINNER: SOVIET UNION\n\n"); + } + else if(ussr_pop==0) + { + print_string("WINNER: UNITED STATES\n\n"); + } + } + else + { + switch(winner) + { + case 1: + print_string("WINNER: UNITED STATES\n\n"); + break; + case 2: + print_string("WINNER: SOVIET UNION\n\n"); + break; + } + } +} + |