赞 | 13 |
VIP | 118 |
好人卡 | 28 |
积分 | 12 |
经验 | 35779 |
最后登录 | 2017-7-6 |
在线时间 | 1564 小时 |
Lv3.寻梦者
- 梦石
- 0
- 星屑
- 1245
- 在线时间
- 1564 小时
- 注册时间
- 2008-7-30
- 帖子
- 4418

|
4楼

楼主 |
发表于 2011-10-23 09:05:18
|
只看该作者
各种压力的猫君 发表于 2011-10-23 05:26 ![]()
想不出连扫雷都会小卡究竟有什么应用长处 = = b
可能是因为我用的是Intel D915GAV芯片组的集显的缘故。
既然是中小型应用,自然不会有什么太大的压力。- #
- # Shoes Minesweeper by que/varyform
- #
- LEVELS = { :beginner => [9, 9, 10], :intermediate => [16, 16, 40], :expert => [30, 16, 99] }
- class Field
- CELL_SIZE = 20
- COLORS = %w(#00A #0A0 #A00 #004 #040 #400 #000)
-
- class Cell
- attr_accessor :flag
- def initialize(aflag = false)
- @flag = aflag
- end
- end
-
- class Bomb < Cell
- attr_accessor :exploded
- def initialize(exploded = false)
- @exploded = exploded
- end
- end
-
- class OpenCell < Cell
- attr_accessor :number
- def initialize(bombs_around = 0)
- @number = bombs_around
- end
- end
-
- class EmptyCell < Cell; end
-
- attr_reader :cell_size, :offset
-
- def initialize(app, level = :beginner)
- @app = app
- @field = []
- @w, @h, @bombs = LEVELS[level][0], LEVELS[level][1], LEVELS[level][2]
- @h.times { @field << Array.new(@w) { EmptyCell.new } }
- @game_over = false
- @width, @height, @cell_size = @w * CELL_SIZE, @h * CELL_SIZE, CELL_SIZE
- @offset = [(@app.width - @width.to_i) / 2, (@app.height - @height.to_i) / 2]
- plant_bombs
- @start_time = Time.now
- end
-
- def total_time
- @latest_time = Time.now - @start_time unless game_over? || all_found?
- @latest_time
- end
-
- def click!(x, y)
- return unless cell_exists?(x, y)
- return if has_flag?(x, y)
- return die!(x, y) if bomb?(x, y)
- open(x, y)
- discover(x, y) if bombs_around(x, y) == 0
- end
- def flag!(x, y)
- return unless cell_exists?(x, y)
- self[x, y].flag = !self[x, y].flag unless self[x, y].is_a?(OpenCell)
- end
-
- def game_over?
- @game_over
- end
-
- def render_cell(x, y, color = "#AAA", stroke = true)
- @app.stroke "#666" if stroke
- @app.fill color
- @app.rect x*cell_size, y*cell_size, cell_size-1, cell_size-1
- @app.stroke "#BBB" if stroke
- @app.line x*cell_size+1, y*cell_size+1, x*cell_size+cell_size-1, y*cell_size
- @app.line x*cell_size+1, y*cell_size+1, x*cell_size, y*cell_size+cell_size-1
- end
-
- def render_flag(x, y)
- @app.stroke "#000"
- @app.line(x*cell_size+cell_size / 4 + 1, y*cell_size + cell_size / 5, x*cell_size+cell_size / 4 + 1, y*cell_size+cell_size / 5 * 4)
- @app.fill "#A00"
- @app.rect(x*cell_size+cell_size / 4+2, y*cell_size + cell_size / 5,
- cell_size / 3, cell_size / 4)
- end
-
- def render_bomb(x, y)
- render_cell(x, y)
- if (game_over? or all_found?) then # draw bomb
- if self[x, y].exploded then
- render_cell(x, y, @app.rgb(0xFF, 0, 0, 0.5))
- end
- @app.nostroke
- @app.fill @app.rgb(0, 0, 0, 0.8)
- @app.oval(x*cell_size+3, y*cell_size+3, 13)
- @app.fill "#333"
- @app.oval(x*cell_size+5, y*cell_size+5, 7)
- @app.fill "#AAA"
- @app.oval(x*cell_size+6, y*cell_size+6, 3)
- @app.fill @app.rgb(0, 0, 0, 0.8)
- @app.stroke "#222"
- @app.strokewidth 2
- @app.oval(x*cell_size + cell_size / 2 + 2, y*cell_size + cell_size / 4 - 2, 2)
- @app.oval(x*cell_size + cell_size / 2 + 4, y*cell_size + cell_size / 4 - 2, 1)
- @app.strokewidth 1
- end
- end
-
- def render_number(x, y)
- render_cell(x, y, "#999", false)
- if self[x, y].number != 0 then
- @app.nostroke
- @app.para self[x, y].number.to_s, :left => x*cell_size + 3, :top => y*cell_size - 2,
- :font => '13px', :stroke => COLORS[self[x, y].number - 1]
- end
- end
-
- def paint
- 0.upto @h-1 do |y|
- 0.upto @w-1 do |x|
- @app.nostroke
- case self[x, y]
- when EmptyCell then render_cell(x, y)
- when Bomb then render_bomb(x, y)
- when OpenCell then render_number(x, y)
- end
- render_flag(x, y) if has_flag?(x, y) && !(game_over? && bomb?(x, y))
- end
- end
- end
- def bombs_left
- @bombs - @field.flatten.compact.reject {|e| !e.flag }.size
- end
- def all_found?
- @field.flatten.compact.reject {|e| !e.is_a?(OpenCell) }.size + @bombs == @w*@h
- end
- def reveal!(x, y)
- return unless cell_exists?(x, y)
- return unless self[x, y].is_a?(Field::OpenCell)
- if flags_around(x, y) >= self[x, y].number then
- (-1..1).each do |v|
- (-1..1).each { |h| click!(x+h, y+v) unless (v==0 && h==0) or has_flag?(x+h, y+v) }
- end
- end
- end
-
- private
-
- def cell_exists?(x, y)
- ((0...@w).include? x) && ((0...@h).include? y)
- end
-
- def has_flag?(x, y)
- return false unless cell_exists?(x, y)
- return self[x, y].flag
- end
-
- def bomb?(x, y)
- cell_exists?(x, y) && (self[x, y].is_a? Bomb)
- end
-
- def can_be_discovered?(x, y)
- return false unless cell_exists?(x, y)
- return false if self[x, y].flag
- cell_exists?(x, y) && (self[x, y].is_a? EmptyCell) && !bomb?(x, y) && (bombs_around(x, y) == 0)
- end
-
- def open(x, y)
- self[x, y] = OpenCell.new(bombs_around(x, y)) unless (self[x, y].is_a? OpenCell) or has_flag?(x, y)
- end
-
- def neighbors
- (-1..1).each do |col|
- (-1..1).each { |row| yield row, col unless col==0 && row == 0 }
- end
- end
-
- def discover(x, y)
- open(x, y)
- neighbors do |col, row|
- cx, cy = x+row, y+col
- next unless cell_exists?(cx, cy)
- discover(cx, cy) if can_be_discovered?(cx, cy)
- open(cx, cy)
- end
- end
- def count_neighbors
- return 0 unless block_given?
- count = 0
- neighbors { |h, v| count += 1 if yield(h, v) }
- count
- end
-
- def bombs_around(x, y)
- count_neighbors { |v, h| bomb?(x+h, y+v) }
- end
-
- def flags_around(x, y)
- count_neighbors { |v, h| has_flag?(x+h, y+v) }
- end
-
- def die!(x, y)
- self[x, y].exploded = true
- @game_over = true
- end
- def plant_bomb(x, y)
- self[x, y].is_a?(EmptyCell) ? self[x, y] = Bomb.new : false
- end
-
- def plant_bombs
- @bombs.times { redo unless plant_bomb(rand(@w), rand(@h)) }
- end
- def [](*args)
- x, y = args
- raise "Cell #{x}:#{y} does not exists!" unless cell_exists?(x, y)
- @field[y][x]
- end
-
- def []=(*args)
- x, y, v = args
- cell_exists?(x, y) ? @field[y][x] = v : false
- end
- end
- Shoes.app :width => 730, :height => 450, :title => 'Minesweeper' do
- def render_field
- clear do
- background rgb(50, 50, 90, 0.7)
- flow :margin => 4 do
- button("Beginner") { new_game :beginner }
- button("Intermediate") { new_game :intermediate }
- button("Expert") { new_game :expert }
- end
- stack do @status = para :stroke => white end
- @field.paint
- para "Left click - open cell, right click - put flag, middle click - reveal empty cells", :top => 420, :left => 0, :stroke => white, :font => "11px"
- end
- end
-
- def new_game level
- @field = Field.new self, level
- translate -@old_offset.first, -@old_offset.last unless @old_offset.nil?
- translate @field.offset.first, @field.offset.last
- @old_offset = @field.offset
- render_field
- end
-
- new_game :beginner
- animate(5) { @status.replace "Time: #{@field.total_time.to_i} Bombs left: #{@field.bombs_left}" }
-
- click do |button, x, y|
- next if @field.game_over? || @field.all_found?
- fx, fy = (([email protected]) / @field.cell_size).to_i, (([email protected]) / @field.cell_size).to_i
- @field.click!(fx, fy) if button == 1
- @field.flag!(fx, fy) if button == 2
- @field.reveal!(fx, fy) if button == 3
- render_field
- alert("Winner!\nTotal time: #{@field.total_time}") if @field.all_found?
- alert("Bang!\nYou loose.") if @field.game_over?
- end
- end
复制代码 |
|