--!name Tents
--!icon puzzle
--!category Puzzles
local aE="!$%&()+,-0123456789:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnpqrstuvwxyz|~"local function aC(b)return aE:sub(b+1,b+1)end local aG,aF,aJ,aL=5,10,18,26 local N={6,8,11}local aM={0,34,0}local I={"Easy","Medium","Hard"}local aj={"022HW6M000aO0WaG20b0G9c0bW06a00OcG06098H4YW0G498a020169a0261G0W804W2GbO05Y81088444cO06a00864X8I4086412c1G2c12P418cG0W060ab02I0X02G0006W4G8c0G0a601O200Oc4K88aOM0W2G1Y010YPK08OG0c006aaG4W801428aY6H46800GbW209804O900XOIcM00OG0W408aa0029X40O0062112910Y0G6609I0X10c8040YGG89400a02PW0I6b00a9G0WOW0I0X8GK4c8c6G08Y4H042OaO00G9Y0HOc0G9c04089G1c2O2GbW6408O009Y0H1WW0I2111824002M1026824X9G408W0MXOI0WGGW002M2814cOK08O00c9H02900900OW0IO10aO0009O61Wa0468000cPG0WO0088441X8240a00caGO10ca02I01a00c8G40bOI1W28O4000O80LOYa241800OG0cOa201XXG28G4W9O000aa20HaW1WO0GaW01Xa2M0W2211804Pc029X46HXW26020b01WW6G0O6b02804O00aO0cG0600a020bO8c4G0a90HOY0c814O900W0GO9102bWG0W162W8M4H1Y2001WGcW108449c00a028146OW0IG0c0H82LWW02P2I01a6418200Y9H0804a01PY60b029H0YO000GOc0498042OaO61W2IG1122bWGMWW020X0M804Oc0108940W0G2016O042OW0IOW4M102a01c0000089K0c9814c002M1W6805W0018c40OW9G09102G0c694G8Y01G4c802H02aG0WG1YI824X1GIOW00610c2010011c2c058845W8M0W901Wa00XOI00O019I0W6I1X2aaG0Wc0G0GacW6G0I0X9002M06W0G92G00cPa00O90062H0202c1G9009b021OY0H0c4086000aOM0W9G1Wc0428b006c0G9aG4X820G4W80021Xa00WaI012610b6204281O00Oc0G0H4Y8O8042018O50cIMW00825529WcM00W9G0G2W1aa12c1G0XY01009WGMYGH2Y16804W0GaX1I2PW0GGcW0GcWG0OcG06a0G4c8aH0YO00H0YO0aO2G09W0G099","W012OG0IY814IM00G92O004MOY0G12084W0X2G041Wc081WIH60800022P40004cGWaaG02990G0Q8aGH218082G000c41GYY0542PY00K0c600908I0I5008c804M006GaWc0101W5WWW900HXY005XW021YK002H2G84W9X040WW101W1W2004XW900IGO001c2GG420c0440WX009c040ac000aYG102Oa402GG1Yc00490bWW0104W9X808O0GGG1Y60040ac00162O0089cGH429WcK00c200400089OM06400W6Oa006010H8282005WGa20b698GO28G0I26040001c9000PO9O020O000a01c1808G10P8WO121Y044WW1G0cPW004O8W0G28b4G9XW002K90W0aA09KW0X112O00089OG0000Hc20008bWK04W2W049bW9a0G1288GH22OWG121AG8GaWO500c0002004W018QPG00W019Y9G42P04801M1A080PW408W0GcI00400OW059aW9c8G0G2HG0A0002II0641W260K1Y0W0bO00HXY400XW00O0W2H848GWG0669002HXWc2G4002P10181e0b0080O00PW000YH10AG0022YK51YGI025WW012GO404W2W94O1WXO18010W81820G5c8W4H9W06800MO9000G9I02G2M60W0W111eOG02O800M0H0281W20Q4W410Y4PKW2040GYI00840GXW00WcP10IG20Y4b4W09P108804M8Y0G4IaY401W0a904O9cG1289WG0O0W2H0G2M24W4Wa106801089WG0088WGH40GXY800Pa0GOYO100b209a01G0A6844HWW8000G9Y91060c0X0100O0G1Y1WO0W0H9Y6G0IM2000OI024099O008W2H04aaW01I1Q480M1Q080069001WY0149490W0a001a1XYG8000aa408YPG2085WH0681408fa0008bWG0226440Oa0G229442OYGG0a9490W6080GG2600HO28600GYI100cGW614WWXX0900G00O9W818I0H4G8c000OOO0W8P0G0a6a0109PW2022G5WO480WPWOG00a00622G6Hc0a0W0109090W1X6081WK09WY0P5W009O80GKY8X0GO0a0YGP00696022G4041OW809042OX408WG1Q0408WaH898G08G0I21048900PY80KIIPWb4H8Y800400W2G00W9X9G006PX1088G069OX009W00900WY1140cc11G02890G09000G022904M9I02000c044OW82OM400a8a1G08W0160a000G0c000a20ALWK01Wb80801X808GW6b6090000W9b90006PW0GO2021W5a2GW14O8W0W0X210K02QIG04WGX202G00AGOG00O9O4G0Y9005W0W9O040WW1GO290WG1I2205W9aX019X808GO4G0Ya00990WM125fGW200061Y0W411W0XW504W8W9K00W6020b4080a6O2G44WWXP408W2006G1W602014c8a40PW90666400WWY114f8bGG296011988000W25O4W009Y4GKe20G04aaW6OO0002024O4080cHX1W00O000PW04PWW00IG2004cPWcG800GOW010090O090O6O09Oa00M120800M220K0Y9b0aa000080XM181W2G00899GGcQ1408c011W6004OaW000cKa0W0W2X050W0H92000O0W910Gfc100080GG2OW011W0bWW010OX818Ga1XWW410Wa2P80OGa00O080aG4O0W1WGOc9000YcH500ec1100090a2O20I4840I0aa11O8400WOaW414W9XO081W01O480W008PWG0O1808M800HY99400cG809O00G6201a8WOH00902G800P1W2005X4W8X4G0Y0Wc504YLX4W8W000a00092GI8Y5H0810088W0H2W2L2HW0cK00YG01YI005c2404YG009c804G66010We11M6600WYO10G02K60W0W616062M0006O409W2004aY414Y9W410cLW0WIG20824GaX1081W2G1W9W9G061c0000W6106M0W","08O1WG64H00Y8880GGM2Oa1001801e22G24045W9W0901W0XW8X0WHG1628100M80O04a20W95HOMA82000O0PW1W4006W9W10GOebX1009Y6O040690000992G2GH2029a200041W2HW0H09c80000YM9b00H01Y8900YGWbGb0I08Y0WH011YOa00GO1090e901006PYM002OOA0G0KGW1c1O80O18018GG80cO0W02H090Ga620690141YOX00G8Gc8200G40OWcO10092I02G4QG0a0cOa0402GM00c0XO0181WW4a14WO8W10G09W9W0OG002GHW0Y09108024Hc4W01WWaW9110O809G042P9YGc2GP10008Y091480aaP000GaWc0100I162482GO1W80MOM208012GM84201Y0W0K1PY8O00G104180c81WIG0A0a9G002a2M420094cM1X0009XW4G09Y0001c0W8XXOH0902G0I0X24b8008G80IOGY0414aYGO00O0400OY8OH4H28W805908WH9G28G00262I0G04Q6Oa08010Gc821425OX6O180086O0006062G90G01Y9aa09WW01120PYKa4000W9fWO1590OW2O1O448G0W2600I69c4000O0091cO4GG4Y24W00W0PW8O04G0aWbW00224444Wc2K1G0YQ0W00101PXYO10009X1GG8A2000908020Hf42H0b0AG9W0a08409GW00W0ab2K080W9Ga0208849GG94cO0W42G02G04GO8YO8K00GW9IG920IGc210408YOW141909W08GG0M6020WYL010880a0G0692IG0GGcI2402GXW1006860020Y255K48YOO000c9a5000XW00W889GGKI2Gc00a00aPYG005Y9WW4G0a1WW20H04c9W00H8420GY0Oa4806OM0004OcOW040c8154G8Wc90GG62290G00Y9OX4010X0Wa8104060W8XWWH011XWMW0I5620X01W9WGG0221O0H80c8600014YQOX0G0001XXYG001X910869W6006084GGGY2905W00W0c060480YOG140PWYa014906029GYK211W1W9O2G00Ge221H412OW801O6OW0G10I1c20W00b1c00YO2H42Ge901G66P8108G8a001O0O89a0000009a2G0aGIG22064Gc0Y0401W2GX9GX92108448GWWM009W0028c84H0Gc00049a4G00Y60a6HWOWa110288cK00bY000429Xc4G01060880O6G0429WXaG00IM4Q00W000G2I29X4019WO04O1WW01a2IO2H0608X00189a90O2G42GWW0X0O1001W9f1O1M81Y01W060091O82O0G0W04b20W14aO8010669W00060190a8IG62462Gc1WOPY4004eO0WG610600Y4O14W18a98GG14I08Y0900600O08OG0G2cO0040cM9W10K08OWW101O808G1WI0XY1X04020M94Y0HX024840WGWa00009WOOHO02O00O0185c8KW06W090Ga0I09Y01G2O9WGG4280W0M02G08X0aH818008HWa00049YOWK0H9c6800008M4aI0WW0a1204K4WYW1406OW2H4208c410G28Y4514W9WW0a00WIM1200000PW2P42G0Y04W4aXO40O6WGH4228WO1Y80a4O021HX4808O4102Y80KKG222600049c9WGc42L0YGY00W4812KI20c44a5W0GW220G4G20I91Y09W04H6Oe801G28904G8O9b000AIO900G080aGIG208WOOHO08900GGb0209Y0W0410WOOb10009YOW00H0c404KW0Y00aGb0208X1W1842O0X4H08c8GH4228W001WGaa20090I06Q414GYOYb0000WcG100W801OHc08cH0G08190G80Y85X1OW68GO00a0a05W68W60G600aWG05I64Y0HW0c8GWG2120001O618O082HW02G2M06992100a8a1O08008HXWH012PY801400809X5W18WOO2O02GK002Y064490Pa0Y0910WHWL242W0W09a600HYGc00444cWWW40004aWbW10819W08G6968G2GI062OG0GI0200W4cPOW0G02GWIG120cIGa00a06G1WWY02HKO1Y00a0bWHW020000Y8014HYPXW05108YO0G88XXGH08W091O90W00X291a4HW4Y00X0O01X0609Wc0O10W2210449c2OG4aG9Xc000002GWW0110a1c0082G0G0YI2L040Y1YGLW02100GA9Y0K14208c09G1Wbc4800WP8060IH194880WGG02202H0O08W0a1OaO01W08W60H64004W1WWG10209W0O0G0II8cG0G2OOcG60900X29X84196QP200046Xc2H001WGI0224a0000O620004YO010G9108HfXI00800022864KGGY0c11W1Wb9W08G0062OcMK00bXYGW008609PG01292O0000OOaO4088W0IG626O04a00X02HOcG810OG8G0a22G0b9W4818W0aG1W60G00292G02GWM0b2000G0aA9a9G0ac4004XWOWaO1094200W4W02H8YGOH02KO10W2O02P4A00WK80OOGaG0029W001OOaG002020G24QO5W0Y8914H1a280Y40041Y42G4W02O2O40408a09G6O1WOH1W29X0108IO0I0620011a089O0080Oa04G0OY60620a04a0Oa08000G1Xe8a0GGOXYP1001cM2K200YGa2000KPf29060020064060O81WGGG2OY0111AO98G9M9W201G0O20O60W201658G48I9W4K00YWab0009WO00462OY00G4W0b12G81002OOX4G18Y2OG40M0YPW800aI00246842GIO08K0OI90000I0eY5XH119W88GGac2004000OYOW1419G402OY914408W8OH8G28IG0Y4194YOIG0M00I6OY0WH00a0aW9W1116O800G1W209M0820OM0a600005XW9X0909W1W00002209L4O29WY01P4a80004cHOW080G00cac101G9W280O0G06PXWO68b2GG81XW0W0010aOG42I0W4040fWY0G0441YPWa619008OW1412OW910818WG8H8W20H9068040HWc0a0G8G29I24M04Y00008a90H0228W4411O0G8HY92006224044YO600I208K4aI04248c4WG1W6600G0620I69Y401400aXWW0012GW00X091192P8004194YO0WW8aP0G099WO1G4IO0Y02K1W0Y92G4909O0b0009W0c40X4Wb80060a00008G19I2O2I000KW8cb8G09G1W094080W9I19048I28244I0a2K884WGGX01462Oc1W2G9OG00I68cG0G2O04010ccO004104W82WG2422K0224A44WKa000948a0WK600YGcP010PW62060091XW000c9IG420cWG112O0O44YGWX0W04119Y8844G0c0O0cG2G0010a99W4000f8a00KO10W2PW8001Kbc8W0X8218G5e660G000O2M8G00I16QK800W64040XWYG0602P0O0O00601O0I8224244O4aW1WH9W28G602P0006PW9G0OI02I1YG000920O64G6GYOW140HWW200PW9WYOG10GOW60100cGb00a88000I262L41G86AO600HWa20460OYG0009WWOG1800bGQG9W00091802OM2GO99100688600M0aW0a1906G0aIO0201W0012MM80Wc9W0KG621Y0004W001Oa4YG8X00G02K2OGW420PXW0aYOb1408W1012O98004G28W24G94G0022G12G2PWbW2O0O0G0668400GW9WGOGc010048O0W2Ga06G2PW"}local aD="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-"local ak={}for b=1,64 do ak[aD:byte(b)]=b-1 end local function az(i)return(N[i]*N[i]+2)//3 end local function aP(i)return#aj[i]//az(i)end local function aU(g)local i=os.date("*t",g)return os.time({year=i.year,month=i.month,day=i.day,hour=12})//86400 end local function U()local g=os.time()if not g or g<1700000000 then return nil end return aU(g)end local aN={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}local aK={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}local aH={3,1,1,2,2,2,3}local function ap(O)return os.date("*t",O*86400+43200)end local function aq(O)local i=ap(O)return aN[i.wday].." "..aK[i.month].." "..i.day end local function ao(O)return aH[ap(O).wday]end local d=6 local H,G,n={},{},{}local L,K={},{}local a local C={}local e={}for b=1,13 do e[b]=0 end local Q={1,1,1}local x={}local o,P=1,false local l,r,al="menu",1,"menu"local u,W,Z=nil,nil,nil local function J(f)f=math.floor(f or 0)if f>=3600 then return string.format("%d:%02d:%02d",f//3600,f//60%60,f%60)end return string.format("%d:%02d",f//60,f%60)end local function Y(v)if v.kind=="d"then return"Daily, "..aq(v.num)end return I[v.diff].." #"..v.num end local function a3(X,p,w)local h=aP(p)if X=="d"then return(w*37+11)%h,w%8 end return(w-1)%h,(w*5+(w-1)//h)%8 end local function _(X,p,w)local am,g=a3(X,p,w)local V=az(p)local a6=aj[p]:sub(am*V+1,am*V+V)local ab={}for c=1,V do local s=ak[a6:byte(c)]or 0 ab[3*c-2],ab[3*c-1],ab[3*c]=s>>4,s>>2&3,s&3 end d=N[p]H,G,n,L,K={},{},{},{},{}for c=1,d do L[c],K[c]=0,0 end for m=0,d-1 do for j=0,d-1 do local T,S=m,j if g&4~=0 then T,S=S,T end if g&1~=0 then T=d-1-T end if g&2~=0 then S=d-1-S end local s,b=ab[T*d+S+1],m*d+j+1 H[b],G[b],n[b]=s==1,s==2,0 if s==2 then L[m+1],K[j+1]=L[m+1]+1,K[j+1]+1 end end end o=1 a={kind=X,diff=p,num=w,el=0,hints=0,done=false}x,P,u={},false,nil end local function a8()local s={}for b=1,d*d do s[b]=n[b]end return table.concat({a.kind,a.diff,a.num,a.el,a.hints,a.done and 1 or 0,o,table.concat(s)},",")end local function aA(f)local k={}for y in(f..","):gmatch("([^,]*),")do k[#k+1]=y end local p,w=tonumber(k[2]),tonumber(k[3])if(k[1]~="d"and k[1]~="b")or not p or p<1 or p>3 or not w then return end _(k[1],p,w)a.el,a.hints,a.done=tonumber(k[4])or 0,tonumber(k[5])or 0,k[6]=="1"local j=tonumber(k[7])or 0 if j>=1 and j<=d*d then o=j end local s=k[8]or""for b=1,d*d do local y=(s:byte(b)or 48)-48 if not H[b]and y>=0 and y<=2 then n[b]=y end end return true end local function z()if a then C[a.kind]=a8()end snail.save(table.concat({"TN1",table.concat(e,","),table.concat(Q,","),a and a.kind or"",C.d or"",C.b or""},";"))end local function a0()local f=snail.load()if type(f)~="string"or f:sub(1,4)~="TN1;"then return end local k={}for y in(f..";"):gmatch("([^;]*);")do k[#k+1]=y end local c=0 for y in(k[2]or""):gmatch("[^,]+")do c=c+1 if c<=13 then e[c]=tonumber(y)or 0 end end c=0 for y in(k[3]or""):gmatch("[^,]+")do c=c+1 if c<=3 then Q[c]=math.max(1,tonumber(y)or 1)end end if k[5]and k[5]~=""then C.d=k[5]end if k[6]and k[6]~=""then C.b=k[6]end local ad=k[4]if ad and C[ad]then local af,ag=pcall(aA,C[ad])if not(af and ag)then a=nil end end end local function aT(b)local m,j=(b-1)//d,(b-1)%d for as=-1,1 do for ar=-1,1 do local ah,ae=m+as,j+ar if(as~=0 or ar~=0)and ah>=0 and ah<d and ae>=0 and ae<d and n[ah*d+ae+1]==1 then return true end end end return false end local function aa(m,c)local h,f=0,c==1 and(m-1)*d+1 or m for a_=0,d-1 do if n[f+a_*c]==1 then h=h+1 end end return h end local function ai(b)return(n[b]==1 and not G[b])or(n[b]==2 and G[b])end local function a1()local h=0 for b=1,d*d do if ai(b)then h=h+1 end end return h end local function ba()local E,D=0,0 for b=1,d*d do if n[b]==1 then E=E+1 end if H[b]then D=D+1 end end return E,D end local function ay(b)x[#x+1]=b*4+n[b]if#x>150 then table.remove(x,1)end end local function au()for b=1,d*d do if(n[b]==1)~=G[b]then return end end a.done,P=true,false local q=(a.diff-1)*3 e[q+1]=e[q+1]+1 if e[q+2]==0 or a.el<e[q+2]then e[q+2]=math.max(1,a.el)end e[q+3]=e[q+3]+a.el if a.kind=="d"and e[13]~=a.num then e[10]=e[10]+1 e[11]=e[13]==a.num-1 and e[11]+1 or 1 if e[11]>e[12]then e[12]=e[11]end e[13]=a.num end end local function aY()for c=0,d*d-1 do local b=(o-1+c)%(d*d)+1 if ai(b)or(G[b]and n[b]~=1)then ay(b)n[b]=G[b]and 1 or 0 o=b a.hints=a.hints+1 u=G[b]and"Hint: a tent goes here"or"Hint: no tent here"au()return end end end local function ac()local i=U()if i and e[13]<i-1 then return 0 end return e[11]end local function B()l,Z,r="play",os.time(),1 end local function aB(p)if a then z()end local h=Q[p]Q[p]=h+1 _("b",p,h)B()z()end local function a9(i)if a then z()end a=nil if C.d then local af,ag=pcall(aA,C.d)if not(af and ag)or a.num~=i then a=nil end end if not a then _("d",ao(i),i)end B()z()end local function aS()local aw=os.time()if a and l=="play"and Z and not a.done then local at=aw-Z if at>0 then a.el=a.el+math.min(at,600)end end Z=aw end local function a7(i)return N[i].."x"..N[i]end local function av()local g={}if a and not a.done then g[#g+1]={"Continue: "..Y(a).." ("..J(a.el)..")","cont"}end local i=U()if i then local f="Daily puzzle: "..aq(i)..", "..I[ao(i)]if e[13]==i then f=f.." (solved)"end g[#g+1]={f,"daily"}else g[#g+1]={"Daily puzzle: needs the clock","noclock"}end for c=1,3 do g[#g+1]={"New "..I[c].." "..a7(c).." puzzle (#"..Q[c]..")",c}end g[#g+1]={"Statistics","stats"}g[#g+1]={"How to play","help"}return g end local function ax()return{{"Back to the puzzle","cont"},{#x>0 and("Undo ("..#x..(#x==1 and" move)"or" moves)"))or"Undo (nothing to undo)","undo"},{"Check for mistakes","check"},{"Hint: fix a square","hint"},{"Grass on all empty squares of full rows","grass"},{"Restart this puzzle","restart"},{"Main menu","menu"},{"How to play","help"},}end local function aX()local v={}for b=1,d*d do local m,j=(b-1)//d+1,(b-1)%d+1 if n[b]==0 and not H[b]and(aa(m,1)==L[m]or aa(j,d)==K[j])then v[#v+1]=b*4 end end for aO,A in ipairs(v)do n[A//4]=2 end if#v>0 then x[#x+1]=v end return#v end local function aR(t)if t=="cont"then B()elseif t=="undo"then local A=table.remove(x)if A then if type(A)~="table"then A={A}end for c=#A,1,-1 do n[A[c]//4]=A[c]%4 end o=A[1]//4 B()z()else u="Nothing to undo"end elseif t=="check"then B()local h=a1()P=h>0 u=h==0 and"No mistakes so far"or(h==1 and"1 mistake, marked"or h.." mistakes, marked")elseif t=="hint"then B()if not a.done then aY();z()end elseif t=="grass"then B()local h=aX()u=h==0 and"No open squares in full lines"or("Grass on "..h..(h==1 and" square"or" squares"))z()elseif t=="restart"then _(a.kind,a.diff,a.num)B()z()elseif t=="menu"then l,r="menu",1 elseif t=="daily"then a9(U())elseif type(t)=="number"then if a and a.kind=="b"and not a.done and W~=t then W,u=t,"Press OK again to leave "..Y(a)else W=nil aB(t)end else al,l=l,t end end local function a2(c)local m,j=(o-1)//d,(o-1)%d if c=="up"then m=(m+d-1)%d elseif c=="down"then m=(m+1)%d elseif c=="left"then j=(j+d-1)%d elseif c=="right"then j=(j+1)%d end o=m*d+j+1 end local function a4(c)if a.done then if c=="top"then l,r="menu",1 elseif c=="ok"then if a.kind=="b"then aB(a.diff)else l,r="menu",1 end end return end if c=="top"then l,r="opts",1 z()elseif c=="ok"then if H[o]then u="That's a tree"return end ay(o)n[o]=(n[o]+1)%3 au()z()else a2(c)end end function key(c)aS()u,P=nil,false if l=="play"and a then a4(c)return end if l=="menu"or l=="opts"then local F=l=="menu"and av()or ax()if c~="ok"then W=nil end if c=="up"then r=(r-2)%#F+1 elseif c=="down"then r=r%#F+1 elseif c=="ok"then aR(F[math.min(r,#F)][2])elseif c=="top"and l=="opts"then l,r="menu",1 end return end if c=="top"or c=="ok"then l=al end end local function an(M,E,D)return aC(M+(E<D and aF or E==D and aJ or aL)+math.min(D,7))end local function aQ()local M=aM[a.diff]local a5=a.done local R={}for m=0,d-1 do local g={}for j=1,d do local b=m*d+j local f=n[b]local s=H[b]and 3 or(f==1 and(aT(b)and 4 or 1))or f if P and ai(b)then g[j]="@"else g[j]=aC(M+s+((b==o and not a5)and aG or 0))end end g[d+1]=an(M,aa(m+1,1),L[m+1])R[#R+1]=table.concat(g)end local g={}for j=1,d do g[j]=an(M,aa(j,d),K[j])end R[#R+1]=table.concat(g).."."return table.concat(R,"/")end local function aV()snail.title("Tents - "..Y(a))local f if a.done then local q=(a.diff-1)*3 f="Solved! Best "..I[a.diff].." time "..J(e[q+2])if a.hints>0 then f=f..", "..a.hints..(a.hints==1 and" hint"or" hints")end elseif u then f=u else local E,D=ba()f=J(a.el).."  Tents "..E.." of "..D end snail.status(f:sub(1,47))snail.board(aQ(),nil,a.done and("Solved in "..J(a.el))or nil)if a.done then local q=(a.diff-1)*3 snail.text(I[a.diff].." puzzles solved: "..e[q+1])if a.kind=="d"then snail.text("Daily streak: "..ac()..(ac()==1 and" day"or" days"))end snail.hint(a.kind=="b"and"BACK puzzles OK next puzzle"or"BACK puzzles OK puzzles")else local bb=H[o]and"tree"or({"tent","grass","clear"})[n[o]+1]snail.hint("BACK options OK "..bb.." L/R move UP/DN move")end end local function aW()snail.title("Tents statistics")for c=1,3 do local q=(c-1)*3 local h=e[q+1]if h>0 then snail.text(I[c]..": "..h.." solved, best "..J(e[q+2])..", average "..J(e[q+3]/h))else snail.text(I[c]..": none solved yet")end end snail.gap()snail.text("Daily puzzles solved: "..e[10])snail.text("Daily streak "..ac()..", best "..e[12])snail.hint("BACK back OK back")end local aI={"Every tree needs its own tent right next to it: above, below, left or right.","Tents never touch each other, not even corner to corner.","Numbers say how many tents go in each row and column: hollow once met, boxed if over.","Arrows move. OK cycles a square: tent, grass (no tent here), empty.","Tents that touch another tent are marked. BACK opens options: undo, check and a hint.","Options can also fill grass in every row and column that has all its tents.",}function draw()if l=="play"and a then aV()return end if l=="stats"then aW()return end if l=="help"then snail.title("How to play")for aO,f in ipairs(aI)do snail.text(f)end snail.hint("BACK back OK back")return end if l=="noclock"then snail.title("Daily puzzle")snail.text("The daily puzzle needs the date. Connect to Wi-Fi once so the clock gets set, then come back.")snail.text("The Easy, Medium and Hard puzzles work any time.")snail.hint("BACK back OK back")return end local F=l=="menu"and av()or ax()if r>#F then r=#F end snail.title(l=="menu"and"Tents"or("Tents - "..Y(a)))if u then snail.status(u)end for b,aZ in ipairs(F)do snail.row(aZ[1],b==r)end snail.gap()if l=="menu"then local h=e[1]+e[4]+e[7]snail.small("Daily streak "..ac()..", "..h..(h==1 and" puzzle"or" puzzles").." solved.")snail.hint("BACK leave OK choose UP/DN move")else snail.small("Time "..J(a.el)..(a.hints>0 and(", hints "..a.hints)or""))snail.hint("BACK puzzles OK choose UP/DN move")end end function start()snail.ink("fast")a0()if a and not a.done and not(a.kind=="d"and U()and a.num~=U())then B()else l,r="menu",1 end end
