The International Simutrans Forum

 

Author Topic: 'Cities ignore height' option  (Read 6090 times)

0 Members and 1 Guest are viewing this topic.

Offline inkelyad

  • Devotees (Inactive)
  • *
  • Posts: 482
  • Languages: EN, RU
'Cities ignore height' option
« on: June 12, 2010, 07:41:07 PM »
How 'Cities ignore height' option works?
The only relevant place I can find is (simcity.cc)
Code: [Select]
const sint32 multiplied_number = umgebung_t::cities_ignore_height || welt == NULL ? anzahl : anzahl * 4;
<SKIP>
if(welt != NULL && !umgebung_t::cities_ignore_height)
    {
        pre_result = new weighted_vector_tpl<koord>(multiplied_number);
    }
and pre_result is not used anywhere..

Offline jamespetts gb

  • Simutrans-Extended project coordinator
  • Moderator
  • *
  • Posts: 18745
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: 'Cities ignore height' option
« Reply #1 on: June 13, 2010, 11:02:30 PM »
Inkelyad,

thank you for spotting that. This was originally (and should still be) part of a system for distributing towns based on the height: the higher the tile, the less likely that it was that a town would be generated there. The "cities_ignore_height" option was a way of disabling that. It seems that, since then, the code in Standard has changed, and, when that change was merged, it obliterated the feature in Experimental. The original code looked like this:

Code: [Select]
vector_tpl<koord>* stadt_t::random_place(const karte_t* wl, const sint32 anzahl, sint16 old_x, sint16 old_y)
 {
  int cl = 0;
  for (int i = 0; i < MAX_CLIMATES; i++)
  {
  if (hausbauer_t::get_special(0, haus_besch_t::rathaus, wl->get_timeline_year_month(), false, (climate)i))
  {
  cl |= (1 << i);
  }
  }
 
  // For clustering cities by climate type, we need a list of at least 4x the number of sites actually needed
  // for towns so that, from that expanded list, the final locations can be chosen.
const sint32 multiplied_number = umgebung_t::cities_ignore_height || welt == NULL ? anzahl : anzahl * 4;
 
  DBG_DEBUG("karte_t::init()", "get random places in climates %x", cl);
  slist_tpl<koord>* list = wl->finde_plaetze(2, 3, (climate_bits)cl, old_x, old_y);
  DBG_DEBUG("karte_t::init()", "found %i places", list->get_count());
vector_tpl<koord>* result = new vector_tpl<koord>(anzahl);
weighted_vector_tpl<koord>* pre_result;
if(welt != NULL && !umgebung_t::cities_ignore_height)
{
pre_result = new weighted_vector_tpl<koord>(multiplied_number);
}
 
  for (int i = 0; i < multiplied_number; i++)
  {
  int len = list->get_count();
  // check distances of all cities to their respective neightbours
  while (len > 0)
  {
  int minimum_dist = 0x7FFFFFFF;  // init with maximum
  koord k;
  const int index = simrand(len);
  k = list->at(index);
  list->remove(k);
  len--;
 
  // check minimum distance
  for (int j = 0; (j < i) && minimum_dist > minimum_city_distance; j++)
  {
  int dist = koord_distance( k, (*pre_result)[j] );
  if (minimum_dist > dist)
  {
  minimum_dist = dist;
  }
  }
  if (minimum_dist > minimum_city_distance)
  {
  // all cities are far enough => ok, find next place

if(welt != NULL && !umgebung_t::cities_ignore_height)
  {
const sint16 height_above_water = welt->lookup_hgt(k) - welt->get_grundwasser();
uint32 weight;
switch(height_above_water)
{
case 1:
weight = 24;
break;
case 2:
weight = 22;
break;
case 3:
weight = 16;
break;
case 4:
weight = 12;
break;
case 5:
weight = 10;
break;
case 6:
weight = 9;
break;
case 7:
weight = 8;
break;
case 8:
weight = 7;
break;
case 9:
weight = 6;
break;
case 10:
weight = 5;
break;
case 11:
weight = 4;
break;
case 12:
case 13:
weight = 3;
break;
case 14:
case 15:
weight = 2;
break;
default:
weight = 1;
};
pre_result->append(k, weight);
  break;
}
else
{
result->append(k);
  break;
}
  }
  // if we reached here, the city was not far enough => try again
  }
 
  if (len <= 0 && i < anzahl - 1)
  {
  dbg->warning("stadt_t::random_place()", "Not enough places found!");
  break;
  }
  }
  list->clear();
  delete list;
 
if(welt != NULL && !umgebung_t::cities_ignore_height)
  {
uint16 weight = 0;
const uint16 total_weight = pre_result->get_sum_weight();
for (int i = 0; i < anzahl; i++)
  {
// Now produce the real results from the pre-list.
weight = simrand(total_weight);
if(!result->append_unique(pre_result->at_weight(weight)))
{
i--;
}
  }

pre_result->clear();
delete pre_result;
}
 
  return result;

When I get a chance, I shall have to look to see how I can acheive that result using the new code (which I understand is much faster than the old code). If you have any suggestions as to how to implement this with the new system, they'd be very gratefully received!

Offline inkelyad

  • Devotees (Inactive)
  • *
  • Posts: 482
  • Languages: EN, RU
Re: 'Cities ignore height' option
« Reply #2 on: June 14, 2010, 06:02:05 PM »
When I get a chance, I shall have to look to see how I can acheive that result using the new code (which I understand is much faster than the old code).
What reasoning was behind this option? Can I replace it? Right now I have planned somenting along 'rivers (even mountain ones)/sea attracts cities'

Offline jamespetts gb

  • Simutrans-Extended project coordinator
  • Moderator
  • *
  • Posts: 18745
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: 'Cities ignore height' option
« Reply #3 on: June 14, 2010, 07:53:47 PM »
What reasoning was behind this option? Can I replace it? Right now I have planned somenting along 'rivers (even mountain ones)/sea attracts cities'

I like your idea for water attracting cities - that would be a substantial enhancement to the game! The reason for my system was that towns are more often built on lowlands than highlands, although they are sometimes built on highlands: the idea was to weight the probability of building cities according to the height of the terrain. This would have the effect that there would be some areas with a large number of towns clustered together and some areas that are quite sparsely populated with towns. This is desirable in itself, not only because it is realistic, but because it provides interesting challenges of balancing, in the areas with many towns clustered together, a dense urban/suburban network, with the very different challenges of connecting remoter towns, or connecting distant pairs of large urban areas with little in between (and potentially over difficult terrain).

Offline jamespetts gb

  • Simutrans-Extended project coordinator
  • Moderator
  • *
  • Posts: 18745
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: 'Cities ignore height' option
« Reply #4 on: June 27, 2010, 12:31:44 AM »
I have now put this feature back in a way that works with the new code in the 8.x branch. Inkelyad - I am still very interested in your ideas as to how to make cities more likely to be built near water - do let me know how you get on with that!

Offline inkelyad

  • Devotees (Inactive)
  • *
  • Posts: 482
  • Languages: EN, RU
Re: 'Cities ignore height' option
« Reply #5 on: June 28, 2010, 12:37:46 PM »
I am a slow programmer. Furthermore  multiple weight maps interfere with each other. I still can't choose 'correct' formula.

Offline jamespetts gb

  • Simutrans-Extended project coordinator
  • Moderator
  • *
  • Posts: 18745
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: 'Cities ignore height' option
« Reply #6 on: June 28, 2010, 07:58:55 PM »
Inkelyad,

the multiple weightings issue is actually the easiest to solve: the hard bit is actually working out which sites are near rivers and the sea, especially as, if I recall correctly, rivers are built after cities in map generation. The simple solution to weighting is to start with a neutral base weight of, say, 100, and to add and subtract (or multiply and divide) for each factor: near small river, add 20, near large river: add 50, on low ground, add 100, on top of mountain, subtract 90 - and so forth.

Offline inkelyad

  • Devotees (Inactive)
  • *
  • Posts: 482
  • Languages: EN, RU
Re: 'Cities ignore height' option
« Reply #7 on: June 29, 2010, 02:39:17 AM »
the hard bit is actually working out which sites are near rivers and the sea, especially as, if I recall correctly, rivers are built after cities in map generation.
No, rivers are built first.
The simple solution to weighting is to start with a neutral base weight of, say, 100, and to add and subtract (or multiply and divide) for each factor: near small river, add 20, near large river: add 50, on low ground, add 100, on top of mountain, subtract 90 - and so forth.
Yes, it realy works almost like this. But it is hard to find coefficients. As it is river map and height map give me very similar effects.
Combine city distance/size + terrain height + water distance into something non-confusing is hard.

Offline jamespetts gb

  • Simutrans-Extended project coordinator
  • Moderator
  • *
  • Posts: 18745
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: 'Cities ignore height' option
« Reply #8 on: June 29, 2010, 09:05:46 PM »
Well, I shall be interested in any progress!

Offline inkelyad

  • Devotees (Inactive)
  • *
  • Posts: 482
  • Languages: EN, RU
Re: 'Cities ignore height' option
« Reply #9 on: June 30, 2010, 08:44:41 PM »
Teaser time. And I need english editor help. How should I actually name parameters in GUI? I beleve names of variables in code are confusing too.

patch against current 'devel' branch. No GUI yet. Just play with 'water_charge', 'one_population_charge', 'clustering' at the begining of  stadt_t::random_place_complex.

Offline inkelyad

  • Devotees (Inactive)
  • *
  • Posts: 482
  • Languages: EN, RU
Re: 'Cities ignore height' option
« Reply #10 on: June 30, 2010, 08:46:11 PM »
water atracts cities.

Offline inkelyad

  • Devotees (Inactive)
  • *
  • Posts: 482
  • Languages: EN, RU
Re: 'Cities ignore height' option
« Reply #11 on: June 30, 2010, 08:47:51 PM »
Cities avoid each other.

Offline inkelyad

  • Devotees (Inactive)
  • *
  • Posts: 482
  • Languages: EN, RU
Re: 'Cities ignore height' option
« Reply #12 on: June 30, 2010, 08:48:54 PM »
Clustering

Offline jamespetts gb

  • Simutrans-Extended project coordinator
  • Moderator
  • *
  • Posts: 18745
  • Cake baker
    • Bridgewater-Brunel
  • Languages: EN
Re: 'Cities ignore height' option
« Reply #13 on: June 30, 2010, 10:41:31 PM »
I am very impressed! Is patched against Experimental or Standard?

Offline Isaac.Eiland-Hall us

  • Benevolent Dictator
  • Administrator
  • *
  • Posts: 3659
  • PanamaCityPC.com/support/
    • Facebook Profile
  • Languages: EN
Re: 'Cities ignore height' option
« Reply #14 on: June 30, 2010, 11:14:38 PM »
That's freakin' sweet. Something I hope comes to Standard (as with many Experimental features, but this one stands out for me personally hehehe)

Offline inkelyad

  • Devotees (Inactive)
  • *
  • Posts: 482
  • Languages: EN, RU
Re: 'Cities ignore height' option
« Reply #15 on: July 01, 2010, 02:17:31 AM »
Is patched against Experimental or Standard?
I use github Experimental 'devel' as a base. Don't know how it will work with Standard.