--!name Snake Trail
--!icon game
--!category Games
local v=snail.touchscreen==true local f,M=14,17 local t,F,u,H=1,12,2,15 local G={up={0,-1,"u","down"},down={0,1,"d","up"},left={-1,0,"l","right"},right={1,0,"r","left"},}local Y=4 local X={}local al={"..^!..","..++..","<++++>","=++++?","..++..","..~|.."}local g,L="menu",1 local d,E,i={},{},{}local B,r,k,q="right",nil,nil,0 local n,C,l,z=0,0,0,0 local y,m,U=false,1,false local p={0,0}local R=1 local function aw(au)R=(R*1664525+1013904223)&0xFFFFFFFF return(R>>16)%au end local function T()if m==1 then return math.max(450,900-C*15)end return math.max(450,750-C*15)end local function ax()snail.save(p[1]..","..p[2])end local function V()local J={}for a=u,H do for b=t,F do local c=a*f+b if not E[c]and c~=r and c~=k then J[#J+1]=c end end end if#J==0 then return nil end return J[aw(#J)+1]end local function av()if os and os.time then R=os.time()%100000+11 end d,E,i={},{},{}for h=0,2 do local c=8*f+6-h d[#d+1]=c E[c]=true end B,r,k,q="right",nil,nil,0 r=V()n,C,l,z=0,0,0,1 y=false g="play"snail.tick(T())end local function ah()g="over"snail.tick(0)U=n>p[m]if U then p[m]=n ax()end end local function aq()n=math.min(9999,n+1)C=C+1 r=V()if C%5==0 then k,q=V(),12 end snail.tick(T())end local function ay()if#i>0 then B=table.remove(i,1)end local ab=G[B]local b,a=d[1]%f+ab[1],d[1]//f+ab[2]if b<t or b>F or a<u or a>H then if m==1 then l=3 return end b=(b-t)%(F-t+1)+t a=(a-u)%(H-u+1)+u end local c=a*f+b local S,ak=c==r,d[#d]if E[c]and(S or c~=ak)then l=3 return end if not S then E[ak]=nil d[#d]=nil end table.insert(d,1,c)E[c]=true if S then aq()if not r then ah()end elseif c==k then n=math.min(9999,n+5)k,q=nil,0 end end function tick()if g~="play"or y then snail.tick(0)return end if z>0 then z=z-1 return end if l>0 then l=l-1 if l==0 then ah()end return end if q>0 then q=q-1 if q==0 then k=nil end end ay()end local function W(e)if g~="play"or y or z>0 or l>0 then return end local ag=i[#i]or B if e~=ag and e~=G[ag][4]and#i<2 then i[#i+1]=e end end function key(e)if g=="menu"then if e=="up"or e=="down"then L=3-L elseif e=="ok"then m=L av()end return end if g=="over"then if e=="ok"then g="menu"end return end if e=="ok"then y=not y snail.tick(y and 0 or T())return end if G[e]then W(e)end end local function ao(o,w)local a,b=w-M-1,o-1 if a<0 then return nil end local O,ac=2*(b-Y)-5,2*a-5 if O>=-7 and O<=7 then local _,aa=math.abs(O),math.abs(ac)if _>aa then return O<0 and"left"or"right"end if aa>_ then return ac<0 and"up"or"down"end return nil end for Z,x in ipairs(X)do if b>=x[1]and b<=x[1]+1 then return x[3]end end end function touch(at,o,w)if at~="board"then return end if v then local e=ao(o,w)if e then return key(e)end else o=o-1 end if w>M or g~="play"then return end local b,a=o-1,w-1 local ad,ae=d[1]%f,d[1]//f if G[i[#i]or B][1]~=0 then if a~=ae then W(a<ae and"up"or"down")end elseif b~=ad then W(b<ad and"left"or"right")end end local function ap()local j={}for a=1,6 do j[a]={}for b=1,f do j[a][b]="."end for h=1,6 do j[a][Y+h]=al[a]:sub(h,h)end end for Z,x in ipairs(X)do local P,a,b=x[4]and"()[]"or"$&;:",x[2]+1,x[1]+1 j[a][b],j[a][b+1]=P:sub(1,1),P:sub(2,2)j[a+1][b],j[a+1][b+1]=P:sub(3,3),P:sub(4,4)end for a=1,6 do j[a]=table.concat(j[a])end return j end local function ai(D)local K={}for a=0,M-1 do local A=table.concat(D[a])K[#K+1]=v and A or"."..A.."."end if v then for Z,Q in ipairs(ap())do K[#K+1]=Q end end return table.concat(K,"/")end local function am()local I=z>0 local D={}for a=0,M-1 do local Q={}for b=1,f do Q[b]="."end D[a]=Q end local function s(c,an)D[c//f][c%f+1]=an end local A=I and"8888"or string.format("%4d",n):gsub(" ","_")for h=1,4 do s(h-1,A:sub(h,h))end if I or k then local aj=I and"88"or string.format("%2d",q):gsub(" ","_")s(12,aj:sub(1,1));s(13,aj:sub(2,2))end local ar=m==1 and"w"or"v"for a=u-1,H+1 do for b=t-1,F+1 do local as=a>=u and a<=H and b>=t and b<=F s(a*f+b,as and(I and"b"or"B")or ar)end end if I then return ai(D)end if r then s(r,"f")end if k then s(k,"y")end for h=2,#d do s(d[h],"b")end s(d[1],l>0 and"x"or G[i[1]or B][3])return ai(D)end function draw()local af=string.format("GAME %s  BEST %d",m==1 and"A"or"B",p[m])snail.title((v and g~="menu")and"Snake Trail  "..af or"Snake Trail")if g=="menu"then snail.row("Game A",L==1)snail.row("Game B (wrap round, faster)",L==2)snail.gap()snail.text(string.format("Best: A %d   B %d",p[1],p[2]))snail.gap()snail.small("The snake moves by itself: steer it onto the apples.")if v then snail.small("Turn with the d-pad under the screen, or tap the")snail.small("screen on the side you want to turn to.")else snail.small("LEFT, RIGHT, UP and DOWN turn the snake.")end snail.small("Don't bite yourself. Game A has walls; in Game B the")snail.small("edges wrap round.")snail.hint("OK start BACK leave")return end if not v then snail.small(af)end local N=nil if z>0 then N="GAME "..(m==1 and"A"or"B")end if y then N="PAUSED"end if g=="over"then N=string.format("GAME OVER  %d%s",n,U and"  BEST!"or"")end snail.board(am(),nil,N)if g=="over"then snail.hint("OK menu BACK leave")elseif v then snail.hint("OK pause BACK leave")else snail.hint("L left R right OK pause BACK leave")end end function start()snail.ink("fast")local A=snail.load()if A then local o,w=A:match("(%d+),(%d+)")p={tonumber(o)or 0,tonumber(w)or 0}end end
