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