[Freeciv-Dev] Re: OR Requirements for Buildings
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
On Fri, 22 Apr 2005, Benedict Adamson wrote:
> Using the new requirements style for buildings, how do I express that
> any one of several requirements is needed for a building, rather than
> requiring all the requirements in a list are necessary? Or is that not
> now possible?
>
> The Ancients rule-set has a Fish Market improvement, which could be
> built in a city adjacent to an Ocean tile or adjacent to a river tile.
> This was done by having a spec_gate = "River" and a terr_gate = "Ocean"
That does not happen just for the Ancients ruleset. Hydro Plant in the
default ruleset is also like that. This is what is there now:
reqs =
{ "type", "name", "range"
"Tech", "Electronics", "Player"
"Building", "Factory", "City"
"Terrain", "Mountains", "Adjacent"
"Special", "River", "Adjacent"
}
The pseudo-code for the check should be like this:
if (hasTech(ELECTRONICS)
&& hasBuilding(FACTORY)
&& (hasAdjacentTerrain(MOUNTAINS) || hasAdjacentSpecial(RIVER)))
That is not what the reqs definition above means. It has no way of using
the OR operator.
This worked in the old code, because of this:
for (;*spec_gate!=S_NO_SPECIAL;spec_gate++) {
if (map_has_special(pcity->tile, *spec_gate) ||
is_special_near_tile(pcity->tile, *spec_gate)) {
return TRUE;
}
}
for (; *terr_gate != T_NONE; terr_gate++) {
if (pcity->tile->terrain == *terr_gate
|| is_terrain_near_tile(pcity->tile, *terr_gate)) {
return TRUE;
}
}
i.e. you only needed to meet either the terrain, or the special.
We got several possible options to fix this. Kludge by hardcoding (like
the old code did) or supporting more generic expressions for enablers.
The .ini format is too rigid to allow expressions like this easily,
unless we use a trick. If we use infix notation, or prefix notation, we
need to have some way to support changing operator priority, like ()s.
Which is near to impossible to parse using .ini format.
So an answer is: Reverse Polish Notation aka postfix notation. Like this:
sreqs =
{ "type", "name", "range"
"Tech", "Electronics", "Player"
"Building", "Factory", "City"
"Operator", "AND"
"Terrain", "Mountains", "Adjacent"
"Special", "River", "Adjacent"
"Operator", "OR"
"Operator", "AND"
}
Super reqs. You can still store the expression as a list, and with a
stack you can calculate the expression pretty easily.
Sick no? The old effects expressions were hardcoded like this:
enable = (a && b && c && d...) && !(a || b || c || d...)
With the sreqs extension, we could do it like this for effects:
enable = reqs && nreqs
OR
enable = sreqs && !nsreqs
and like this for the things which do not require disablers:
enable = reqs
OR
enable = sreqs
---
Vasco Alexandre da Silva Costa @ Instituto Superior Tecnico, Lisboa
|
|