--!name Star Battle
--!icon puzzle
--!category Puzzles
local aJ="!$%&()+,-0123456789:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnpqrstuvwxyz|~"local function aj(b)return aJ:sub(b+1,b+1)end local aS,aN,aL,aQ,aI,aK=5,10,15,30,33,36 local K={6,8,10}local an={1,1,2}local aR={0,37,0}local H={"Easy","Medium","Hard"}local al={"4441224444434454227448226688926B888822201023200422224588674498A64488B64422666136666686566688467A89AA6A888BAA222221324444288548A78888AAAA9AAABAAA422221422322456662466672889822B882220000104438005888004888874988AA888BAA64410264442364588876A888A6A898ABA8882200012230002224507A22446A8944AB8888012222000232522222447662446689666BAA0010003000002224546764446444A9664BAA1066664466364456664448874889884B88886104446000436045447644486AA89866BAAA222144234444226645827644922A44822AB442222148322258222248272A898AAA88AABA441002440032458822A44827A44988B44488444010340000845006884007890000800B00012224022324222245667444668894B8888844221644322654666648666789A66688AB6600102200023205662284676298662288662B44122244443254462246676649868688888B2220102320062225662A8867AA9866BAA8660001440304480AAA580A76680AA689BA888812222266622366652267644A66A89AAABAAA10022202322266245867244866298866688B422001442300852200888270889866B888861222224444324454664A8667AA8986AB8666001A2200AA2354AA22AAAA72A9AAA288ABAA14444404444388566288AA76898AA6888BAA441022466632456228446768444889B48888012222400232506882667A88AAAA89AAAB88010000000003005422844672948666888B6622100032244466685467688466698488888B10222222344222645467664466A94A6AAAAB6601226642236458227AA882AAA89AABAAAA66610264400364544476A444A6A898ABA888440001443A0054AA0044A67089AA668AAB661044224444234445284748886688986AB888422001442320454000444676AA9866B6666601422284444384544684447694AA66888BA6466201466322546682447682AAAA98ABAA880010220022230065427664826A44986B8888222010320000244504276444666A49AABA8844410044002354668866766866A898ABA888220100630448626658667448668889BA888841022244443254646644676644A68944B8882222102232002222257644446AA9886B88884412224402326566286667886AA889BAA8881422220422324546664AA76644AA69AABAAA014442044443644544788A4A689AAA68AABA810422804443885466886676988A66888BAA1022880022380526880427880AA689AAB6880010003204042225442224472922A688AABA00144430044420045467A44466A88966AB8800122240623650666648A66789A66688AB662222012322402226506676409AA64488ABAA88410288442385442286667298666688BAAA","0010000200000032500060000000700000000809AB00C888AAAACDE8AAAFEEE80122222266222232666522227A668222AAA89222AABAA2E2AAAAADEEAAAAEEEF666AAA10366AAA44666AAAA5676AAAAA6669AAAA6888ABAA88DEEEAA88EEFEAA22241444234444442224454422244447A2298666B22CC666AA2CC6D6AAFCCCCC0100022400623224006662540076622498866224888B2224888AAD2E88888EEF220000102232000052260600A6667600A6600009AB60E000AAADE000AAAAEF000100004400034444044445847CC844846CC89884CCCCC88BCCDCC8EECCCCCCFE444466613446666622456666C2466766CC966666CC88B666CDCCCC6ECCCCCCFE01044422000443220445422204444476944444EE8884BEEE88DAAAEE8888888F22444100344444404445444044444847AAA49888AAB4488CAAA488DCAFACCCCC444610004466E0305EE6EEEEEEE7EEECEEEEE9ECEEBEECCCEEEECCCDEFEEECCC22222001223222025CC82222CC886762CCC9C666CC88C6B6CDCCCEEECCCCFEEE00100000000223880506622800072288AA00CC89BA0EC888A00ECCD8A00EFCC8662222416622324466224454667A444498AAC444AAABC4CCAAAACDCCAFAACCCC4442200144423202454222024447222244AA2892BAAC8888AADCCE88AAACCF882222222122322424622254447A2AC444AAAACC94ABAACCEEAACDCCEEAACCCFEE10000CCC00032CCCA52266CCAA2276CCAAA2669CAABEECCCAAAAECCDAAAEEFCC1444222244423622454446624A4466674AAAA98644ABA8C64AAAA8D644FAAACC222222102232222052E66226EEEE6766EEEEE669CCEEB688CDEEEEEECCEFEEEE2221000023204000222056068828467688988666B88886CC888888CD88888FEC000001000223000066622205782222CC68922CCC8822BCCC8822CCDCEFE22CCC442222214442232245422666C4428676CC988666CCEEB666DEEEE666CCEFE6668001066683044466888856668888AEE798AAAEEE8CAAABEECCDAAAEECCAAAEFE0166662206662322C6622225C676222ACC6698AACC66E8BADE66EEEACEEFEEEA22244441384444448866454488676664C98AAAAACCCCCCBACCDCCCCACCCCFAAAAAAA1222AAA0023CAAA5422CA866676CA89866CCB8686CCCAA666CCDEF666CCC666440016664430066454888744888886A489888AB888888AAA888D8AEF8888801000000000004230005446200C886720CCC9888BCCCCEE8CCDCCCEECCCCCFEE888122228884222388845AA278444AAAC898AAAACCEEEEBECDEEEEEECCCEEFEE22221666322666662256666A888667AA89866AAE888CCABE88CDAAEE88CEEEEF6666616636666066AA566666A4466676A4498CC6ABAAACC6ACCADC66AACCCCCF100446668032446680885666888866768889E666AB88E666AAAEEE6DAAEEEFEEA6222214A6623244AA624445AA6744449AAA4444AABCCCCCEEECCDCCEFEECCCC4444001034440000445400004444676844CEE669CCCEB888CDCE8888CCEF8888222222212232884462288544678884446689ECCCB68EECCCEEEECCDCEEEEFECC2222001022223200245466604484676698846C6688AB6CCC8AA6666D8FAACCCC44441000444400034500000C444887CC4449AAACC888AABCCCDCAAACFECCCCCC22001044223000042224450466674444A6666CC9B666CCC8AAACCCDCAFCCCCCC6601000066602320A6602885AA788888AAA8CC98BAAACCCCAAAADCCCAFEECCCC4444200144462320854666CC8847CCCC9AAAAACC8ABAAACCAAACDCCCAACCCCFC6664400166644300666548887A684888AA689888AB6EECCCAA6EECDCAAFEECCC222201043220044462226445666764446966444488CC44B48CD44444CCCEF4446222144466320444622C45887CCC4A8866CCAA98C6CBAA88CDCAAAA8CCCAAAAF222010442230200422222054222760449226644488666BA488866CCDEFCCCCCC0100024488003224880224548872AA449A6AAAA48AABAAA48AAAAACD88AAAFCC10244444223444446266454467666CC46689CCCA6668CCEBEEEEDEEEEEEEEEFE222201002322000022225400822444769224444C88ABA44C8AAAAA4D88FCCCCC0010000000000063456666668868AA768869AAA6C888ABA6D888EAA6CC88FAAA22226610223226662222566622844867AA888966EBA88666EAADE666FEEEE666882222218832220088A2245488A27C449AAA6CCCEEEBAACCEEEEEDCCEFEEEECC1022664422326444288664548866766489888888888BA8888AAAADEEAAAEEEEF44100066444003665444446644444667498AAAA64AABCC664AAAECD6AAAAFECC4441022244440636AA546666AAA44867AA449866ABAA886CAAAA8DCCFCCCCCCC44220010A4223000A5888866AA888887AAC9EE8EBACEEEEEACDEEEEECCEEEFEE0100044240000432544444224476888A44469EAA444C8EEB444DCCEACCCCCFEE001888880888888308658882676488886C448898CCCABE88DAAAEE88CCCAEFEE","888C44544188DCD44440988CC45440888GH4441098JIGGE00E82IIIHEFEE83IIIEEAAF2227IAABAA2326IJAAAA2227IAAABA0EEEFAAA761EEEEABA6600EFAAAA76010EEBIA66000JIIIH66CD0IIIIG23CCCICJIH22CCDCCIGG2344CC989GG2545448GGG2A666676663B6676II662AA666EIJI3BAF6EEGIIIAEEEEHGJIIA10FEGGIII000GGGDCDC4144HG88C840444498984454548888AA23GHG888A222GGGD89A223GHCCC8AJI2IGCCC9AIIIJ4CDC4BAFI444444AEEI445454BEF4404400A666001410A766700000AAEFEEEE54ABEEE01448AAAEF00458AABEEE1448AAIIJI0GG97AIIIIIH88666JGHGG8867GGGGGGG966GGCDGD88323CCCCCC8CCCCGGG323D0CDGGGG22000CGHGG72010HGGG6660000IIJI7A8188JIAA6A888888BAAB88989EEEEE54444EEFEE445EEFEEEE3IIIIIIIAB2276IEEBAA3266IJEEAAGGG7IIEEEFGHG88IEF44CGGH8JI444CDCC884454CCCC989444CCD0000050CCC01010001445444AAA00G4G5AABA1GHGGGAAAACCGGHABEE6CCDCIIAEE7CCIIJIIFE68DIIIIIEE7888I2JEFE2898922EEE28882223232ABAII22232AAAFIJ2222BEEEEI2227EEEFII2326EEE0IJG22700108GGH2250089GGG224018GGHCCC44889CCCDC4588CCDCCC223267AAAA322666AABA22IJ67AAAA2HGII6ABAAGGGGJ6AAEFGGHGIAAFE4GGGGDAA005GDCCCC1044GC8900045498800014442367EEEAAA2266EEFEAB366766EAAAII666FE1AAIJIIII00ABGGGGGJI1AAHGH88888AAGGC898885ACGDCC8984ACCCCD8885A9CCD40000088CC4500109CD444440ECCC445410ECJCI44E0EFIIIIJIFEEEII3GGEEE7E222GHABA66232GAAAAA7222HGAAB66CCDC898004CC88888105CDGG9G0044CCGGGG10546GHGHG0E447GIIGIIEFE666JIIFEEE7IIIIIEAEB6623IIIBAA632IIJIIAA454489888C04458888DC14I4I98CCC04IJI8CDCC10I888GCCHIIJIEGHGGGEEEEFG6G3GEFAAAG7622EEAAB66663AABAAA6766AABEE22232BAAAE32222AIIFEE2227IIIIIF2HG6IJIIIGGGG70I0IJIGH88101ICCGG884400DCD8884540C888984445449888666GGHGDCC3667GCCCCC2266GGCDC9327GGGC888AA6IHG1888AIJIIG0009AAAAJI1888ABAIIIE454AAAFEFEE44ABAAEEEE54EEEEF44445BEEEEI5404AAEFIII4016BAEII010066IJIJI00067IIGII090666GHIDC88663GGGC89C762GGHCCCC223GGGGDCCEEFEFEEEE0BAAEEE01002ABEE004052IIIJ014442JI6000GG52II66HGHGC276768CGCC222668DCDC32236888CC22226988982GGH666676232GGI7E66222HIIEE6B23CCIJEEEACCCCIIIFEBCCD4JI44EEDC44II44FE888454544498944004008884410100223IIJEEEE32AAAIEEFE222BIIJEEEC72AGGGEF4C66BAH0E04C766GG0104CCCGH88045CCDCC80144DC88C88045CCC89890007666EEE232667EFEEG22B666EEEGG3A6EFEEHG22ABAEI88GH800AIJ8988800JII88889000CCDCD880101CC4C880000454588FIIII88944EEIIJ88445EFIII89444AAAJI08845AAII010104ABABA0G044AAAAA0HCDC2A32HGGCCC3226GGCCDC267667CCCC23666676AA22267666BA232666BAAA222J66EEEFCGGIIJIFEEDGHIII4444CCGGI54454D88H0040008888004101889890000094444544448445444I14988444JI0088DGGIIII18CCCHIEJAA88DGGEEEAB22GGFEFEEA232GEEE6BA222H67E6AA23GG6667AA3EEEEEFEEE22676EEAAB36666EEB442IJI76EE44IIIGG6FE54IIJGH88E44IIIG880105IDGG890000CCCH888010CD888900008889844445898445404088888G41018DCDGGG000226CGHGHG03676IIGGGG2226JIAABG3266IIJAAAEE7EEIEEBEEEEEFEFEEEEEE8989844EF888884452EEEFE8544323III4444622IIJG4D4676JGIGCCC666GGGHCDC7AABGGGCCC66AAGHGCC166BGGG010036666HGGGG2676666GDG366676GGCC2666888H0D266JI98800EFEIII4980EEEJII4081AFAAII5000AAAAB44410AABAA45444676GGG010066676HGG00B6E6EG4441AAFEFG4444BAAIGGC544AIIIIHCCC5IJIJICCC44III22CDCD8II323228C8II22889898BAAEE67222AEFE766222BAAEIII2234EAEJII3I24EFEIIIIIH4EIIIJIHGG45410CGGGG44000DGC984541CCCCC84440CCDC98ABABA66622AAEAA76663AFEFE66662AAIEI67632AAJIJGGGG2000IIGHGHG101IGGGGGG0000GDCDC8504444CC894444548988CCCDCC00109CCCCC50008CCDC4401089GCC54400GGGCI4IFEFGGHGJIIIEEHG2IIIJIIE2G3ABAIIEE222AAAI767232AABA666CDCC622232CC67667222DGGGG6223ACGGHGHGGAACGGGGIIJABC9GIIJIEEA8888IIIFAB88981EEEEA544000FEAA445010EEAA32366AAAA426666BAAB427G7666AA4GGG66FEF44GGHGIEIE45GGGGJIIJI4CHCCCII005CCCDC81000DCCCC88010CCCC989880766AAAAAA166BABAAA0076AIIEA010666IFEF00066JIIIE4452IIIIJE54423IHGCCC4422IGGD8DCC23IH8888CC222888989CAAAEEE3236ABAEFEE266AAAAAEF667ABAJAAE666IIIIIAEH674IJI1AGGG654II0CCHGG449I01CGCG54880CCGDG44890DCCCCCDGG444454CGGH45I400DGIIIII481GGGIIJI98022HGII8881222GJE898832366EEEE826667EFE8867A6AAEEFE66ABAABEEE2222IEFABA2322JIEAAA22222IFEEB32766II44A22C6GJIG5A2DC7GIGG44CC66GHG104CCCHG8G045DCC8888100CC989000008888898454D889800444CG88001054CGHIJ00044CCGII0104BDCHIIIAAAA22GIJIAAAB23226EEFAA226767EEAA232266EFAA3666ABAAAA2667AAAAAF2366ABEEEE226766E10E2JII6EE8012ICIFEI988DIDIIII888CCCCGGJ898CCHCHG4484CCGGG454548888CCDCC389898CC222488IIDGG23544IIIGHGG4IJIJEGGGG54EIEEGGHGEEFEFEGGGG00E0E6BABG0101E666AA0000E767AA4444498CDC545888888C4000988CCD4F088I8HGCEE010JIGGGEE000IIH67EFE1III666EA22I2J276BAB2I2I266AA223232262322322A662222AABAA722HGBAAAA6GGGGGAAFE7GHGDEEEE66GGCCCJEF669G4DIIEEE08444IIJI109854I4II008844450010AAAE544010ABAE445400AAAFEE401GABAEIJ4GGGAAAFIGGHG8A6AEIHG8897676IIGG886666IIID896232JIICCC32222IDCCCAB00004445AA0E10144CABEE00445CEEEFIJ888CF2EIIG89CCE22JIHG8CC2222GG898D2236HG88CC32666688D6267666766605444DCCC800454GCDC8044GGHGIC910100GIII800EGHGGII9FEEEEIIJ22EABAFI6222AAAAII7232ABAJII6622AAAAA672329CCCCCCCC388CCDCDCC2988GGCCC32EGHGGHC226EEGGGGI767EFE10GII66EEE00JIJI6EFE104AAAAE44444BABAEE545AAAAA898CCCCC3288CDCDC2229CCCCCC23288HGCCJII288GGHEIII7450GEEJA66400EFEIAA74010EAABA650EEEFEAA640010EAB66CCCC988454CDCC885444CCC898I441CCD8I8JI00HCCCIII001GGGHIIIFEE67666JIIEE666766AAFE36222BAAAE223222ABAE888545E0009884E4EE108888FEF000G98EEEEE10G88DCJEEAAGDCCGIIBAAGCGGHIIA6BGGHG66J66A3GGGG6II6722326667668944540000888C4450019C8D4GG0008CCCGGHG1A8JIDGGGG0AIIIGGHABAAIIJEEGGAABII22EF67AA3I3EEEE66A222EF6667A1044444ABA0454II5AAA1444IIIA6B08IJIJIE6609888IEF66888D8FE666898CGG676688CCH666678CDGGG32268GGGHG223244401AABAA445000066B54GG16666644GGEEF676IJIHEE6666IIGGGFE267IIHIIE23229IIIIJ22228ICDCC2232898CCCDCC28880101044988C0GG0548CDCHG00449CCCCG54448CDICGIIIFCCCIIHIJIEIIIJIIIIIF23I6666BEE266767AAEA2366666ABA00000A76761001AAAAA60004ABAEB20545AGAEE244G4GGAF234HGGGHEEE2GGGGGGEFE3G89IJIII2298888IJ2228CDCDCCC22223CCCCC98222CDCD8886632CCC8987EE2JCCC886EEIIIGHG17EEIIJGG0066EFE4GHG0ABAE454GG0AAEF444GG1ABA4445GG0"}local aH="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-"local am={}for b=1,64 do am[aH:byte(b)]=b-1 end local function aC(h)return K[h]*K[h]end local function aW(h)return#al[h]//aC(h)end local function a_(e)local h=os.date("*t",e)return os.time({year=h.year,month=h.month,day=h.day,hour=12})//86400 end local function S()local e=os.time()if not e or e<1700000000 then return nil end return a_(e)end local aT={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}local aP={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}local aM={3,1,1,2,2,2,3}local function as(L)return os.date("*t",L*86400+43200)end local function at(L)local h=as(L)return aT[h.wday].." "..aP[h.month].." "..h.day end local function ar(L)return aM[as(L).wday]end local c,E=6,1 local u,G,l,ae={},{},{},{}local a local C={}local g={}for b=1,13 do g[b]=0 end local O={1,1,1}local x={}local s,M=1,false local m,r,ao="menu",1,"menu"local v,T,W=nil,nil,nil local function I(i)i=math.floor(i or 0)if i>=3600 then return string.format("%d:%02d:%02d",i//3600,i//60%60,i%60)end return string.format("%d:%02d",i//60,i%60)end local function V(q)if q.kind=="d"then return"Daily, "..at(q.num)end return H[q.diff].." #"..q.num end local function a9(U,o,w)local f=aW(o)if U=="d"then return(w*37+11)%f,w%8 end return(w-1)%f,(w*5+(w-1)//f)%8 end local function Y(U,o,w)local ap,e=a9(U,o,w)local _=aC(o)local bc=al[o]:sub(ap*_+1,ap*_+_)c,E=K[o],an[o]u,G,l,ae={},{},{},{}for n=0,c-1 do for j=0,c-1 do local R,Q=n,j if e&4~=0 then R,Q=Q,R end if e&1~=0 then R=c-1-R end if e&2~=0 then Q=c-1-Q end local D,b=am[bc:byte(R*c+Q+1)]or 0,n*c+j+1 u[b],G[b],l[b]=D>>1,D&1==1,0 end end for b=1,c*c do local n,j=(b-1)//c,(b-1)%c local bf=n==0 or u[b]~=u[b-c]local a4=j==0 or u[b]~=u[b-1]local ad=(bf and 1 or 0)+(a4 and 2 or 0)if ad==0 and(u[b-c]~=u[b-c-1]or u[b-1]~=u[b-c-1])then ad=4 end ae[b]=ad end s=1 a={kind=U,diff=o,num=w,el=0,hints=0,done=false}x,M,v={},false,nil end local function bd()local D={}for b=1,c*c do D[b]=l[b]end return table.concat({a.kind,a.diff,a.num,a.el,a.hints,a.done and 1 or 0,s,table.concat(D)},",")end local function aE(i)local k={}for y in(i..","):gmatch("([^,]*),")do k[#k+1]=y end local o,w=tonumber(k[2]),tonumber(k[3])if(k[1]~="d"and k[1]~="b")or not o or o<1 or o>3 or not w then return end Y(k[1],o,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<=c*c then s=j end local D=k[8]or""for b=1,c*c do local y=(D:byte(b)or 48)-48 if y>=0 and y<=2 then l[b]=y end end return true end local function z()if a then C[a.kind]=bd()end snail.save(table.concat({"SB1",table.concat(g,","),table.concat(O,","),a and a.kind or"",C.d or"",C.b or""},";"))end local function a6()local i=snail.load()if type(i)~="string"or i:sub(1,4)~="SB1;"then return end local k={}for y in(i..";"):gmatch("([^;]*);")do k[#k+1]=y end local d=0 for y in(k[2]or""):gmatch("[^,]+")do d=d+1 if d<=13 then g[d]=tonumber(y)or 0 end end d=0 for y in(k[3]or""):gmatch("[^,]+")do d=d+1 if d<=3 then O[d]=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 ab=k[4]if ab and C[ab]then local ag,ah=pcall(aE,C[ab])if not(ag and ah)then a=nil end end end local function aF(b)local n,j,e=(b-1)//c,(b-1)%c,{}for av=-1,1 do for au=-1,1 do local ai,ac=n+av,j+au if(av~=0 or au~=0)and ai>=0 and ai<c and ac>=0 and ac<c then e[#e+1]=ai*c+ac+1 end end end return e end local function X(n,d)local f,i=0,d==1 and(n-1)*c+1 or n for N=0,c-1 do if l[i+N*d]==1 then f=f+1 end end return f end local function aD()local e={}for q=0,c-1 do e[q]=0 end for b=1,c*c do if l[b]==1 then e[u[b]]=e[u[b]]+1 end end return e end local function bg()for b=1,c*c do if l[b]==1 then for aa,N in ipairs(aF(b))do if l[N]==1 then return"Two stars touch"end end end end local e=aD()for q=0,c-1 do if e[q]>E then return"A region has too many stars"end end end local function ak(b)return(l[b]==1 and not G[b])or(l[b]==2 and G[b])end local function a7()local f=0 for b=1,c*c do if ak(b)then f=f+1 end end return f end local function aB(b)x[#x+1]=b*4+l[b]if#x>150 then table.remove(x,1)end end local function ax()for b=1,c*c do if(l[b]==1)~=G[b]then return end end a.done,M=true,false local p=(a.diff-1)*3 g[p+1]=g[p+1]+1 if g[p+2]==0 or a.el<g[p+2]then g[p+2]=math.max(1,a.el)end g[p+3]=g[p+3]+a.el if a.kind=="d"and g[13]~=a.num then g[10]=g[10]+1 g[11]=g[13]==a.num-1 and g[11]+1 or 1 if g[11]>g[12]then g[12]=g[11]end g[13]=a.num end end local function a2()for d=0,c*c-1 do local b=(s-1+d)%(c*c)+1 if ak(b)or(G[b]and l[b]~=1)then aB(b)l[b]=G[b]and 1 or 0 s=b a.hints=a.hints+1 v=G[b]and"Hint: a star goes here"or"Hint: no star here"ax()return end end end local function aV()local e=aD()local q={}for b=1,c*c do if l[b]==0 then local n,j=(b-1)//c+1,(b-1)%c+1 local af=e[u[b]]>=E or X(n,1)>=E or X(j,c)>=E if not af then for aa,N in ipairs(aF(b))do if l[N]==1 then af=true end end end if af then q[#q+1]=b*4 end end end for aa,A in ipairs(q)do l[A//4]=2 end if#q>0 then x[#x+1]=q end return#q end local function Z()local h=S()if h and g[13]<h-1 then return 0 end return g[11]end local function B()m,W,r="play",os.time(),1 end local function aG(o)if a then z()end local f=O[o]O[o]=f+1 Y("b",o,f)B()z()end local function be(h)if a then z()end a=nil if C.d then local ag,ah=pcall(aE,C.d)if not(ag and ah)or a.num~=h then a=nil end end if not a then Y("d",ar(h),h)end B()z()end local function aZ()local az=os.time()if a and m=="play"and W and not a.done then local aw=az-W if aw>0 then a.el=a.el+math.min(aw,600)end end W=az end local function a5(h)return H[h].." "..K[h].."x"..K[h]..(an[h]==1 and", 1 star"or", 2 stars")end local function ay()local e={}if a and not a.done then e[#e+1]={"Continue: "..V(a).." ("..I(a.el)..")","cont"}end local h=S()if h then local i="Daily puzzle: "..at(h)..", "..H[ar(h)]if g[13]==h then i=i.." (solved)"end e[#e+1]={i,"daily"}else e[#e+1]={"Daily puzzle: needs the clock","noclock"}end for d=1,3 do e[#e+1]={"New "..a5(d).." (#"..O[d]..")",d}end e[#e+1]={"Statistics","stats"}e[#e+1]={"How to play","help"}return e end local function aA()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"},{"Dot squares that can't hold a star","dots"},{"Restart this puzzle","restart"},{"Main menu","menu"},{"How to play","help"},}end local function aY(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 d=#A,1,-1 do l[A[d]//4]=A[d]%4 end s=A[1]//4 B()z()else v="Nothing to undo"end elseif t=="check"then B()local f=a7()M=f>0 v=f==0 and"No mistakes so far"or(f==1 and"1 mistake, marked"or f.." mistakes, marked")elseif t=="hint"then B()if not a.done then a2();z()end elseif t=="dots"then B()local f=aV()v=f==0 and"Nothing to dot"or("Dotted "..f..(f==1 and" square"or" squares"))z()elseif t=="restart"then Y(a.kind,a.diff,a.num)B()z()elseif t=="menu"then m,r="menu",1 elseif t=="daily"then be(S())elseif type(t)=="number"then if a and a.kind=="b"and not a.done and T~=t then T,v=t,"Press OK again to leave "..V(a)else T=nil aG(t)end else ao,m=m,t end end local function a8(d)local n,j=(s-1)//c,(s-1)%c if d=="up"then n=(n+c-1)%c elseif d=="down"then n=(n+1)%c elseif d=="left"then j=(j+c-1)%c elseif d=="right"then j=(j+1)%c end s=n*c+j+1 end local function ba(d)if a.done then if d=="top"then m,r="menu",1 elseif d=="ok"then if a.kind=="b"then aG(a.diff)else m,r="menu",1 end end return end if d=="top"then m,r="opts",1 z()elseif d=="ok"then aB(s)l[s]=(l[s]+1)%3 ax()z()else a8(d)end end function key(d)aZ()v,M=nil,false if m=="play"and a then ba(d)return end if m=="menu"or m=="opts"then local F=m=="menu"and ay()or aA()if d~="ok"then T=nil end if d=="up"then r=(r-2)%#F+1 elseif d=="down"then r=r%#F+1 elseif d=="ok"then aY(F[math.min(r,#F)][2])elseif d=="top"and m=="opts"then m,r="menu",1 end return end if d=="top"or d=="ok"then m=ao end end local function aq(J,aU,f)return aj(J+aU+(f==E and 1 or f>E and 2 or 0))end local function aX()local J=aR[a.diff]local bb=a.done local P={}for n=0,c-1 do local e={}for j=1,c do local b=n*c+j if M and ak(b)then e[j]="@"else local D=l[b]==1 and aS or l[b]==2 and aN or 0 e[j]=aj(J+D+ae[b]+((b==s and not bb)and aL or 0))end end e[c+1]=aq(J,aQ,X(n+1,1))P[#P+1]=table.concat(e)end local e={}for j=1,c do e[j]=aq(J,aI,X(j,c))end e[c+1]=aj(J+aK)P[#P+1]=table.concat(e)return table.concat(P,"/")end local function a0()snail.title("Star Battle - "..V(a))local i if a.done then local p=(a.diff-1)*3 i="Solved! Best "..H[a.diff].." time "..I(g[p+2])if a.hints>0 then i=i..", "..a.hints..(a.hints==1 and" hint"or" hints")end elseif v then i=v else local f=0 for b=1,c*c do if l[b]==1 then f=f+1 end end i=I(a.el).."  "..(bg()or("Stars "..f.." of "..c*E))end snail.status(i:sub(1,47))snail.board(aX(),nil,a.done and("Solved in "..I(a.el))or nil)if a.done then local p=(a.diff-1)*3 snail.text(H[a.diff].." puzzles solved: "..g[p+1])if a.kind=="d"then snail.text("Daily streak: "..Z()..(Z()==1 and" day"or" days"))end snail.hint(a.kind=="b"and"BACK puzzles OK next puzzle"or"BACK puzzles OK puzzles")else local bh=({"star","dot","clear"})[l[s]+1]snail.hint("BACK options OK "..bh.." L/R move UP/DN move")end end local function a1()snail.title("Star Battle statistics")for d=1,3 do local p=(d-1)*3 local f=g[p+1]if f>0 then snail.text(H[d]..": "..f.." solved, best "..I(g[p+2])..", average "..I(g[p+3]/f))else snail.text(H[d]..": none solved yet")end end snail.gap()snail.text("Daily puzzles solved: "..g[10])snail.text("Daily streak "..Z()..", best "..g[12])snail.hint("BACK back OK back")end local aO={"Every row, column and outlined region needs one star (two on the Hard 10x10 grids).","Stars never touch each other, not even corner to corner.","Arrows move. OK cycles a square: star, dot (no star here), empty.","A tick at the edge means that row or column has its stars; a cross means too many.","BACK opens options: undo, check, a hint, and dots for squares that can't hold a star.",}function draw()if m=="play"and a then a0()return end if m=="stats"then a1()return end if m=="help"then snail.title("How to play")for aa,i in ipairs(aO)do snail.text(i)end snail.hint("BACK back OK back")return end if m=="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=m=="menu"and ay()or aA()if r>#F then r=#F end snail.title(m=="menu"and"Star Battle"or("Star Battle - "..V(a)))if v then snail.status(v)end for b,a3 in ipairs(F)do snail.row(a3[1],b==r)end snail.gap()if m=="menu"then local f=g[1]+g[4]+g[7]snail.small("Daily streak "..Z()..", "..f..(f==1 and" puzzle"or" puzzles").." solved.")snail.hint("BACK leave OK choose UP/DN move")else snail.small("Time "..I(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")a6()if a and not a.done and not(a.kind=="d"and S()and a.num~=S())then B()else m,r="menu",1 end end
