Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
- # • Minesweeper • Date :29-05-2014
- # Original Author :DrDhoom
- # XP / VXAce ver by LiTTleDRAgo
- #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
- #
- # How to call
- # Xp : $scene = Scene_Minesweeper.new
- # Vxa : SceneManager.call(Scene_Minesweeper)
- #
- # Graphics used :
- # - Graphics/System/minesweeper_back.png
- # - Graphics/System/minesweeper_button.png
- # - Graphics/System/minesweeper_flag.png
- # - Graphics/System/minesweeper_mines.png
- # - Graphics/System/minesweeper_selection.png
- #
- #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
- module Minesweeper
- Difficulty = [
- # Difficulty, Width, Height, Total Mine.
- ['Monkey' , 20, 15, 4],
- ['Easy' , 9, 9, 10],
- ['Medium' , 15, 15, 40],
- ['Hard' , 20, 15, 99],
- ]
- Return_Scene = Scene_Map
- # Variable which contain the result of the game.
- Result_Variable = 10
- # Result = -1 : lose
- # 0 : escape
- # 1 : win
- end
- ($imported ||= {})[:drdhoom_minesweeper] = 1.00
- $imported[:drg_core_engine] || raise("This script needs Drago Core Engine")
- $imported[:drg_custom_input] || raise("This script needs Drago Custom Input")
- #==============================================================================
- # ** Window_Command
- #------------------------------------------------------------------------------
- # This window deals with Scene_Minesweeper choices.
- #==============================================================================
- class Window_Minesweeper_Difficulty < Window_Command
- #--------------------------------------------------------------------------
- # * Create Command List
- #--------------------------------------------------------------------------
- def make_command_list
- Minesweeper::Difficulty.compact.each do |diff|
- add_command(diff[0], :"#{diff[0]}")
- end
- end
- end
- #==============================================================================
- # ** Scene_Minesweeper
- #------------------------------------------------------------------------------
- # This class performs the Minesweeper screen processing.
- #==============================================================================
- class Scene_Minesweeper
- #--------------------------------------------------------------------------
- # * Main
- #--------------------------------------------------------------------------
- def main
- start
- update while LiTTleDRAgo.scene == self
- terminate
- end
- #--------------------------------------------------------------------------
- # * Start Processing
- #--------------------------------------------------------------------------
- def start
- create_main_viewport
- init_value
- Graphics.transition
- create_window
- end
- #--------------------------------------------------------------------------
- # * Create Viewport
- #--------------------------------------------------------------------------
- def create_main_viewport
- @viewport = Viewport.new(0,0,Graphics.width,Graphics.height)
- @viewport.z = 200
- end
- #--------------------------------------------------------------------------
- # * Frame Update
- #--------------------------------------------------------------------------
- def update
- update_basic
- if @start
- update_info
- update_player_input
- elsif @result
- update_result_input
- end
- end
- #--------------------------------------------------------------------------
- # * Update Frame (Basic)
- #--------------------------------------------------------------------------
- def update_basic
- Graphics.update
- Input.update
- update_all_windows
- end
- #--------------------------------------------------------------------------
- # * Update All Windows
- #--------------------------------------------------------------------------
- def update_all_windows
- all = instance_variables.map {|s| instance_variable_get("#{s}")}.flatten
- all.delete_if {|s| s.not.is_a?(Window) }
- all.delete_if {|s| s.respond_to?(:disposed?) && s.disposed?}
- all.update
- end
- #--------------------------------------------------------------------------
- # * Termination Processing
- #--------------------------------------------------------------------------
- def terminate
- all_variable_dispose
- Graphics.freeze
- Graphics.resize_screen(*@old_res) if @old_res
- @button_sprite.flatten.dispose
- end
- #--------------------------------------------------------------------------
- # * New method: init_value
- #--------------------------------------------------------------------------
- def init_value
- @start = false
- @fail_safe = true
- @index = [0,0]
- @hour = 0
- @minute = 0
- @second = 0
- @frame = 0
- @total_flag = 0
- @old_res = [Graphics.width, Graphics.height]
- end
- #--------------------------------------------------------------------------
- # * New method: create_window
- #--------------------------------------------------------------------------
- def create_window
- return start_game unless LiTTleDRAgo::VXA
- @window = Window_Minesweeper_Difficulty.new(Graphics.width/2,
- Graphics.height/2)
- @window.x -= @window.width/2
- @window.y -= @window.height/2
- @window.set_handler(:ok, method(:start_game))
- end
- #--------------------------------------------------------------------------
- # * New method: start_game
- #--------------------------------------------------------------------------
- def start_game
- unless (vxa = LiTTleDRAgo::VXA)
- command = Minesweeper::Difficulty.collect {|diff| diff[0]}
- command = Window_Command.new(200,command)
- command.x = Graphics.width / 2 - command.width / 2
- command.y = Graphics.height / 2 - command.height / 2
- Input.update
- until Input.trigger?(Input::C)
- update
- command.update
- end
- Sound.play_ok
- end
- index = @window ? @window.index : command.index
- @tile_col = Minesweeper::Difficulty[index][1]
- @tile_row = Minesweeper::Difficulty[index][2]
- @total_mines = Minesweeper::Difficulty[index][3]
- Graphics.resize_screen(@tile_col*32,@tile_row*32)
- if @window
- @window.deactivate
- @window.visible = false
- else
- command.dispose
- end
- create_spriteset
- @start = true
- end
- #--------------------------------------------------------------------------
- # * New method: create_spriteset
- #--------------------------------------------------------------------------
- def create_spriteset
- @viewport1 = Viewport.new(0,0,@tile_col*32,@tile_row*32)
- @viewport2 = Viewport.new(0,0,@tile_col*32,@tile_row*32)
- @viewport3 = Viewport.new(0,0,@tile_col*32,@tile_row*32)
- @viewport1.z = 50
- @viewport2.z = 30
- @viewport3.z = 10
- @back_sprite = Plane.new
- @back_sprite.bitmap = begin
- LiTTleDRAgo.cache.system("minesweeper_back")
- rescue
- if LiTTleDRAgo::VXA
- LiTTleDRAgo.cache.tileset("Dungeon_A4").crop(0,320,32,32)
- else
- LiTTleDRAgo.cache.tileset("012-PortTown02").crop(32,32,32,32)
- end
- end
- @number_sprite = Sprite.new
- @number_sprite.bitmap = Bitmap.new(@tile_col*32,@tile_row*32)
- @shadow_sprite = Sprite.new
- @shadow_sprite.bitmap = Bitmap.new(@tile_col*32,@tile_row*32)
- @selection_sprite = Sprite.new
- @selection_sprite.bitmap = begin
- LiTTleDRAgo.cache.system("minesweeper_selection")
- rescue
- b = Bitmap.new(32,32)
- b.full_fill(Color.red)
- b.fill_rect(Rect.new(2,2,28,28),Color.erase)
- b
- end
- @selection_sprite.z = 99
- for i in 0...@tile_row
- for a in 0...@tile_col
- ((@open||=[])[i]||=[])[a] = false
- ((@mines||=[])[i]||=[])[a] = false
- ((@flag||=[])[i]||=[])[a] = false
- ((@button_sprite||=[])[i]||=[])[a] = Sprite.new
- @button_sprite[i][a].bitmap = begin
- LiTTleDRAgo.cache.system("minesweeper_button")
- rescue
- if LiTTleDRAgo::VXA
- LiTTleDRAgo.cache.tileset("Dungeon_A4").crop(224,352,32,32)
- else
- LiTTleDRAgo.cache.tileset("012-PortTown02").crop(128,32,32,32)
- end
- end
- @button_sprite[i][a].x = a*32
- @button_sprite[i][a].y = i*32
- end
- end
- @flag_sprite = Sprite.new
- @flag_sprite.z = 60
- @flag_sprite.bitmap = Bitmap.new(@tile_col*32,@tile_row*32)
- @info_sprite = Sprite.new
- @info_sprite.z = 70
- @info_sprite.bitmap = Bitmap.new(@tile_col*32,@tile_row*32)
- if @info_sprite.bitmap.font.respond_to?(:outline)
- @info_sprite.bitmap.font.outline = false
- end
- @info_sprite.bitmap.font.size = 18
- end
- #--------------------------------------------------------------------------
- # * New method: update_info
- #--------------------------------------------------------------------------
- def update_info
- @frame += 1
- @frame == 60 && (@frame = 0) && @second += 1
- @second == 60 && (@second = 0) && @minute += 1
- @minute == 60 && (@minute = 0) && @hour += 1
- refresh_info_sprite
- end
- #--------------------------------------------------------------------------
- # * New method: update_player_input
- #--------------------------------------------------------------------------
- def update_player_input
- if Input.repeat?(Input::DOWN)
- return if @index[1] == @tile_row-1
- Sound.play_cursor
- @index[1] += 1
- update_selection_sprite
- elsif Input.repeat?(Input::UP)
- return if @index[1] == 0
- Sound.play_cursor
- @index[1] -= 1
- update_selection_sprite
- elsif Input.repeat?(Input::LEFT)
- return if @index[0] == 0
- Sound.play_cursor
- @index[0] -= 1
- update_selection_sprite
- elsif Input.repeat?(Input::RIGHT)
- return if @index[0] == @tile_col-1
- Sound.play_cursor
- @index[0] += 1
- update_selection_sprite
- elsif Keyboard.trigger?(:Enter)
- return Sound.play_cancel if @flag[@index[1]][@index[0]]
- unless @open[@index[1]][@index[0]]
- Sound.play_ok
- if @fail_safe
- calculate_mines_placement
- refresh_number_sprite
- open_tile(true)
- @fail_safe = false
- else
- open_tile
- end
- refresh_button_sprite
- refresh_shadow_sprite
- check_win_condition
- end
- elsif Keyboard.trigger?(:Backspace)
- unless @open[@index[1]][@index[0]]
- Sound.play_ok
- place_flag
- refresh_flag
- end
- elsif Keyboard.trigger?(:Esc)
- Sound.play_cancel
- if Minesweeper::Result_Variable
- $game_variables[Minesweeper::Result_Variable] = 0
- end
- LiTTleDRAgo.scene = Minesweeper::Return_Scene.new
- end
- end
- #--------------------------------------------------------------------------
- # * New method: update_result_input
- #--------------------------------------------------------------------------
- def update_result_input
- if Keyboard.trigger?(:Enter)
- Sound.play_ok
- if (v = Minesweeper::Result_Variable)
- $game_variables[v] = @result == :win ? 1 : -1
- end
- LiTTleDRAgo.scene = Minesweeper::Return_Scene.new
- end
- end
- #--------------------------------------------------------------------------
- # * New method: update_selection_sprite
- #--------------------------------------------------------------------------
- def update_selection_sprite
- @selection_sprite.x = @index[0]*32
- @selection_sprite.y = @index[1]*32
- end
- #--------------------------------------------------------------------------
- # * New method: calculate_mines_placement
- #--------------------------------------------------------------------------
- def calculate_mines_placement
- mines = @total_mines
- while mines > 0
- rw = rand(@tile_col)
- rh = rand(@tile_row)
- if !@mines[rh][rw]
- if (rh < @index[1]-1 or rh > @index[1]+1) and
- (rw < @index[0]-1 or rw > @index[0]+1)
- @mines[rh][rw] = true
- mines -= 1
- end
- end
- end
- end
- #--------------------------------------------------------------------------
- # * New method: refresh_number_sprite
- #--------------------------------------------------------------------------
- def refresh_number_sprite
- @number_sprite.bitmap.font.size = 32
- if @number_sprite.bitmap.font.respond_to?(:outline)
- @number_sprite.bitmap.font.outline = false
- end
- @number = []
- for i in 0...@tile_row
- @number[i] = [] if @number[i].nil?
- for a in 0...@tile_col
- if @mines[i][a]
- c = -1
- else
- c = 0
- o1 = i-1 < 0 ? 0 : i-1
- o2 = i+1 > @tile_row-1 ? @tile_row-1 : i+1
- p1 = a-1 < 0 ? 0 : a-1
- p2 = a+1 > @tile_col-1 ? @tile_col-1 : a+1
- for y in o1..o2
- for x in p1..p2
- if @mines[y] != nil and @mines[y][x] and [y,x] != [i,a]
- c += 1
- end
- end
- end
- end
- @number[i][a] = c
- if c == -1
- bitmap = begin
- LiTTleDRAgo.cache.system("minesweeper_mines")
- rescue
- if LiTTleDRAgo::VXA
- LiTTleDRAgo.cache.character("!Other1").crop(288,0,32,32)
- else
- LiTTleDRAgo.cache.character("183-Rock02",0).crop(0,0,32,32)
- end
- end
- @number_sprite.bitmap.blt(a*32, i*32, bitmap, bitmap.rect)
- bitmap.dispose
- elsif c > 0
- @number_sprite.bitmap.font.color = number_color(c)
- @number_sprite.bitmap.draw_text(a*32, i*32,32,32,c.to_s,1)
- end
- end
- end
- end
- #--------------------------------------------------------------------------
- # * New method: number_color
- #--------------------------------------------------------------------------
- def number_color(index)
- case index
- when 1 then return Color.new(65,80,190)
- when 2 then return Color.new(30,110,0)
- when 3 then return Color.new(170,5,5)
- when 4 then return Color.new(0,0,125)
- when 5 then return Color.new(125,0,0)
- when 6 then return Color.new(0,125,125)
- when 7 then return Color.new(125,125,0)
- when 8 then return Color.new(125,0,125)
- end
- end
- #--------------------------------------------------------------------------
- # * New method: refresh_button_sprite
- #--------------------------------------------------------------------------
- def refresh_button_sprite
- for y in 0...@tile_row
- for x in 0...@tile_col
- @open[y][x] && @button_sprite[y][x].visible = false
- end
- end
- end
- #--------------------------------------------------------------------------
- # * New method: refresh_shadow_sprite
- #--------------------------------------------------------------------------
- def refresh_shadow_sprite
- (s = @shadow_sprite.bitmap).clear
- for y in 0...@tile_row
- for x in 0...@tile_col
- if !@open[y][x] and @open[y][x+1]
- s.fill_rect((x+1)*32,y*32,3,32,Color.new(0,0,0,80))
- end
- if !@open[y][x] and @open[y+1] != nil and @open[y+1][x]
- s.fill_rect(x*32,(y+1)*32,32,3,Color.new(0,0,0,80))
- end
- end
- end
- @shadow_sprite.bitmap.blur
- end
- #--------------------------------------------------------------------------
- # * New method: refresh_flag
- #--------------------------------------------------------------------------
- def refresh_flag
- @flag_sprite.bitmap.clear
- for y in 0...@tile_row
- for x in 0...@tile_col
- if @flag[y][x]
- bitmap = begin
- LiTTleDRAgo.cache.system("minesweeper_flag")
- rescue
- b = Bitmap.new(32,32)
- b.draw_edging_text(0,0,32,32,"*",1)
- b
- end
- @flag_sprite.bitmap.blt(x*32,y*32,bitmap,bitmap.rect)
- bitmap.dispose
- end
- end
- end
- end
- #--------------------------------------------------------------------------
- # * New method: refresh_info_sprite
- #--------------------------------------------------------------------------
- def refresh_info_sprite
- @info_sprite.bitmap.clear
- @info_sprite.bitmap.font.color = Color.new(255,0,0)
- @info_sprite.bitmap.draw_text(0,12,Graphics.width-18,18,"Mines : "+
- (@total_mines-@total_flag).to_s,2)
- @info_sprite.bitmap.font.color = Color.new(0,0,0)
- @info_sprite.bitmap.draw_text(0,30,Graphics.width-18,18,@hour.to_s +
- ":" + @minute.to_s + ":" + @second.to_s.to_s,2)
- end
- #--------------------------------------------------------------------------
- # * New method: open_tile
- #--------------------------------------------------------------------------
- def open_tile(clear = false)
- index = @index
- @open[index[1]][index[0]] = true
- if @number[index[1]][index[0]] == -1
- game_over
- elsif @number[index[1]][index[0]] == 0
- clear_tile([index[0],index[1]])
- elsif @number[index[1]][index[0]] > 0 and !clear
- flag = @number[index[1]][index[0]]
- o1 = index[1]-1 > 0 ? index[1]-1 : 0
- o2 = index[1]+1 < @tile_row-1 ? index[1]+1 : @tile_row-1
- p1 = index[0]-1 > 0 ? index[0]-1 : 0
- p2 = index[0]+1 < @tile_col-1 ? index[0]+1 : @tile_col-1
- for y in o1..o2
- for x in p1..p2
- if @flag[y] != nil and @flag[y][x] != nil and @flag[y][x]
- flag -= 1
- end
- end
- end
- return if flag != 0
- for y in o1..o2
- for x in p1..p2
- if @open[y] != nil and @open[y][x] != nil and
- [y][x] != index and !@open[y][x]
- if !@flag[y][x]
- @open[y][x] = true
- if @number[y][x] == -1
- game_over
- elsif @number[y][x] == 0
- clear_tile([x,y])
- end
- end
- end
- end
- end
- end
- end
- #--------------------------------------------------------------------------
- # * New method: place_flag
- #--------------------------------------------------------------------------
- def place_flag
- @flag[@index[1]][@index[0]] = !@flag[@index[1]][@index[0]]# ? false : true
- @total_flag = 0
- for y in 0...@tile_row
- for x in 0...@tile_col
- if @flag[y][x]
- @total_flag += 1
- end
- end
- end
- end
- #--------------------------------------------------------------------------
- # * New method: clear_tile
- #--------------------------------------------------------------------------
- def clear_tile(start)
- zero = [[start[0],start[1]]]
- while zero.size > 0
- o1 = zero[0][1]-1 > 0 ? zero[0][1]-1 : 0
- o2 = zero[0][1]+1 < @tile_row-1 ? zero[0][1]+1 : @tile_row-1
- p1 = zero[0][0]-1 > 0 ? zero[0][0]-1 : 0
- p2 = zero[0][0]+1 < @tile_col-1 ? zero[0][0]+1 : @tile_col-1
- for y in o1..o2
- for x in p1..p2
- if @open[y] != nil and @open[y][x] != nil and
- [[y][x]] != zero[0] and !@open[y][x] and @number[y][x] != -1
- @open[y][x] = true
- @number[y][x] == 0 && zero.push([x,y])
- end
- end
- end
- zero.delete_at(0)
- end
- end
- #--------------------------------------------------------------------------
- # * New method: game_over
- #--------------------------------------------------------------------------
- def game_over
- @result = :lose
- open_all_mines
- Sound.play_buzzer
- @sprite_end = Sprite.new
- @sprite_end.z = 999
- @sprite_end.y = Graphics.height/4+Graphics.height/4/2
- @sprite_end.bitmap = Bitmap.new(Graphics.width,Graphics.height/4)
- @sprite_end.bitmap.fill_rect(0,0,Graphics.width,
- Graphics.height/4,Color.new(0,0,0,128))
- @sprite_end.bitmap.font.size = Graphics.height/4/3
- @sprite_end.bitmap.font.bold = true
- @sprite_end.bitmap.draw_text(0,-12,
- Graphics.width,Graphics.height/4,"You Lose!",1)
- @sprite_end.bitmap.font.bold = false
- @sprite_end.bitmap.draw_text(0,Graphics.height/4/3-12,
- Graphics.width,Graphics.height/4,"Press Enter to exit",1)
- end
- #--------------------------------------------------------------------------
- # * New method: victory
- #--------------------------------------------------------------------------
- def victory
- @result = :win
- open_all_mines
- @sprite_end = Sprite.new
- @sprite_end.z = 999
- @sprite_end.y = Graphics.height/4+Graphics.height/4/2
- @sprite_end.bitmap = Bitmap.new(Graphics.width,Graphics.height/4)
- @sprite_end.bitmap.fill_rect(0,0,
- Graphics.width,Graphics.height/4,Color.new(0,0,0,128))
- @sprite_end.bitmap.font.size = Graphics.height/4/3
- @sprite_end.bitmap.font.color = Color.new(255,255,60)
- @sprite_end.bitmap.font.bold = true
- @sprite_end.bitmap.draw_text(0,-12,
- Graphics.width,Graphics.height/4,"You Win!",1)
- @sprite_end.bitmap.font.bold = false
- @sprite_end.bitmap.draw_text(0,Graphics.height/4/3-12,
- Graphics.width,Graphics.height/4,"Press Enter to exit",1)
- end
- #--------------------------------------------------------------------------
- # * New method: check_win_condition
- #--------------------------------------------------------------------------
- def check_win_condition
- return if @result
- a = 0
- b = 0
- c = LiTTleDRAgo::XP ? 4 : 0
- for y in 0...@tile_row
- for x in 0...@tile_col
- if (@open[y] != nil and @open[y][x]) or
- (@flag[y] != nil and @flag[y][x])
- a += 1
- @flag[y][x] && b += 1
- end
- end
- end
- if (a - @tile_col * @tile_row).abs <= c and b <= @total_mines
- victory
- end
- end
- #--------------------------------------------------------------------------
- # * New method: open_all_mines
- #--------------------------------------------------------------------------
- def open_all_mines
- for y in 0...@tile_row
- for x in 0...@tile_col
- @mines[y][x] && @open[y][x] = true
- end
- end
- refresh_button_sprite
- @start = false
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement