1*eeb7e5b3SAdam Hornáček#! /usr/bin/ruby -Ku 2*eeb7e5b3SAdam Hornáček# -*- coding: utf-8 -*- 3*eeb7e5b3SAdam Hornáček 4*eeb7e5b3SAdam Hornáčekclass Board 5*eeb7e5b3SAdam Hornáček def clr 6*eeb7e5b3SAdam Hornáček print "\e[2J" 7*eeb7e5b3SAdam Hornáček end 8*eeb7e5b3SAdam Hornáček def pos(x,y) 9*eeb7e5b3SAdam Hornáček printf "\e[%d;%dH", y+1, x*2+1 10*eeb7e5b3SAdam Hornáček end 11*eeb7e5b3SAdam Hornáček def colorstr(id,s) 12*eeb7e5b3SAdam Hornáček printf "\e[%dm%s\e[0m", id, s 13*eeb7e5b3SAdam Hornáček end 14*eeb7e5b3SAdam Hornáček def put(x, y, col, str) 15*eeb7e5b3SAdam Hornáček pos(x,y); colorstr(43,str) 16*eeb7e5b3SAdam Hornáček pos(0,@hi); print "残り:",@mc,"/",@total," " 17*eeb7e5b3SAdam Hornáček pos(x,y) 18*eeb7e5b3SAdam Hornáček end 19*eeb7e5b3SAdam Hornáček private :clr, :pos, :colorstr, :put 20*eeb7e5b3SAdam Hornáček CHR=["・","1","2","3","4","5","6","7","8","★","●","@@"] 21*eeb7e5b3SAdam Hornáček COL=[46,43,45] # default,opened,over 22*eeb7e5b3SAdam Hornáček def initialize(h,w,m) 23*eeb7e5b3SAdam Hornáček # ゲーム盤の生成(h:縦,w:横,m:爆弾の数) 24*eeb7e5b3SAdam Hornáček @hi=h; @wi=w; @m=m 25*eeb7e5b3SAdam Hornáček reset 26*eeb7e5b3SAdam Hornáček end 27*eeb7e5b3SAdam Hornáček def reset 28*eeb7e5b3SAdam Hornáček # ゲーム盤を(再)初期化する 29*eeb7e5b3SAdam Hornáček srand() 30*eeb7e5b3SAdam Hornáček @cx=0; @cy=0; @mc=@m 31*eeb7e5b3SAdam Hornáček @over=false 32*eeb7e5b3SAdam Hornáček @data=Array.new(@hi*@wi) 33*eeb7e5b3SAdam Hornáček @state=Array.new(@hi*@wi) 34*eeb7e5b3SAdam Hornáček @total=@hi*@wi 35*eeb7e5b3SAdam Hornáček @total.times {|i| @data[i]=0} 36*eeb7e5b3SAdam Hornáček @m.times do 37*eeb7e5b3SAdam Hornáček loop do 38*eeb7e5b3SAdam Hornáček j=rand(@total-1) 39*eeb7e5b3SAdam Hornáček if @data[j] == 0 then 40*eeb7e5b3SAdam Hornáček @data[j]=1 41*eeb7e5b3SAdam Hornáček break 42*eeb7e5b3SAdam Hornáček end 43*eeb7e5b3SAdam Hornáček end 44*eeb7e5b3SAdam Hornáček end 45*eeb7e5b3SAdam Hornáček clr; pos(0,0) 46*eeb7e5b3SAdam Hornáček @hi.times{|y| pos(0,y); colorstr(COL[0],CHR[0]*@wi)} 47*eeb7e5b3SAdam Hornáček pos(@cx,@cy) 48*eeb7e5b3SAdam Hornáček end 49*eeb7e5b3SAdam Hornáček def mark 50*eeb7e5b3SAdam Hornáček # 現在のカーソル位置にマークをつける 51*eeb7e5b3SAdam Hornáček if @state[@wi*@cy+@cx] != nil then return end 52*eeb7e5b3SAdam Hornáček @state[@wi*@cy+@cx] = "MARK" 53*eeb7e5b3SAdam Hornáček @mc=@mc-1; 54*eeb7e5b3SAdam Hornáček @total=@total-1; 55*eeb7e5b3SAdam Hornáček put(@cx, @cy, COL[1], CHR[9]) 56*eeb7e5b3SAdam Hornáček end 57*eeb7e5b3SAdam Hornáček def open(x=@cx,y=@cy) 58*eeb7e5b3SAdam Hornáček # 現在のカーソル位置をオープンにする 59*eeb7e5b3SAdam Hornáček # 爆弾があればゲームオーバー 60*eeb7e5b3SAdam Hornáček if @state[@wi*y+x] =="OPEN" then return 0 end 61*eeb7e5b3SAdam Hornáček if @state[@wi*y+x] == nil then @total=@total-1 end 62*eeb7e5b3SAdam Hornáček if @state[@wi*y+x] =="MARK" then @mc=@mc+1 end 63*eeb7e5b3SAdam Hornáček @state[@wi*y+x]="OPEN" 64*eeb7e5b3SAdam Hornáček if fetch(x,y) == 1 then @over = 1; return end 65*eeb7e5b3SAdam Hornáček c = count(x,y) 66*eeb7e5b3SAdam Hornáček put(x, y, COL[1], CHR[c]) 67*eeb7e5b3SAdam Hornáček return 0 if c != 0 68*eeb7e5b3SAdam Hornáček if x > 0 && y > 0 then open(x-1,y-1) end 69*eeb7e5b3SAdam Hornáček if y > 0 then open(x, y-1) end 70*eeb7e5b3SAdam Hornáček if x < @wi-1 && y > 0 then open(x+1,y-1) end 71*eeb7e5b3SAdam Hornáček if x > 0 then open(x-1,y) end 72*eeb7e5b3SAdam Hornáček if x < @wi-1 then open(x+1,y) end 73*eeb7e5b3SAdam Hornáček if x > 0 && y < @hi-1 then open(x-1,y+1) end 74*eeb7e5b3SAdam Hornáček if y < @hi -1 then open(x,y+1) end 75*eeb7e5b3SAdam Hornáček if x < @wi-1 && y < @hi-1 then open(x+1,y+1) end 76*eeb7e5b3SAdam Hornáček pos(@cx,@cy) 77*eeb7e5b3SAdam Hornáček end 78*eeb7e5b3SAdam Hornáček def fetch(x,y) 79*eeb7e5b3SAdam Hornáček # (x,y)の位置の爆弾の数(0 or 1)を返す 80*eeb7e5b3SAdam Hornáček if x < 0 then 0 81*eeb7e5b3SAdam Hornáček elsif x >= @wi then 0 82*eeb7e5b3SAdam Hornáček elsif y < 0 then 0 83*eeb7e5b3SAdam Hornáček elsif y >= @hi then 0 84*eeb7e5b3SAdam Hornáček else 85*eeb7e5b3SAdam Hornáček @data[y*@wi+x] 86*eeb7e5b3SAdam Hornáček end 87*eeb7e5b3SAdam Hornáček end 88*eeb7e5b3SAdam Hornáček def count(x,y) 89*eeb7e5b3SAdam Hornáček # (x,y)に隣接する爆弾の数を返す 90*eeb7e5b3SAdam Hornáček fetch(x-1,y-1)+fetch(x,y-1)+fetch(x+1,y-1)+ 91*eeb7e5b3SAdam Hornáček fetch(x-1,y) + fetch(x+1,y)+ 92*eeb7e5b3SAdam Hornáček fetch(x-1,y+1)+fetch(x,y+1)+fetch(x+1,y+1) 93*eeb7e5b3SAdam Hornáček end 94*eeb7e5b3SAdam Hornáček def over(win) 95*eeb7e5b3SAdam Hornáček # ゲームの終了 96*eeb7e5b3SAdam Hornáček quit 97*eeb7e5b3SAdam Hornáček unless win 98*eeb7e5b3SAdam Hornáček pos(@cx,@cy); print CHR[11] 99*eeb7e5b3SAdam Hornáček end 100*eeb7e5b3SAdam Hornáček pos(0,@hi) 101*eeb7e5b3SAdam Hornáček if win then print "*** YOU WIN !! ***" 102*eeb7e5b3SAdam Hornáček else print "*** GAME OVER ***" 103*eeb7e5b3SAdam Hornáček end 104*eeb7e5b3SAdam Hornáček end 105*eeb7e5b3SAdam Hornáček def over? 106*eeb7e5b3SAdam Hornáček # ゲームの終了チェック 107*eeb7e5b3SAdam Hornáček # 終了処理も呼び出す 108*eeb7e5b3SAdam Hornáček remain = (@mc+@total == 0) 109*eeb7e5b3SAdam Hornáček if @over || remain 110*eeb7e5b3SAdam Hornáček over(remain) 111*eeb7e5b3SAdam Hornáček true 112*eeb7e5b3SAdam Hornáček else 113*eeb7e5b3SAdam Hornáček false 114*eeb7e5b3SAdam Hornáček end 115*eeb7e5b3SAdam Hornáček end 116*eeb7e5b3SAdam Hornáček def quit 117*eeb7e5b3SAdam Hornáček # ゲームの中断(または終了) 118*eeb7e5b3SAdam Hornáček # 盤面を全て見せる 119*eeb7e5b3SAdam Hornáček @hi.times do|y| 120*eeb7e5b3SAdam Hornáček pos(0,y) 121*eeb7e5b3SAdam Hornáček @wi.times do|x| 122*eeb7e5b3SAdam Hornáček colorstr(if @state[y*@wi+x] == "MARK" then COL[1] else COL[2] end, 123*eeb7e5b3SAdam Hornáček if fetch(x,y)==1 then CHR[10] else CHR[count(x,y)] end) 124*eeb7e5b3SAdam Hornáček end 125*eeb7e5b3SAdam Hornáček end 126*eeb7e5b3SAdam Hornáček end 127*eeb7e5b3SAdam Hornáček def down 128*eeb7e5b3SAdam Hornáček # カーソルを下に 129*eeb7e5b3SAdam Hornáček if @cy < @hi-1 then @cy=@cy+1; pos(@cx, @cy) end 130*eeb7e5b3SAdam Hornáček end 131*eeb7e5b3SAdam Hornáček def up 132*eeb7e5b3SAdam Hornáček # カーソルを上に 133*eeb7e5b3SAdam Hornáček if @cy > 0 then @cy=@cy-1; pos(@cx, @cy) end 134*eeb7e5b3SAdam Hornáček end 135*eeb7e5b3SAdam Hornáček def left 136*eeb7e5b3SAdam Hornáček # カーソルを左に 137*eeb7e5b3SAdam Hornáček if @cx > 0 then @cx=@cx-1; pos(@cx, @cy) end 138*eeb7e5b3SAdam Hornáček end 139*eeb7e5b3SAdam Hornáček def right 140*eeb7e5b3SAdam Hornáček # カーソルを右に 141*eeb7e5b3SAdam Hornáček if @cx < @wi-1 then @cx=@cx+1; pos(@cx, @cy) end 142*eeb7e5b3SAdam Hornáček end 143*eeb7e5b3SAdam Hornáčekend 144*eeb7e5b3SAdam Hornáček 145*eeb7e5b3SAdam Hornáčekbd=Board.new(10,10,10) 146*eeb7e5b3SAdam Hornáčeksystem("stty raw -echo") 147*eeb7e5b3SAdam Hornáčekbegin 148*eeb7e5b3SAdam Hornáček loop do 149*eeb7e5b3SAdam Hornáček case STDIN.getc 150*eeb7e5b3SAdam Hornáček when ?n # new game 151*eeb7e5b3SAdam Hornáček bd.reset 152*eeb7e5b3SAdam Hornáček when ?m # mark 153*eeb7e5b3SAdam Hornáček bd.mark 154*eeb7e5b3SAdam Hornáček when ?j 155*eeb7e5b3SAdam Hornáček bd.down 156*eeb7e5b3SAdam Hornáček when ?k 157*eeb7e5b3SAdam Hornáček bd.up 158*eeb7e5b3SAdam Hornáček when ?h 159*eeb7e5b3SAdam Hornáček bd.left 160*eeb7e5b3SAdam Hornáček when ?l 161*eeb7e5b3SAdam Hornáček bd.right 162*eeb7e5b3SAdam Hornáček when ?\s 163*eeb7e5b3SAdam Hornáček bd.open 164*eeb7e5b3SAdam Hornáček when ?q,?\C-c # quit game 165*eeb7e5b3SAdam Hornáček bd.quit 166*eeb7e5b3SAdam Hornáček break 167*eeb7e5b3SAdam Hornáček end 168*eeb7e5b3SAdam Hornáček if bd.over? 169*eeb7e5b3SAdam Hornáček if STDIN.getc == ?q then break end 170*eeb7e5b3SAdam Hornáček bd.reset 171*eeb7e5b3SAdam Hornáček end 172*eeb7e5b3SAdam Hornáček end 173*eeb7e5b3SAdam Hornáčekensure 174*eeb7e5b3SAdam Hornáček system("stty -raw echo") 175*eeb7e5b3SAdam Hornáčekend 176*eeb7e5b3SAdam Hornáčekprint "\n" 177*eeb7e5b3SAdam Hornáčekprint 'http://example.com' 178*eeb7e5b3SAdam Hornáčekputs "Last #{log_lines} lines from #{logfn}:" 179*eeb7e5b3SAdam Hornáčekprint "\n" 180