Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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