* io.c (rb_open_file): encoding in mode string was ignored if perm is
[ruby-svn.git] / sample / mine.rb
blob8fc27e0c6d6f989a3bb417d4a92deb7d1e08419c
1 #! /usr/bin/ruby -Ke
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)
15     pos(0,@hi); print "»Ä¤ê:",@mc,"/",@total,"   "
16     pos(x,y)
17   end
18   private :clr, :pos, :colorstr, :put
19   CHR=["¡¦","£±","£²","£³","£´","£µ","£¶","£·","£¸","¡ú","¡ü","@@"]
20   COL=[46,43,45] # default,opened,over
21   def initialize(h,w,m)
22     # ¥²¡¼¥àÈפÎÀ¸À®(h:½Ä¡¤w:²£¡¤m:ÇúÃƤοô)
23     @hi=h; @wi=w; @m=m
24     reset
25   end
26   def reset
27     # ¥²¡¼¥àÈפò(ºÆ)½é´ü²½¤¹¤ë
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
49     # ¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃ֤˥ޡ¼¥¯¤ò¤Ä¤±¤ë
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)
57     # ¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃÖ¤ò¥ª¡¼¥×¥ó¤Ë¤¹¤ë
58     # ÇúÃƤ¬¤¢¤ì¤Ð¥²¡¼¥à¥ª¡¼¥Ð¡¼
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)
78     # (x,y)¤Î°ÌÃÖ¤ÎÇúÃƤοô(0 or 1)¤òÊÖ¤¹
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
84       @data[y*@wi+x]
85     end
86   end
87   def count(x,y)
88     # (x,y)¤ËÎÙÀܤ¹¤ëÇúÃƤοô¤òÊÖ¤¹
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)
94     # ¥²¡¼¥à¤Î½ªÎ»
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?
105     # ¥²¡¼¥à¤Î½ªÎ»¥Á¥§¥Ã¥¯
106     # ½ªÎ»½èÍý¤â¸Æ¤Ó½Ð¤¹
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
116     # ¥²¡¼¥à¤ÎÃæÃÇ(¤Þ¤¿¤Ï½ªÎ»)
117     # È×Ì̤òÁ´¤Æ¸«¤»¤ë
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
127     # ¥«¡¼¥½¥ë¤ò²¼¤Ë
128     if @cy < @hi-1 then @cy=@cy+1; pos(@cx, @cy) end
129   end
130   def up
131     # ¥«¡¼¥½¥ë¤ò¾å¤Ë
132     if @cy > 0 then @cy=@cy-1; pos(@cx, @cy) end
133   end
134   def left
135     # ¥«¡¼¥½¥ë¤òº¸¤Ë
136     if @cx > 0 then @cx=@cx-1; pos(@cx, @cy) end
137   end
138   def right
139     # ¥«¡¼¥½¥ë¤ò±¦¤Ë
140     if @cx < @wi-1 then @cx=@cx+1; pos(@cx, @cy) end
141   end
144 bd=Board.new(10,10,10)
145 system("stty raw -echo")
146 begin
147   loop do
148     case STDIN.getc
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?
168       if STDIN.getc == ?q then break end
169       bd.reset
170     end
171   end
172 ensure
173   system("stty -raw echo")
175 print "\n"