scalar map_fire( struct map_t *map, scalar x, scalar y) { scalar aim = map_get( map, x, y); if( ! is_ship( aim)) { map_set( map, x, y, Hit); return Hit; } if( is_ship( aim) && aim != Destroyed_ship) { map_set( map, x, y, Hit_ship); map_check_ship( map, x, y); return Hit_ship; } return 0; }
/* Task b: print the game field */ void print_field(void) { for (int y = 0; y < ysize; y++) { for (int x = 0; x < xsize; x++) { if (is_visible(x, y)) printf("%c", is_ship(x, y)); else printf("?"); } printf("\n"); } }
/* Task d: Returns 1 if game is over (all ships are sunk), or 0 if there * still are locations that have not yet been hit. <num> is the number of * ships on the game map. It is assumed to be the same as in the call to * set_ships function. */ int game_over(unsigned int num) { int shot = 0; for (int y = 0; y < ysize; y++) { for (int x = 0; x < xsize; x++) { if (is_ship(x, y) == '#') shot++; } } if (shot >= num * 3) return 1; return 0; }
/* Task c: Ask coordinates (two integers) from user, and shoot the location. * Returns -1 if user gave invalid input or coordinates, 0 if there was no ship * at the given location; and 1 if there was a ship hit at the location. */ int shoot(void) { int x, y; scanf("%d %d", &x, &y); if (x < 0 || x >= xsize || y < 0 || y >= ysize) return -1; checked(x, y); if (is_ship(x, y) == '+') { hit_ship(x, y); return 1; } return 0; }
scalar bad_map_if_ship( struct map_t *search_map, scalar x, scalar y) { if( is_ship( map_get( search_map, x, y))) { return Bad_map; } else { map_set( search_map, x, y, Search_mark); return 0; } }
/* Task b: print the game field */ void print_field(void) { for (unsigned int i = 0; i < ysize; i++) { for (unsigned int j = 0; j < xsize; j++) { if (is_visible(j, i)) { printf("%c", is_ship(j, i)); } else { printf("?"); } } printf("\n"); } }
void map_destroy_ship( struct map_t *map, scalar x, scalar y) { scalar current = map_get( map, x, y); if( is_ship( current) && current != Destroyed_ship) { map_set( map, x, y, Destroyed_ship); map_destroy_ship( map, x+1, y); map_destroy_ship( map, x-1, y); map_destroy_ship( map, x, y+1); map_destroy_ship( map, x, y-1); } }
/* Task d: Returns 1 if game is over (all ships are sunk), or 0 if there * still are locations that have not yet been hit. <num> is the number of * ships on the game map. It is assumed to be the same as in the call to * set_ships function. */ int game_over(unsigned int num) { unsigned int hits = 0; for (unsigned int i = 0; i < xsize; i++) { for (unsigned int j = 0; j < ysize; j++) { if (is_ship(i, j) == '#') { hits++; } } } if (hits == num * 3) { return 1; } return 0; }
scalar map_is_correct( struct map_t *map) { scalar is_correct = 1; struct map_t *search_map = map_new_clone( map); scalar found_ships[ Max_ship_size+1] = { 0, 0, 0, 0, 0}; for( int i = 0; i < search_map->x_size; i++) { for( int j = 0; j < search_map->y_size; j++) { scalar current = map_get( search_map, i, j); if( current == Search_mark ) { continue; } if( is_ship( current)) { scalar size = map_get_ship_size( search_map, i, j); if( size == Bad_map) { map_delete( search_map); return 0; } if( 0 < size && size <= Max_ship_size) { found_ships[ size]++; } } map_set( search_map, i, j, Search_mark); } } map_delete( search_map); for( int i = 0; i <= Max_ship_size; i++) { if( found_ships[ i] != Ship_sizes[ i]) { printf( "Warning: ships with length %d expected %d, but found %d\n", i, Ship_sizes[ i], found_ships[ i]); is_correct = 0; } } return is_correct; }
/* Task c: Ask coordinates (two integers) from user, and shoot the location. * Returns -1 if user gave invalid input or coordinates, 0 if there was no ship * at the given location; and 1 if there was a ship hit at the location. */ int shoot(void) { unsigned int xpos, ypos; char space; int ret_x = scanf("%u", &xpos); int ret_space = scanf("%c", &space); int ret_y = scanf("%u", &ypos); if (ret_x == 0 || ret_y == 0 || ret_space == 0) { return -1; } if (xpos >= xsize || ypos >= ysize) { return -1; } checked(xpos, ypos); if (is_ship(xpos, ypos) == '+') { hit_ship(xpos, ypos); return 1; } return 0; }
int v_bird_spy(struct command *c) { int targ = c->a; int where = subloc(c->who); struct exit_view *v; if (!has_holy_symbol(c->who)) { wout(c->who, "A holy symbol is required to bird spy."); return FALSE; }; if (!has_piety(c->who, skill_piety(c->use_skill))) { wout(c->who, "You don't have the piety required to use that prayer."); return FALSE; }; if (is_ship(where)) where = loc(where); if (numargs(c) < 1) { wout(c->who, "Specify what location the bird should spy on."); return FALSE; } if (!is_loc_or_ship(c->a)) { v = parse_exit_dir(c, where, sout("use %d", sk_bird_spy)); if (v == NULL) return FALSE; targ = v->destination; } if (province(targ) != province(c->who)) { struct exit_view **l; int i; int okay = FALSE; l = exits_from_loc(c->who, where); for (i = 0; i < ilist_len(l); i++) if (l[i]->destination == targ) okay = TRUE; if (!okay) { wout(c->who, "The location to be spied upon must be " "a sublocation in the same province or a " "neighboring location."); return FALSE; } } c->d = targ; return TRUE; }
scalar map_get_ship_size( struct map_t *search_map, scalar x, scalar y) { scalar result = 0; scalar current = map_get( search_map, x, y); if( !is_ship( current)) { return result = 0; } if( is_ship( map_get( search_map, x-1, y))) { if( bad_map_if_ship( search_map, x, y+1) || bad_map_if_ship( search_map, x, y-1)) { return Bad_map; } else { map_set( search_map, x, y+1, Search_mark); map_set( search_map, x, y-1, Search_mark); } return result = map_get_ship_size( search_map, x-1, y); } else if( is_ship( map_get( search_map, x, y-1))) { if( bad_map_if_ship( search_map, x+1, y) || bad_map_if_ship( search_map, x-1, y)) { return Bad_map; } else { map_set( search_map, x+1, y, Search_mark); map_set( search_map, x-1, y, Search_mark); } return result = map_get_ship_size( search_map, x, y-1); } if( is_ship( map_get( search_map, x+1, y))) {//Horizontal if( bad_map_if_ship( search_map, x-1, y-1) || bad_map_if_ship( search_map, x-1, y) || bad_map_if_ship( search_map, x-1, y+1)) { return Bad_map; } scalar offset = 0; scalar current = map_get( search_map, x, y); while( is_ship( current)) { if( bad_map_if_ship( search_map, x+offset, y+1) || bad_map_if_ship( search_map, x+offset, y-1)) { return Bad_map; } map_set( search_map, x+offset, y, Search_mark); offset++; current = map_get( search_map, x+offset, y); } result = offset; if( bad_map_if_ship( search_map, x+offset, y-1) || bad_map_if_ship( search_map, x+offset, y) || bad_map_if_ship( search_map, x+offset, y+1)) { return Bad_map; } return result; } else if( is_ship( map_get( search_map, x, y+1))) {//Vertical if( bad_map_if_ship( search_map, x-1, y-1) || bad_map_if_ship( search_map, x, y-1) || bad_map_if_ship( search_map, x+1, y-1)) { return Bad_map; } scalar offset = 0; scalar current = map_get( search_map, x, y); while( is_ship( current)) { if( bad_map_if_ship( search_map, x+1, y+offset) || bad_map_if_ship( search_map, x-1, y+offset)) { return Bad_map; } map_set( search_map, x, y+offset, Search_mark); offset++; current = map_get( search_map, x, y+offset); } result = offset; if( bad_map_if_ship( search_map, x-1, y+offset) || bad_map_if_ship( search_map, x, y+offset) || bad_map_if_ship( search_map, x+1, y+offset)) { return Bad_map; } return result; } else {//Single if( bad_map_if_ship( search_map, x-1, y-1) || bad_map_if_ship( search_map, x-1, y) || bad_map_if_ship( search_map, x-1, y+1) || bad_map_if_ship( search_map, x, y-1) || bad_map_if_ship( search_map, x, y+1) || bad_map_if_ship( search_map, x+1, y-1) || bad_map_if_ship( search_map, x+1, y) || bad_map_if_ship( search_map, x+1, y+1)) { return Bad_map; } else { map_set( search_map, x, y, Search_mark); return 1; } } return 0; }
scalar map_check_ship( struct map_t *map, scalar x, scalar y) { scalar hit_count = 0; scalar count = 0; scalar current = map_get( map, x, y); if( !is_ship( current)) { return current; } int x0 = x; current = map_get( map, x0, y); while( is_ship( current)) { current = map_get( map, x0, y); if( current == Hit_ship) { hit_count++; } if( current == Destroyed_ship) { return Destroyed_ship; } x0++; if( is_ship( current)) { count++; } } x0 = x-1; current = map_get( map, x0, y); while( is_ship( current)) { current = map_get( map, x0, y); if( current == Hit_ship) { hit_count++; } if( current == Destroyed_ship) { return Destroyed_ship; } x0--; if( is_ship( current)) { count++; } } int y0 = y+1; current = map_get( map, x, y0); while( is_ship( current)) { current = map_get( map, x, y0); if( current == Hit_ship) { hit_count++; } if( current == Destroyed_ship) { return Destroyed_ship; } y0++; if( is_ship( current)) { count++; } } y0 = y-1; current = map_get( map, x, y0); while( is_ship( current)) { current = map_get( map, x, y0); if( current == Hit_ship) { hit_count++; } if( current == Destroyed_ship) { return Destroyed_ship; } y0--; if( is_ship( current)) { count++; } } if( count == hit_count) { map_destroy_ship( map, x, y); return Destroyed_ship; } if( hit_count != 0) { return Hit_ship; } return Ship_any; }