require"io/console" W=6 H=12 D=0.03 T=W*2+4 X=[0,1,0,-1] Y=[1,0,-1,0] class B attr_accessor:x,:y,:o,:c end def p(x,y,z) i=z.gsub(/\e\[[^m]+m/,"").length print y>0?"\e[#{x}C\e[#{y}B#{z}\e[0m\e[#{x+i}D\e[#{y}A":"\e[#{x}C#{z}\e[0m\e[#{x+i}D" end def m(t,c) ["\e[97;#{101+c}m","\e[#{91+c};40m","\e[#{31+c};107m"][t]+"<>(){}[]"[c*2,2] end $h=ARGV.length>1?ARGV[1,ARGV.length-1]*"":STDIN.isatty ? nil:STDIN.read def q(g,o,z) h=[] (H-1).downto(0){|y|h.push([]) W.times{|x|t=g[x][y] h[-1].push(t ? m(z[[x, y]]?2:0,t):nil)}} if o t=[[o.x,o.y,o.c[0]],[o.x+X[o.o],o.y+Y[o.o],o.c[1]]] t[0],t[1]=t[1],t[0]if t[0][1]>t[1][1] 2.times{|i|x=t[i][0] y=t[i][1] next if x<0 or x>=W h[H-y-1][x]=m(0,t[i][2])if y>=0 and y=0 and d=g.length or g[o.x][o.y] x1=o.x+X[o.o] y1=o.y+Y[o.o] (x1<0 or x1>=g.length or g[x1][y1])?1:nil end S=s=(ARGV.length>0? ARGV[0]:Time.now).to_i STDIN.echo=false print"\e[?25l#{(("#"*(W*2+20))+"\n")*(H+2)}\e[#{H+1}A\e[2C" p(T,0," Next: ") p(T,4," Block: ") p(T,7," Score: ") g=[] W.times{g.push([])} l=[] 6.times{ 4.times{|i| 4.times{|j| l.push([i, j])}}} 4.times{|i|l.push([i,i])} (l.length-1).downto 1 do |i| s^=s<<13 s&=0x7fffffff s^=s>>17 s^=s<<5 s&=0x7fffffff j=s% (i+1) l[i],l[j]=l[j],l[i] end f=[] u=e=0 h="" l.length.times{|a|2.times{|i|b=l[a+i+1] t=b ? ["\e[40m #{m(0,b[0])}\e[40m ","\e[40m #{m(0,b[1])}\e[40m "]:["####"]*2 p(T+i*4,1,t[1]) p(T+i*4,2,t[0])} p(T,5,"\e[97;40m #{a+1} / #{l.length} ") p(T,8,"\e[97;40m #{e} ") o=B.new o.x=(W-1)/2 o.y=H-1 o.o=0 o.c=l[a] break if w(o,g) while 1 print q(g,o,{}) c=nil while not c if$h break if$h.length<1 n=$h[0] $h=$h[1,$h.length-1] else n=STDIN.getch end c={'A'=>'k','k'=>'k','B'=>'j','j'=>'j','C'=>'l','l'=>'l','D'=>'h','h'=>'h','x'=>'q','q'=>'q'}[n] end case c when 'k' n=o.clone n.o=(n.o+1)%4 if w(n,g) if X[n.o]==0 n.y+=1 else n.x-=X[n.o] n=nil if w(n,g) end end if n h+=c o=n end when 'j' g[o.x][o.y]=o.c[0] g[o.x+X[o.o]][o.y+Y[o.o]]=o.c[1] h+=c break when 'h','l' n=o.clone n.x+=c=='h'?-1:1 if not w(n,g) if n.y!=H-1 d=n.clone d.y=H-1 n=d if not w(d,g) end h+=c o=n end else c=nil break end end break if not c e+=1 n=0 while 1 print q(g,nil,{}) while 1 r=[] v=nil g.length.times{|x|y=g[x].index(nil) if y r.push(g[x][0,y]+g[x][y+1,g[x].length-1]) v=1 else r.push(g[x]) end} break if not v g=r sleep D print q(g,nil,{}) end r=[] v={} g.length.times{|i|g[i].length.times{|j|c=g[i][j] t=[] z=[[i,j]] while z.length>0 x,y=z.pop next if x<0 or y<0 or x>=g.length or y>=g[x].length or v[[x,y]] or g[x][y]!=c v[[x,y]]=1 t.push([x,y]) z.push([x+1,y]) z.push([x-1,y]) z.push([x,y+1]) z.push([x,y-1]) end r.push(t)if t.length>3}} break if r.length<1 n+=1 p(T,H-1,"\e[97;40m #{n} chain ") v={} r.each{|t|t.each{|x|v[[x[0],x[1]]]=1}} x=q(g,nil,{}) y=q(g,nil,v) 10.times{ print x sleep D print y sleep D} x=0 y=0 z={} r.each{|t|z[g[t[0][0]][t[0][1]]]=1 x+=t.length y+=t.length>4? t.length>10?10:t.length-3:0} z=(n>1? 2*2**n:0)+[nil,0,3,6,12][z.keys.length]+y e+=10*x*[[1,z].max,999].min p(T,8,"\e[97;40m #{e} ") v.each_key{|t|g[t[0]][t[1]]=nil} u+=x end f.push(n) p(T,H-1,"\e[0m"+"#"*12)} if f.lengths[0]} x="rank = \e[4;1m#{x}\e[0m\n" y="\e[92mYOU WIN :)" end STDIN.echo=true print"\e[0m\n"*(H+2),"\e[?25h#{y}\e[0m\n\nscore = #{e}\nblocks = #{f.length} / #{l.length}\ntiles cleared = #{u}\n",x if f.length>0 and f.max>0 print"\nChain history:\n" y=f.max+2 y+=1 if y%2==1 until y==0 y-=2 x=0 until x>=f.length v=f[x,2].max print"8o_ "[v>y+1?0:v==y+1?1:y==0?2:3] x+=2 end print"\n" end v=f.index(f.max) print" "*(v/2),"^\n"," "*(v/2),"block #{v+1} = #{f.max} chain\n" end print"\nReplay:\nruby #{$0} #{S} #{h}\n"