Classic Squad Leader AFV Covered Arc

These are some really basic notes on how to find the hexes within an AFV's covered arc as per Classic Squad Leader (SL).

Sooner or later I'll tidy these notes up but the'll have to do for now.

Definitions

To program for SL you need some method of indexing hexes. Mine is this:
Vertical columns in SL have letters A to GG across (x coordinate). I give these column indices 0 to 32 (33 columns in total)
Horizontal rows have indices 0 to 11 downwards (y coordinate). I number these 0 to 10 but note that columns like A have 10 full hexes and count from 1. Columns like B have 9 full hexes and a half hex at top and bottom. B type columns number from 0 to 10 in SL and Panzerblitz but not in Ancients or some other games!

I assign an index to hexes by using:
index = 100*col + row
So for example D4 has index 3*100+4 = 304

I had forgotten that some SL scenarios use 4 boards joined in a long horizontal row! It would be better to times by 1000.

Having defined a coordinate and index system next calculate the index change vectors required to move between adjacent hexes.
These differ between odd (B) and even (A) columns. Up and down within a column are the same for both.

At the same time you need to define the hex spines and use these as indices for two arrays of vectors for producing the index shifts for moves between hexes.
I use index 0 for 9 o'clock and go round clockwise.

You can now define the two movement arrays.
AFVCAEvenLeft = [-100,-101,-1,99,100,1 ]// even cols left
AFVCAEvenRight = [-101,-1,99,100,1, -100]// even cols right
AFVCAOddLeft= [-99,-100,-1,100,101,1]// odd cols 1 or B
AFVCAOddRight= [-100,-1,100,101,1,-99]// odd cols 1 or B
So if you are in E5 (405) and look along spine 0 then to the left is D5 (305) transition -100
If you look from E5 along spine 0 to the right is D4 ( 304) transistion -101.

Covered Arc Theory

Once you have defined spines and calculated transition vectors for your coordinate system then you can find the two vectors a (left vector) and b (right vector) as shown below.

Combinations of these two vectors will produce the indices of all the hexes in the covered arc and only of hexes in the covered arc.
Repeated application of vector a yields the left edge of the CA.
Repeated application of vector b yields the right edge of the CA.
Mixtures of both vectors yield all the hexes in between.

Covered Arc Calculation Algorithm

I use an array of hexes called board[] this is a sparse array as not all index values are used.
A dense array of used hex indices boardIndices[] this has all of board's indices and can be iterated over.
I also have a javascript SET object version of boardIndices which can be searched using boardIndicesSet.has(testIndex) to see if I have fallen off the board.
I believe that javascript Set operations are much quicker than array methods.

Algorithm

All arrays start from array index 0

Example. Starting from C4 (204) which is an even column looking along spine 3

Starting from hex with index originIndex and looking along spine spine

Find leftVector (a or AFVCAEvenLeft[3]) which is +99

Find rightVector (b or AFVCAEvenRight[3]) which is +100

Create stack stack and push originIndex onto it.

Create output set output

Do until stack has length zero

pop stack and call this value testindex

If output doesn't have testIndex add it to output

Create testIndexLeft = testIndex + leftVector
If boardIndicesSet has testindexLeft then you are still on the board.
If testindexLeft is not in the output set already and not in the stack then push this value push onto the stack

Create testIndexRight = testIndex + rightVector
If boardIndicesSet has testindexRight then you are still on the board.
If testindexRight is not in the output set already and not in the stack then push this value push onto the stack

Repeat

Further Points

There are multiple paths to any hexes within the CA but not on the edges. The indices of these will be created several times but should only be used once.
This process is necessary to cope with what happens when a CA hits the edges and corners of the board.