# Requesting help: How to test for river crossing in a wargame?

Greetings all, been awhile and I started back up coding my wargame. I am stuck on something and would appreciate your help if you are willing. I have a data structure for tiles I am using and when declaring an attack from one tile to another I am trying to determine if it is crossing a River. I have established that rivers run along a tile side(s). Example: Tile[x].NorthRiver, Tile[x].EastRiver, Tile[x].SouthRiver, Tile[x].WestRiver all will be 0 if there isnt a river, and 1 if there is. I am struggling to come up with an algorithm to test all possibilities to return true(well River=1 means that yes this unit has to cross a river). Here’s what I have so far but I need to be able to test cases where you are moving say NE. I need to be able to test the square immediately to the N to see if it ALSO has a river on it’s E side as that should also return true. I think what I have works for pure N, S, E, W tests but how to test for that kind of cardinal point cases? I think what I have works for one type of cardinal point test where there is a river to your N AND E but I realized the case above would be missed. This is a real tough one for me, rest of the game…not a problem so far.

The test case also needs to handle checking the sqare to the east and see if that has a N river too.

IE: the following would all return true if moving/attacking NE:

River N AND E

River N but not E AND River N on square to the E

River E but not N AND River E on square to the N

Having a hard time on last 2 cases…

CODE:

local function RiverCrossingCheck(AX, AY, DX, DY)

``````--AX, AY, DX, DY are the tile x and y values(not pixel points) so that is what must be passed to this function
--Determine if the attacker has to cross a river by checking the vector of the attack.
--compare the vector with a test to see if that side has a river
--if that side has a river return true, else false

--NOTE: The map will have to be marked as a river on both sides.  IE: if a tile has a river on it's south side then the tile to the immediate south side must be marked with a North river as well...

--attackers riversides
local N = 0
local NW = 0
local NE = 0
local E = 0
local S = 0
local SE = 0
local SW = 0
local W = 0

local River = 0
local AT=0

--Determine the Attackers tile number so you can reference the river properties.
AT = ((AY-1) * MapWidth) + AX;

--ATTACKING NORTH
if (AY-DY = 1) then
N = Tile[AT].NorthSideRiver
end

--ATTACKING EAST
if (AX-DX = -1) then
E = Tile[AT].EastSideRiver
end

--ATTACKING SOUTH
if (AY-DY = -1) then
S = Tile[AT].SouthSideRiver
end

--ATTACKING WEST
if (AX-DX = 1) then
W = Tile[AT].WestSideRiver
end

--Check all 8 cardinal points to find the vector of attack:
--Need to get the riversides on all 8 adjacent squares:
--because if a river is on E but not N AND your attacking NE
--it would have been missed by my initial algorithym because
--if the river in the square to the N also has and E river side that
--should return true..
--
--So 1 algorithm to test pure N, S, E, W
--another for NE, NW, SE, SW is also needed.

if (N==1 ) then
if(E==1) then
River = 1
end

if(W==1) then
River = 1
end
end
``````

``````return River
``````

end

@Gib I might add river info to each tile similar to this. Then you can check the river location with a lot less code. I show 4 if statements as examples.

``````
function setup()
-- tile containing river info.
tile={  {river={"n","ne"}},
{river={"e","se"}},
{river={"w"}} }

if riverLocation(1,"n") and riverLocation(1,"ne") then
print("true")
else
print("false")
end

if riverLocation(2,"e") and riverLocation(2,"se") then
print("true")
else
print("false")
end

if riverLocation(2,"n") and riverLocation(2,"ne") then
print("true")
else
print("false")
end

if riverLocation(3,"w") then
print("true")
else
print("false")
end

end

function riverLocation(location,dir)
for pos=1,8 do
if tile[location].river[pos]==dir then
return true
end
end
return false
end

``````

Since the river details (and your rules for crossing them) won’t change, you could actually use dave’s approach to build a table right at the beginning, which tells you which way to go for each tile on the board. This would keep your code much cleaner.

@Gib The “for” loop in the Function riverLocation() can be changed to what I have below. It didn’t need to loop to 8, but just the size of direction data in each table.

``````
function riverLocation(location,dir)
for pos=1,#tile[location].river do
if tile[location].river[pos]==dir then
return true
end
end
return false
end

``````

@Gib Here’s a riverLocation function that will allow you to check multiple directions using one “if” statement by passing multiple directions.

``````
function setup()
-- tile containing river info.
tile={  {river={"n","ne","e","se","s"}},
{river={"e","se","s"}},
{river={"w","nw"}} }

if riverLocation(1,"n","ne","se","s") then
print("true")
else
print("false")
end

if riverLocation(1,"ne","s","sw") then
print("true")
else
print("false")
end

if riverLocation(3,"w") then
print("true")
else
print("false")
end

end

function riverLocation(...)
location=arg
temp1=true
for z=2,#arg do
temp2=false
for pos=1,#tile[location].river do
if tile[location].river[pos]==arg[z] then
temp2=true
end
end
if not temp2 then
temp1=false
end
end
return temp1
end

``````

Oh thanks bud, that’s so much nicer and concise! I don’t fully understand it yet but will study it and probably learn a thing or two about better data structuring in programming.