120 lines
3.8 KiB
Ruby
Executable file
120 lines
3.8 KiB
Ruby
Executable file
#!/usr/bin/env ruby
|
|
# frozen_string_literal: true
|
|
|
|
require 'gosu'
|
|
|
|
require 'minehunt'
|
|
|
|
class GosuHunt < Gosu::Window
|
|
def initialize( number_of_mines = 20 )
|
|
@scale = 4
|
|
@sprite_size = 6
|
|
|
|
super ( @scale * ( @sprite_size * 16 ) ) + 16 + @scale,
|
|
( @scale * ( @sprite_size * 8 ) ) + 20 + 8 + @scale
|
|
|
|
self.caption = 'Gosu Hunt'
|
|
|
|
@number_of_mines = number_of_mines
|
|
@field = MineHunt::Board.new( @number_of_mines )
|
|
@finished = false
|
|
@state = { dead: false, victory: false }
|
|
|
|
@font = Gosu::Font.new( 20 )
|
|
@images = { explorer: Gosu::Image.from_blob( @sprite_size, @sprite_size, bits_to_rgbas( '000000001100011110011110001100000000' ) ),
|
|
dead_explorer: Gosu::Image.from_blob( @sprite_size, @sprite_size, bits_to_rgbas( '100001010010001100001100010010100001' ) ),
|
|
door: Gosu::Image.from_blob( @sprite_size, @sprite_size, bits_to_rgbas( '010101101010' ) * ( @sprite_size / 2 ) ),
|
|
mine: Gosu::Image.from_blob( @sprite_size, @sprite_size, bits_to_rgbas( '111111110011100001100001110011111111' ) ),
|
|
cell: Gosu::Image.from_blob( @sprite_size, @sprite_size, bits_to_rgbas( '1' ) * @sprite_size * @sprite_size ),
|
|
visited_cell: Gosu::Image.from_blob( @sprite_size, @sprite_size, bits_to_rgbas( '0' ) * @sprite_size * @sprite_size ) }
|
|
end
|
|
|
|
def bits_to_rgbas( bits )
|
|
bits.gsub( '0', "\0\0\0\0" ).gsub( '1', "\255\255\255\255" )
|
|
end
|
|
|
|
def new_level
|
|
@field = MineHunt::Board.new( @number_of_mines )
|
|
@finished = false
|
|
@state = { dead: false, victory: false }
|
|
end
|
|
|
|
def button_up(id)
|
|
if @finished
|
|
case id
|
|
when Gosu::KB_ESCAPE, Gosu::KB_Q
|
|
close
|
|
when Gosu::KB_R
|
|
new_level
|
|
else
|
|
super
|
|
end
|
|
else
|
|
case id
|
|
when Gosu::KB_ESCAPE, Gosu::KB_Q
|
|
close
|
|
when Gosu::KB_R
|
|
new_level
|
|
when Gosu::KB_NUMPAD_1
|
|
@state = @field.move 'down-left'
|
|
when Gosu::KB_NUMPAD_2, Gosu::KB_DOWN
|
|
@state = @field.move 'down'
|
|
when Gosu::KB_NUMPAD_3
|
|
@state = @field.move 'down-right'
|
|
when Gosu::KB_NUMPAD_4, Gosu::KB_LEFT
|
|
@state = @field.move 'left'
|
|
when Gosu::KB_NUMPAD_6, Gosu::KB_RIGHT
|
|
@state = @field.move 'right'
|
|
when Gosu::KB_NUMPAD_7
|
|
@state = @field.move 'up-left'
|
|
when Gosu::KB_NUMPAD_8, Gosu::KB_UP
|
|
@state = @field.move 'up'
|
|
when Gosu::KB_NUMPAD_9
|
|
@state = @field.move 'up-right'
|
|
else
|
|
super
|
|
end
|
|
end
|
|
|
|
@finished = @state[:dead] || @state[:victory]
|
|
end
|
|
|
|
def update; end
|
|
|
|
def draw
|
|
self.caption = if @state[:dead]
|
|
"You blew up!! :(, score: #{@field.score} "
|
|
elsif @state[:victory]
|
|
"You won!! :), score: #{@field.score} "
|
|
else
|
|
"Near #{@field.count_nearby_mines} mines, score: #{@field.score}"
|
|
end
|
|
|
|
@font.draw_text( caption, 0, 0, 0 )
|
|
|
|
@field.height.times do |y|
|
|
@field.width.times do |x|
|
|
( if [@field.explorer_x, @field.explorer_y] == [x, y]
|
|
@state[:dead] ? @images[:dead_explorer] : @images[:explorer]
|
|
elsif [@field.width, @field.height] == [x + 1, y + 1]
|
|
@images[:door]
|
|
elsif @field.field[[x, y]].open
|
|
@images[:visited_cell]
|
|
elsif @field.field[[x, y]].mine && ( @state[:dead] || @state[:victory] )
|
|
@images[:mine]
|
|
else
|
|
@images[:cell]
|
|
end ).draw ( @scale * ( x * @sprite_size ) ) + x + @scale,
|
|
( @scale * ( y * @sprite_size ) ) + 20 + y + @scale,
|
|
0,
|
|
@scale,
|
|
@scale
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
number_of_mines = 20
|
|
number_of_mines = ARGV.first.to_i if ARGV.length == 1
|
|
|
|
GosuHunt.new( number_of_mines ).show
|