Replace FOREACH

This commit is contained in:
fendrin 2016-08-06 04:36:29 +02:00
parent 7918425cd2
commit 8eea8122f9
3 changed files with 145 additions and 127 deletions

View File

@ -510,11 +510,14 @@ Note: This is a demonstration of how the Goto Micro AI can be used to code guard
variable=stored_ghosts
[/store_unit]
{FOREACH stored_ghosts i_g}
[kill]
id=$stored_ghosts[$i_g].id
[/kill]
{NEXT i_g}
[foreach]
array=stored_ghosts
[do]
[kill]
id=$this_item.id
[/kill]
[/do]
[/foreach]
{CLEAR_VARIABLE stored_ghosts}
[/event]

View File

@ -411,9 +411,12 @@ separate attack Zone"
variable=tmp_units
kill=no
[/store_unit]
{FOREACH tmp_units i}
{SET_LABEL $tmp_units[$i].x $tmp_units[$i].y $tmp_units[$i].variables.label}
{NEXT i}
[foreach]
array=tmp_units
[do]
{SET_LABEL $this_item.x $this_item.y $this_item.variables.label}
[/do]
[/foreach]
{CLEAR_VARIABLE tmp_units}
# The right-click menu items

View File

@ -10,15 +10,19 @@
{VARIABLE minimum 99999}
# Go through container variable
{FOREACH {CONTAINER} i_min}
{IF_VAR {CONTAINER}[$i_min].{VAR} less_than $minimum (
[then]
{VARIABLE minimum ${CONTAINER}[$i_min].{VAR}}
{VARIABLE min_index $i_min}
[/then]
)}
#{DEBUG "$i_min: $minimum (${CONTAINER}[$i_min].{VAR})"}
{NEXT i_min}
[for]
array={CONTAINER}
variable=i_min
[do]
{IF_VAR {CONTAINER}[$i_min].{VAR} less_than $minimum (
[then]
{VARIABLE minimum ${CONTAINER}[$i_min].{VAR}}
{VARIABLE min_index $i_min}
[/then]
)}
#{DEBUG "$i_min: $minimum (${CONTAINER}[$i_min].{VAR})"}
[/do]
[/for]
#enddef
#define LURKER_MOVES SIDE ENEMY_SIDES
@ -44,123 +48,131 @@
[/store_unit]
# For each Lurker, we do:
{FOREACH stored_lurkers i_l}
#{DEBUG "Lurker $i_l"}
[for]
array=stored_lurkers
variable=i_l
[do]
#{DEBUG "Lurker $i_l"}
# Store reachable swamp locations next to an enemy
# This should include the current location
[store_reachable_locations]
[filter]
id=$stored_lurkers[$i_l].id
[/filter]
[filter_location]
terrain=S* # swamp
[not] # unoccupied by other unit
[filter]
[not]
id=$stored_lurkers[$i_l].id
[/not]
[/filter]
[/not]
[filter_adjacent_location] # next to enemy
[filter]
side={ENEMY_SIDES}
[/filter]
[/filter_adjacent_location]
[/filter_location]
moves=max
variable=stored_locs
[/store_reachable_locations]
#{DEBUG " reachable with enemy adjacent: $stored_locs.length"}
# Now find all those enemies and store
# Doesn't matter if some enemies are stored several times
{FOREACH stored_locs i_e}
[store_unit]
# Store reachable swamp locations next to an enemy
# This should include the current location
[store_reachable_locations]
[filter]
side={ENEMY_SIDES}
[filter_location]
[filter_adjacent_location]
x,y=$stored_locs[$i_e].x,$stored_locs[$i_e].y
[/filter_adjacent_location]
[/filter_location]
id=$stored_lurkers[$i_l].id
[/filter]
variable=adj_enemies
mode=append
[/store_unit]
#{DEBUG " $i_e: enemies adjacent to current location: $adj_enemies.length"}
{NEXT i_e}
[filter_location]
terrain=S* # swamp
[not] # unoccupied by other unit
[filter]
[not]
id=$stored_lurkers[$i_l].id
[/not]
[/filter]
[/not]
[filter_adjacent_location] # next to enemy
[filter]
side={ENEMY_SIDES}
[/filter]
[/filter_adjacent_location]
[/filter_location]
moves=max
variable=stored_locs
[/store_reachable_locations]
#{DEBUG " reachable with enemy adjacent: $stored_locs.length"}
{IF_VAR adj_enemies.length equals 0 (
[then] # if there is no reachable enemy
# Simply pick a random reachable swamp hex (Lurkers are pretty stupid)
# (there is always at least the hex the unit is on)
[store_reachable_locations]
[filter]
id=$stored_lurkers[$i_l].id
[/filter]
[filter_location]
terrain=S* # swamp
[not] # unoccupied by other unit
[filter]
[not]
id=$stored_lurkers[$i_l].id
[/not]
[/filter]
[/not]
[/filter_location]
moves=max
variable=stored_locs
[/store_reachable_locations]
#{DEBUG "Reachable hexes: $stored_locs.length"}
[/then]
# Now find all those enemies and store
# Doesn't matter if some enemies are stored several times
[for]
array=stored_locs
variable=i_e
[do]
[store_unit]
[filter]
side={ENEMY_SIDES}
[filter_location]
[filter_adjacent_location]
x,y=$stored_locs[$i_e].x,$stored_locs[$i_e].y
[/filter_adjacent_location]
[/filter_location]
[/filter]
variable=adj_enemies
mode=append
[/store_unit]
#{DEBUG " $i_e: enemies adjacent to current location: $adj_enemies.length"}
[/do]
[/for]
[else] # if there are reachable enemies
# We simply find the enemies with minimum hitpoints (Lurkers are pretty stupid)
{MINIMUM adj_enemies hitpoints}
# Unfortunately, now we need to store the reachable location again
[store_reachable_locations]
[filter]
id=$stored_lurkers[$i_l].id
[/filter]
[filter_location]
terrain=S* # swamp
[not] # unoccupied by other unit
[filter]
[not]
id=$stored_lurkers[$i_l].id
[/not]
[/filter]
[/not]
[filter_adjacent_location]
[filter]
x,y=$adj_enemies[$min_index].x,$adj_enemies[$min_index].y
[/filter]
[/filter_adjacent_location]
[/filter_location]
moves=max
variable=stored_locs
[/store_reachable_locations]
#{DEBUG " final possible reachable locations: $stored_locs.length"}
[/else]
)}
{IF_VAR adj_enemies.length equals 0 (
[then] # if there is no reachable enemy
# Simply pick a random reachable swamp hex (Lurkers are pretty stupid)
# (there is always at least the hex the unit is on)
[store_reachable_locations]
[filter]
id=$stored_lurkers[$i_l].id
[/filter]
[filter_location]
terrain=S* # swamp
[not] # unoccupied by other unit
[filter]
[not]
id=$stored_lurkers[$i_l].id
[/not]
[/filter]
[/not]
[/filter_location]
moves=max
variable=stored_locs
[/store_reachable_locations]
#{DEBUG "Reachable hexes: $stored_locs.length"}
[/then]
# Move unit to one of those at random
{RANDOM "0..$($stored_locs.length-1)"}
#{DEBUG "$stored_lurkers[$i_l].x $stored_lurkers[$i_l].y : $random"}
[if] # only if different from current position
{VARIABLE_CONDITIONAL stored_locs[$random].x not_equals $stored_lurkers[$i_l].x}
[or]
{VARIABLE_CONDITIONAL stored_locs[$random].y not_equals $stored_lurkers[$i_l].y}
[/or]
[then]
{MOVE_UNIT id=$stored_lurkers[$i_l].id $stored_locs[$random].x $stored_locs[$random].y}
[/then]
[/if]
[else] # if there are reachable enemies
# We simply find the enemies with minimum hitpoints (Lurkers are pretty stupid)
{MINIMUM adj_enemies hitpoints}
# Unfortunately, now we need to store the reachable location again
[store_reachable_locations]
[filter]
id=$stored_lurkers[$i_l].id
[/filter]
[filter_location]
terrain=S* # swamp
[not] # unoccupied by other unit
[filter]
[not]
id=$stored_lurkers[$i_l].id
[/not]
[/filter]
[/not]
[filter_adjacent_location]
[filter]
x,y=$adj_enemies[$min_index].x,$adj_enemies[$min_index].y
[/filter]
[/filter_adjacent_location]
[/filter_location]
moves=max
variable=stored_locs
[/store_reachable_locations]
#{DEBUG " final possible reachable locations: $stored_locs.length"}
[/else]
)}
# Need to clear adj_enemies inside the loop, as mode=append
{CLEAR_VARIABLE adj_enemies,minimum,min_index,random,stored_locs}
{NEXT i_l}
# Move unit to one of those at random
{RANDOM "0..$($stored_locs.length-1)"}
#{DEBUG "$stored_lurkers[$i_l].x $stored_lurkers[$i_l].y : $random"}
[if] # only if different from current position
{VARIABLE_CONDITIONAL stored_locs[$random].x not_equals $stored_lurkers[$i_l].x}
[or]
{VARIABLE_CONDITIONAL stored_locs[$random].y not_equals $stored_lurkers[$i_l].y}
[/or]
[then]
{MOVE_UNIT id=$stored_lurkers[$i_l].id $stored_locs[$random].x $stored_locs[$random].y}
[/then]
[/if]
# Need to clear adj_enemies inside the loop, as mode=append
{CLEAR_VARIABLE adj_enemies,minimum,min_index,random,stored_locs}
[/do]
[/for]
{CLEAR_VARIABLE stored_lurkers}
# Attack is then left to the AI