diff -Nurd -X freeciv-09.25/diff_ignore ../cvs/freeciv/server/cityhand.c freeciv-09.25/server/cityhand.c --- ../cvs/freeciv/server/cityhand.c Sun Sep 24 22:57:19 2000 +++ freeciv-09.25/server/cityhand.c Mon Sep 25 02:02:48 2000 @@ -104,7 +104,7 @@ buffer etc, and should be considered read-only (and not freed) by caller. *****************************************************************/ -char *city_name_suggestion(struct player *pplayer) +const char *city_name_suggestion(struct player *pplayer) { char **nptr; int i, j; @@ -113,13 +113,13 @@ static const int num_tiles = MAP_MAX_WIDTH * MAP_MAX_HEIGHT; freelog(LOG_VERBOSE, "Suggesting city name for %s", pplayer->name); - + for(nptr=get_nation_by_plr(pplayer)->default_city_names; *nptr; nptr++) { if(!game_find_city_by_name(*nptr)) return *nptr; } - if (num_misc_city_names > 0) { + if (num_misc_city_names > 0 && 0) { /* decide by a server option perhaps */ j = myrand(num_misc_city_names); for (i = 0; i < num_misc_city_names; i++) { @@ -130,6 +130,57 @@ return misc_city_names[j]; j++; } + } else { + /* This algorithm starts with two leading letters from an existing city + names, and then adds more letters in a way that every triplet of + characters occurs in any predefined city name, and the last two letters + occur at the end of a predefined city name. This leads to city names + that sound similar to the predefined ones. + + The implementation is very inefficient, but since this function should + only be called very seldom, this should be acceptable. */ + int size = 0, p = 0, c; + char *all_citynames; + + for (nptr = get_nation_by_plr(pplayer)->default_city_names; *nptr; nptr++) + size += strlen(*nptr) + 1; + all_citynames = fc_malloc(size + 1); + + for (nptr = get_nation_by_plr(pplayer)->default_city_names; *nptr; nptr++) { + strcpy(&all_citynames[p], *nptr); + p += strlen(*nptr); + all_citynames[p++] = '\n'; + } + all_citynames[p] = '\0'; + + /* all_citynames now contains all predefined city names of the current + civilization, seperated by newlines. */ + for (i = 0; i < 1000; i++) { + do { + p = myrand(size - 1); + tempname[0] = all_citynames[p]; + tempname[1] = all_citynames[p + 1]; + } while (!isupper(tempname[0])); + + /* Now we've found two letters at the beginning of a predefined city name. */ + c = 1; + do { + p = myrand(size - 2) + 1; /* exclude last and first letter */ + if (all_citynames[p] == tempname[c] + && all_citynames[p - 1] == tempname[c - 1]) + /* Do the last two letters match? This is pretty unlikely, but by + construction there must be at least one place where they do, so + it will eventually happen. */ + tempname[++c] = all_citynames[p + 1]; + } while(tempname[c] != '\n' && c < 15); + tempname[c] = '\0'; + + if (c > 3 && c < 15 && !game_find_city_by_name(tempname)) { + free(all_citynames); + return tempname; + } + } + free(all_citynames); } for (i = 1; i <= num_tiles; i++ ) { diff -Nurd -X freeciv-09.25/diff_ignore ../cvs/freeciv/server/cityhand.h freeciv-09.25/server/cityhand.h --- ../cvs/freeciv/server/cityhand.h Thu Aug 3 23:33:06 2000 +++ freeciv-09.25/server/cityhand.h Mon Sep 25 00:46:51 2000 @@ -63,7 +63,7 @@ struct packet_generic_values *preq); void handle_city_name_suggest_req(struct connection *pconn, struct packet_generic_integer *packet); -char *city_name_suggestion(struct player *pplayer); +const char *city_name_suggestion(struct player *pplayer); void reality_check_city(struct player *pplayer,int x, int y); void update_dumb_city(struct player *pplayer, struct city *pcity); void send_all_known_cities(struct conn_list *dest);