_TITLE "Snake AI-1_8 Trail Blazer" 'b+ 2020-03-21 and Ashish SUB snakeBrainAshish1
'2020-03-14 Snake AI-1 first post
'2020-03-16 Snake AI-1_1 there must be overlap of the snake somewhere! Aha!
'2020-03-17 Snake AI-1_2 fix the duplicate segment problem
' Now a new mystery, an ocassional flashing duplicate box
'2020-03-17 Install standard snake rules for testing brain evolving
' First setup XY type and rename and convert variables using XY type.
' 2nd Make snake brain and whole game only dependent sqrsX, sqrsY and sq for screen size
' Got it!!! the code ends with hangup head next to fruit with 99 (1 cell less that whole board)
' cells of snake length, no new place can be found for fruit, perfect finish and no duplicate
' cells! PLUS now can turn on a dime go up one colume and down the next in 2 key press.
' Now add autoPilot on -1 / off 0 toggle control, OK snake rules tested when human pilots snake.
' Help screen & independent speeds for human or AI.
'2020-03-18 "Snake AI-1_4 fix tester" The AI tester needs to save Head(x, y) in case the AI
' does not change the head(x, y) or tries to move it diagonally.
'2020-03-18 Snake AI-1_5 SHARE change AS XY
' DIM SHARE change AS XY or change.x, change.y replaces variables called dx, dy.
' I decided to switch over to human control if AI fails to return a proper change.
' AI must leave change.x, change.y ready for human to take over control which means my changing
' the code for toggling the autopilot and adding change.x, change.y updates in my snakeBrain SUB.
' Rewrite SnakeBrain using only change.X and change.Y now. A BEEP will indicate an AI error and
' signal control returned to human. This noted in Key Help part of screen.
'2020-03-19 Snake AI-1_6 B+brain#2 begin a new snakeBrainBplus2 sub routine
' Add a driver report in title bar along with sLen.
' Oh hey what a fancy snake dance, not the least bit faster than snakeBrainBplus1.
'2020-03-20 Snake AI-1_7 real AI
' RE: snakeBrainBplus2
' Recode snakeBrainBplus2 to be self contained in one SUB, load data for the array it uses inside
' that SUB. It also has to check sqrsX, sqrsY to be sure they are correct, this is pure novelty
' SUB so will set sqrsX, sqrsY back to 20 each for standard game AI setting. OK good!
' RE: sqrsX, sqrsY
' sqrsX, sqrsY reset back to 20, 20 for standard setup for testing AI.
' RE: Ashish first "real AI" very excellent submission!
' Attempt to incorporate Ashish "real AI" as SUB snakeBrainAshish1
' Ashish is using $CONSOLE and DIM SHARED state$ but I don't see why so I made state$ STATIC in
' his SUB and took console out, though I can see it might be needed later. Working here yeah!
' RE: SnakeBrainBplus3, bplus first "real AI" also working pretty well to a point.
' SnakeBrainBplus3 uses real AI and crashes when snake can't get to fruit due to it's length
' either by inaccessible fruit, snakes body blocks head or head buried in body and can't escape.
' Using lessons learned from Pathfinder work.
'2020-03-21 Snake AI-1_8 Trail Blazer
' As described at forum today, entice snake to safely coil itself before going after fruit at
' each increase of it's length. Does't look like this will work out.
' 3-22 try trailblazer sqaure attack pattern
' Snakepit Dimensions: square size = sq, sqrsX = # of squares along x-axis and sqrsY squares down.
CONST sq
= 20, sqrsX
= 20, sqrsY
= 20, xmax
= sq
* sqrsX
, ymax
= sq
* sqrsY
'Usually used to give a point on 2D board a single name that has an X dimension and a Y dimension.
' SHARED variables for any version of SnakeBrain SUB to act as autoPilot for snake snake.
DIM SHARED change
AS XY
' directs the head direction through AI or Human DIM SHARED head
AS XY
' leads the way of the snake(body) through snakepit DIM SHARED snake
(1 TO sqrsX
* sqrsY
) AS XY
' whole snake, head is at index = sLen DIM SHARED fruit
AS XY
' as snake eats fruit it grows, object is to grow snake to fill snakepit
' SHARED for screenUpdate
'other data needed for program
help ' Key Menu
hSpeed = 3: aSpeed = 20 ' autopilot speed is independent of human control speed
restart: ' reinitialize
r
= .3 + RND * .7: g
= r
* .5 + RND * .3 - .15: b
= .5 * r
+ RND * .3 - .15 ' rnd pal color varsFOR i
= 1 TO sqrsX
* sqrsY
' enough colors for snake to fill snakepit pal
(i
) = _RGB32(84 + 64 * SIN(r
+ i
/ 2), 84 + 64 * SIN(g
+ i
/ 2), 104 * SIN(b
+ i
/ 2))head.X = sqrsX / 2 - 3: head.Y = sqrsY / 2 - 3 ' head start
fruit.X = sqrsX - 1: fruit.Y = sqrsY - 1
'fruit.X = sqrsX / 2 + 2: fruit.Y = sqrsY / 2 + 2 ' first fruit
sLen = 1 ' for starters snake is all head
snake(sLen).X = head.X: snake(sLen).Y = head.Y ' head is always at sLen end
autoPilot = 1 ' start snake body count
change.X = 0: change.Y = 1 ' head snake down board, Y direction of first fruit
IF autoPilot
THEN title$
= "AI." ELSE title$
= "human." _TITLE STR$(sLen
) + " Current driver is " + title$
LINE (0, 0)-(xmax
, ymax
), &HFF884422, BF
' clear snakepit IF sLen
= sqrsX
* sqrsY
- 1 THEN screenUpdate:
EXIT DO ' game is won! start another autoPilot = 1 - autoPilot ' it is now up to AI to keep change updated for human take over
ELSEIF KEY$
= "p" THEN ' pause toggle p starts pause p ends pause IF autoPilot
AND aSpeed
+ 5 < 400 THEN aSpeed
= aSpeed
+ 5 'max autopilot speed is 400 !!! IF autoPilot
= 0 AND hSpeed
+ .5 < 10 THEN hSpeed
= hSpeed
+ .5 ' max human speed is 10 IF autoPilot
AND aSpeed
- 5 > 0 THEN aSpeed
= aSpeed
- 5 IF autoPilot
= 0 AND hSpeed
- .5 > 1 THEN hSpeed
= hSpeed
- .5
IF autoPilot
THEN ' who is piloting the snake?
saveChange.X = change.X: saveChange.Y = change.Y ' if AI screws up then human takes over
' PLUG-IN YOUR Snake Brain AI here
'=========================================================================== AI Auto Pilot
'snakeBrainBplus1 ' dumb track AI but always gets it's fruit! requires even # sqrsX
'snakeBrainBplus2 ' dumb track AI but looks cool! requirescustom sqrsX = 17, sqrsY = 16
'snakeBrainAshish1 ' first "realAI" I would call an heuristic approach, thanks Ashish!
'snakeBrainBplus3 ' bplus "first real AI" uses modified Pathfinder methods
snakeBrainBplus4
'=========================================================================================
'check changes
IF ABS(change.X
) = 0 THEN ' must have diffence in y's IF ABS(change.Y
) <> 1 THEN autoPilot
= 0 ' error switch to human IF ABS(change.X
) <> 1 THEN autoPilot
= 0 ' error switch to human ELSE ' must have a 0 in either change.x or change.y but not both autoPilot = 0 ' error switch to human
IF autoPilot
= 0 THEN ' switching control over to human restore change values change.X
= saveChange.X: change.Y
= saveChange.Y:
BEEP ' alert human
ELSE ' ======================================================================= human control change.X = 0: change.Y = -1
change.X = 0: change.Y = 1
change.X = 1: change.Y = 0
change.X = -1: change.Y = 0
head.X = head.X + change.X: head.Y = head.Y + change.Y ' OK human or AI have spoken
' ============================ check snake head with Rules: ===============================
' 1. Snakepit boundary check, snake hits wall, dies.
IF head.X
< 0 OR head.X
> sqrsX
- 1 OR head.Y
< 0 OR head.Y
> sqrsY
- 1 THEN
' 2. Snake eats body part, dies. This should kill snake if turn its head back on itself.
FOR i
= 1 TO sLen
' did head just crash into body? IF head.X
= snake
(i
).X
AND head.Y
= snake
(i
).Y
THEN
' 3. Eats Fruit and grows or just move every segment up 1 space.
IF (fruit.X
= head.X
AND fruit.Y
= head.Y
) THEN ' snake eats fruit sLen = sLen + 1
snake(sLen).X = head.X: snake(sLen).Y = head.Y 'assimilate fruit into head for new segment
fruit.X
= INT(RND * sqrsX
): fruit.Y
= INT(RND * sqrsY
): good
= -1 FOR i
= 1 TO sLen
' move the snake data down 1 dropping off last snake(i).X = snake(i + 1).X: snake(i).Y = snake(i + 1).Y
snake(sLen).X = head.X: snake(sLen).Y = head.Y ' and adding new head position
screenUpdate ' on with the show this is it!
_DELAY 4 ' win or loose, go again
SUB screenUpdate
' draw snake and fruit, overlap code debugger DIM c~&
, i
, overlap
(sqrsX
, sqrsY
) IF i
= sLen
THEN c~&
= &HFF000000 ELSE c~&
= pal
(sLen
- i
)
' overlap helps debug duplicate square drawing which indicates a flawed code
overlap(snake(i).X, snake(i).Y) = overlap(snake(i).X, snake(i).Y) + 1
LINE (snake
(i
).X
* sq
, snake
(i
).Y
* sq
)-STEP(sq
- 2, sq
- 2), c~&
, BF
IF overlap
(snake
(i
).X
, snake
(i
).Y
) > 1 THEN 'show visually where code flaws effect display LINE (snake
(i
).X
* sq
+ .25 * sq
, snake
(i
).Y
* sq
+ .25 * sq
)_
-STEP(.5 * sq
- 2, .5 * sq
- 2), &HFFFFFFFF, BF
LINE (fruit.X
* sq
, fruit.Y
* sq
)-STEP(sq
- 2, sq
- 2), _RGB32(255, 100, 255), BF
'bplus using for test of brain 4
LINE (0, yHeadLimit
* sq
)-(xmax
, ymax
), &H11FFFFFF, BF
'basic functions added for snakeBrainBplus3 (bplus first real AI)
' ================================================================= end code that runs Snake Games
SUB snakeBrainBplus1
'>>>>>>>>>> B+ SNAKE BRAIN needs sqrsX to be even number <<<<<<<<<<<<<<< ' This will be handy for standard 20x20 snakepit to dove tail real AI towrds.
'todo fix this so that when takeover control won't crash into self
IF sqrsX
MOD 2 = 1 THEN change.X
= 0: change.Y
= 0:
EXIT SUB ' throw error for code check to ' discover and switch to human control
change.X = 0: change.Y = -1
change.X = 0: change.Y = -1
change.X = 1: change.Y = 0
change.X = 1: change.Y = 0
change.X = 0: change.Y = 1
change.X = -1: change.Y = 0
change.X = -1: change.Y = 0
change.X = 0: change.Y = 1
change.X = 0: change.Y = 1
SUB snakeBrainBplus2
' Needs custom sqrsX = 17, sqrsY = 16 This is mainly a novelty SUB for fun! 'A good AI will NOT require a custom sqrsX = 17, sqrsY = 16
IF sqrsX
<> 17 OR sqrsY
<> 16 THEN change.X
= 0: change.Y
= 0:
EXIT SUB ' throw error for code ' check to discover and switch to human control
IF brain2Directions
(0, 0) <> "R" THEN GOSUB loadBrain2Directions
'array not loaded yet so load direction$ = brain2Directions(head.X, head.Y)
CASE "U": change.X
= 0: change.Y
= -1 CASE "D": change.X
= 0: change.Y
= 1 CASE "L": change.X
= -1: change.Y
= 0 CASE "R": change.X
= 1: change.Y
= 0 loadBrain2Directions:
brain2Directions
(x
, y
) = MID$(s$
, x
+ 1, 1)
' note: I had the following lines in main code delares section in case OPTION _EXPLICIT
' started alerts about DIM the STATIC variable in main but not needed.
'
' I think OPTION _EXPLICIT requires next line but will make snakeBrainBplus2 self contained.
'DIM SHARED brain2Directions(0 TO sqrsX - 1, 0 TO sqrsY - 1) AS STRING ' 4 snakeBrainBplus2 AI
SUB snakeBrainAshish1
'needs supplemental FUNCTION snakeBodyExists (which%) DIM nx
, ny
, dx
, dy
'Ashish AI STATIC state$
' bplus added state$ to SUB here and removed from DIM SHARED in Main Declares dx = fruit.X - head.X
dy = fruit.Y - head.Y
nx = snakeBodyExists(1)
ny = snakeBodyExists(2)
IF sLen
> 1 THEN 'collison at corners of square state$ = "corners"
IF change.X
= -1 THEN change.X
= 0: change.Y
= 1: decided
= 0:
EXIT SUB IF change.Y
= -1 THEN change.Y
= 0: change.X
= 1: decided
= 0:
EXIT SUB state$ = "corners"
IF change.X
= -1 THEN change.X
= 0: change.Y
= -1: decided
= 0:
EXIT SUB IF change.Y
= 1 THEN change.Y
= 0: change.X
= 1: decided
= 0: decided
= 0:
EXIT SUB state$ = "corners"
IF change.X
= 1 THEN change.X
= 0: change.Y
= 1: decided
= 0:
EXIT SUB IF change.Y
= -1 THEN change.Y
= 0: change.X
= -1: decided
= 0:
EXIT SUB state$ = "corners"
IF change.X
= 1 THEN change.X
= 0: change.Y
= -1: decided
= 0:
EXIT SUB IF change.Y
= 1 THEN change.Y
= 0: change.X
= -1: decided
= 0:
EXIT SUB IF decided
= 0 THEN 'collision with walls IF head.X
= sqrsX
- 1 OR head.X
= 0 THEN state$ = "walls"
change.Y = ny * -1: change.X = 0
decided = 1
state$ = "walls"
change.X = nx * -1: change.Y = 0
decided = 1
IF dx
= 0 THEN 'when fruit and head in same direction and motion in same axis state$ = "linear"
change.Y
= 1: change.X
= 0: decided
= 0:
EXIT SUB change.Y
= -1: change.X
= 0: decided
= 0:
EXIT SUB state$ = "linear"
change.X
= 1: change.Y
= 0: decided
= 0:
EXIT SUB change.X
= -1: change.Y
= 0: decided
= 0:
EXIT SUB
state$ = "common"
'common decision
state$
= "common ny=" + STR$(ny
) change.X = 0
state$
= "common cy=" + STR$(change.Y
) IF dy
> 0 AND ny
<> 1 THEN change.Y
= 1: change.X
= 0 IF dy
< 0 AND ny
<> -1 THEN change.Y
= -1: change.X
= 0 decided = 0
state$
= "common nx=" + STR$(nx
) change.Y = 0
state$
= "common cx=" + STR$(change.X
) IF dx
> 0 AND nx
<> 1 THEN change.X
= 1: change.Y
= 0 IF dx
< 0 AND nx
<> -1 THEN change.X
= -1: change.Y
= 0 decided = 0
state$ = "rand_common"
IF ABS(dx
) = ABS(dy
) THEN 'random choice will be made then, rest code is same as above state$
= "rand_common ny=" + STR$(ny
) change.X = 0
state$
= "rand_common cy=" + STR$(change.Y
) IF dy
> 0 AND ny
<> 1 THEN change.Y
= 1: change.X
= 0 IF dy
< 0 AND ny
<> -1 THEN change.Y
= -1: change.X
= 0 decided = 0
state$
= "rand_common nx=" + STR$(nx
) change.Y = 0
state$
= "rand_common cx=" + STR$(change.X
) IF dx
> 0 AND nx
<> 1 THEN change.X
= 1: change.Y
= 0 IF dx
< 0 AND nx
<> -1 THEN change.X
= -1: change.Y
= 0 decided = 0
FUNCTION snakeBodyExists
(which%
) ' for SUB snakeBrainAshish1 supplemental IF which%
= 1 THEN 'x-direction
SUB snakeBrainBplus3
' real AI, responds to real time information
'needs FUNCTION max (n , m ), FUNCTION min (n , m )
'from: Pathfinder inside Maze.bas B+ 2019-12-19 only completely overhauled!
DIM parentF
, tick
, foundHead
, headMarked
DIM yStart
, yStop
, xStart
, xStop
map(x, y) = " "
FOR i
= 1 TO sLen
- 1 ' draw snake in map map(snake(i).X, snake(i).Y) = "S"
map(head.X, head.Y) = "H"
map(fruit.X, fruit.Y) = "F"
tick = 0
parentF = 0: tick = tick + 1
yStart = max(fruit.Y - tick, 0): yStop = min(fruit.Y + tick, sqrsY - 1)
REDIM map2
(sqrsX
- 1, sqrsY
- 1) AS STRING ' need a 2nd map to hold all new stuff until FOR y
= 0 TO sqrsY
- 1 ' the entire square coverd map2(x, y) = " "
xStart = max(fruit.X - tick, 0): xStop = min(fruit.X + tick, sqrsX - 1)
'check out the neighbors
IF map
(x
, y
) = " " OR map
(x
, y
) = "H" THEN IF map
(x
, y
) = "H" THEN foundHead
= -1 map2(x, y) = "U": parentF = 1
IF foundHead
THEN headMarked
= -1 map2(x, y) = "D": parentF = 1
IF foundHead
THEN headMarked
= -1 map2(x, y) = "R": parentF = 1
IF foundHead
THEN headMarked
= -1 map2(x, y) = "L": parentF = 1
IF foundHead
THEN headMarked
= -1 FOR y
= 0 TO sqrsY
- 1 'transfer data to map IF map2
(x
, y
) <> " " THEN map
(x
, y
) = map2
(x
, y
): changeF
= 1 WEND 'if no ParentF then dead connection to Fruit CASE "H" ' cause crash because no connection to fruit found IF change.X
THEN change.X
= -change.X
ELSE change.Y
= -change.Y
'make Body crash ' change.X = 0: change.Y = 0 ' this will switch auto control off to avoid program hang, dang still hangs!
CASE "D": change.X
= 0: change.Y
= 1 CASE "U": change.X
= 0: change.Y
= -1 CASE "R": change.X
= 1: change.Y
= 0 CASE "L": change.X
= -1: change.Y
= 0
'SUB snakeBrainBplus 4 ' fake fruit test responds to real time information
' 'needs FUNCTION max (n , m ), FUNCTION min (n , m )
' 'from: Pathfinder inside Maze.bas B+ 2019-12-19 only completely overhauled!
' DIM x, y, i, changeF
' DIM parentF, tick, foundHead, headMarked
' DIM yStart, yStop, xStart, xStop
' DIM map(sqrsX - 1, sqrsY - 1) AS STRING, map2(sqrsX - 1, sqrsY - 1) AS STRING
' 'fake fruit variables
' STATIC lastSLen, goals(1 TO 40) AS XY, topGoal
' FOR y = 0 TO sqrsY - 1
' FOR x = 0 TO sqrsX - 1
' map(x, y) = " "
' NEXT
' NEXT
' FOR i = 1 TO sLen - 1 ' draw snake in map
' map(snake(i).X, snake(i).Y) = "S"
' NEXT
' map(head.X, head.Y) = "H"
' 'fake fruit before releaseing snake to persue real fruit, we setup some fale fruit goals
' 'to persue first in order to safely coil the snake so it's doesn't entangle itself and
' ' choke itelf of access to fruit
' IF sLen > lastSLen THEN
' 'make goals list if hasn't been made yet
' IF goals(2).Y <> sqrsY - 1 THEN
' goals(1).X = 0: goals(1).Y = 0
' goals(2).X = 0: goals(2).Y = sqrsY - 1
' goals(3).X = sqrsX - 1: goals(3).Y = sqrsY - 1
' i = 4
' WHILE i + 1 < sqrsY * 2
' goals(i).X = sqrsX - 1: goals(i).Y = goals(i - 1).Y - 1
' goals(i + 1).X = 1: goals(i + 1).Y = goals(i).Y
' goals(i + 2).X = 1: goals(i + 2).Y = goals(i).Y - 1
' goals(i + 3).X = sqrsX - 1: goals(i + 3).Y = goals(i + 2).Y
' i = i + 4
' WEND
' END IF 'list not made yet
' topGoal = sLen \ 20 'set new goal
' lastSLen = sLen 'reset checker
' END IF
' IF topGoal THEN
' IF head.X = goals(topGoal).X AND head.Y = goals(topGoal).Y THEN topGoal = topGoal - 1
' IF topGoal THEN map(goals(topGoal).X, goals(topGoal).Y) = "F" ELSE map(fruit.X, fruit.Y) = "F"
' ELSE
' map(fruit.X, fruit.Y) = "F"
' END IF
' 'ok false fruit or fruit target set for pathfinder
' tick = 0
' WHILE parentF OR headMarked = 0
' parentF = 0: tick = tick + 1
' yStart = max(fruit.Y - tick, 0): yStop = min(fruit.Y + tick, sqrsY - 1)
' REDIM map2(sqrsX - 1, sqrsY - 1) AS STRING ' need a 2nd map to hold all new stuff until
' FOR y = 0 TO sqrsY - 1 ' the entire square coverd
' FOR x = 0 TO sqrsX - 1
' map2(x, y) = " "
' NEXT
' NEXT
' FOR y = yStart TO yStop
' xStart = max(fruit.X - tick, 0): xStop = min(fruit.X + tick, sqrsX - 1)
' FOR x = xStart TO xStop
' 'check out the neighbors
' IF map(x, y) = " " OR map(x, y) = "H" THEN
' IF map(x, y) = "H" THEN foundHead = -1
' IF y - 1 >= 0 THEN
' IF INSTR("UDLRF", map(x, y - 1)) THEN
' map2(x, y) = "U": parentF = 1
' IF foundHead THEN headMarked = -1
' END IF
' END IF
' IF y + 1 <= sqrsY - 1 THEN
' IF INSTR("UDLRF", map(x, y + 1)) THEN
' map2(x, y) = "D": parentF = 1
' IF foundHead THEN headMarked = -1
' END IF
' END IF
' IF x + 1 <= sqrsX - 1 THEN
' IF INSTR("UDLRF", map(x + 1, y)) THEN
' map2(x, y) = "R": parentF = 1
' IF foundHead THEN headMarked = -1
' END IF
' END IF
' IF x - 1 >= 0 THEN
' IF INSTR("UDLRF", map(x - 1, y)) THEN
' map2(x, y) = "L": parentF = 1
' IF foundHead THEN headMarked = -1
' END IF
' END IF
' END IF
' NEXT
' NEXT
' FOR y = 0 TO sqrsY - 1 'transfer data to map
' FOR x = 0 TO sqrsX - 1
' IF map2(x, y) <> " " THEN map(x, y) = map2(x, y): changeF = 1
' NEXT
' NEXT
' WEND 'if no ParentF then dead connection to Fruit
' SELECT CASE map(head.X, head.Y)
' CASE "H" ' cause crash because no connection to fruit found
' IF change.X THEN change.X = -change.X ELSE change.Y = -change.Y 'make Body crash
' ' change.X = 0: change.Y = 0 ' this will switch auto control off to avoid program hang, dang still hangs!
' CASE "D": change.X = 0: change.Y = 1
' CASE "U": change.X = 0: change.Y = -1
' CASE "R": change.X = 1: change.Y = 0
' CASE "L": change.X = -1: change.Y = 0
' END SELECT
'END SUB
SUB snakeBrainBplus4
' real AI, responds to real time information 'STATIC xLim, yLim, dat$(sqrsX - 1, sqrsY - 1)
DIM xlim
, ylim
, bodyStack
xlim = sqrsX - 1: ylim = sqrsY - 1
'IF dat$(0, 0) <> "D" THEN GOSUB setupdat 'haven't been here yet
bodyStack
= INT(sLen
/ 40) 'these are integers so 0 for first 40 yHeadLimit = ylim - bodyStack * 2 + 1
'IF head.Y >= yHeadLimit THEN '<<<<<<<<<<<<<<<<< go up om even when stacking
'IF head.X MOD 2 = 0 THEN 'even row includes top row
' IF head.X = 0 THEN
' IF head.Y <> ylim THEN
' change.X = 0: change.Y = 1
' ELSE
' change.X = 1: change.Y = 0
' END IF
' ELSEIF head.X = 1 THEN
' IF head.Y <> 0 THEN
' change.X = 0: change.Y = -1
' ELSE
' change.X = -1: change.Y = 0
' END IF
' ELSEIF head.X > 1 AND head.X < xlim THEN
' change.X = -1: change.Y = 0
' ELSEIF head.X = xlim THEN
' change.X = -1: change.Y = 0
' END IF
'ELSE 'head.x mod 2 = 1 'includes bottom row
' IF head.X = 0 THEN
' IF head.Y = ylim THEN
' change.X = 1: change.Y = 0
' ELSE
' change.X = 0: change.Y = 1
' END IF
' ELSEIF head.X >= 1 AND head.X <> xlim THEN 'crashing on bottom line
' change.X = 1: change.Y = 0
' ELSEIF head.X = xlim THEN
' change.X = 0: change.Y = -1
' END IF
'END IF
'ELSE ' head.y < yheadlimit
change.X = 0: change.Y = 1
change.X = 1: change.Y = 0
change.X = 1: change.Y = 0
change.X = -1: change.Y = 0
change.X = -1: change.Y = 0
change.X = -1: change.Y = 0
change.X = 0: change.Y = -1
'END IF
'setupdat:
'FOR y = 0 TO yLim
' FOR x = 0 TO xLim
' IF x = 0 AND y <> yLim THEN ' left side
' dat$(x, y) = "D"
' ELSEIF x = 0 AND y = yLim THEN 'bottom, left corner
' dat$(x, y) = "R"
' ELSEIF x <> xLim AND y = yLim THEN 'bottom row
' dat$(x, y) = "R"
' ELSEIF x = xLim AND y MOD 2 = 1 THEN ' right side up odd
' dat$(x, y) = "U"
' ELSEIF x = xLim AND y MOD 2 = 0 THEN 'right side left even
' dat$(x, y) = "L"
' ELSEIF y MOD 2 = 0 AND x = 1 AND y <> 0 THEN ' left coil even turn up
' dat$(x, y) = "U"
' ELSEIF y MOD 2 = 0 AND x = 1 AND y = 0 THEN 'left coil even on top row
' dat$(x, y) = "L"
' ELSEIF y MOD 2 = 1 AND x <> 1 THEN 'coil odd row
' dat$(x, y) = "R"
' ELSEIF y MOD 2 = 1 AND x = 1 AND y <> yLim THEN ' coil odd row
' dat$(x, y) = "R"
' ELSEIF y MOD 2 = 0 AND x <> 1 THEN 'coil even
' dat$(x, y) = "L"
' ELSEIF y MOD 2 = 0 AND x = 1 THEN 'coil even
' dat$(x, y) = "R"
' END IF
' NEXT
'NEXT
'RETURN