class RSokoban::RSokobanGame
Constants
Public Class Methods
new(window)
click to toggle source
# File lib/rsokoban_game.rb, line 12 def initialize(window) @window = window end
Public Instance Methods
can_move?(direction)
click to toggle source
# File lib/rsokoban_game.rb, line 16 def can_move?(direction) # Calculate the player's new position if this move is to be executed. Remember that # `new_player` is an Array whereas @player is a Hash. new_player = [@player[:row], @player[:col]].zip(DIRECTIONS[direction]).map{|a, b| a + b} if @walls[new_player] then return false else if @boxes[new_player] then # Calculate the position of any box that's in the player's way. new_box = new_player.zip(DIRECTIONS[direction]).map{|a, b| a + b} if @walls[new_box] or @boxes[new_box] then return false else return true end else return true end end end
draw()
click to toggle source
# File lib/rsokoban_game.rb, line 38 def draw @current_level.walls.keys.each do |k| @window.move k[0], k[1] @window.addstr '#' end @goals.keys.each do |k| @window.move k[0], k[1] @window.addstr '.' end @boxes.keys.each do |k| @window.move k[0], k[1] if @goals[k] then @window.addstr '+' else @window.addstr '$' end end @window.move @player[:row], @player[:col] @window.addstr '@' @window.refresh end
level_complete?()
click to toggle source
# File lib/rsokoban_game.rb, line 60 def level_complete? (@boxes.keys - @goals.keys).empty? end
move(direction)
click to toggle source
# File lib/rsokoban_game.rb, line 64 def move(direction) return unless can_move?(direction) new_player = [@player[:row], @player[:col]].zip(DIRECTIONS[direction]).map{|a, b| a + b} if @boxes[new_player] then new_box = new_player.zip(DIRECTIONS[direction]).map{|a, b| a + b} @boxes[new_box] = true @boxes.delete new_player end # Cover up the space behind the player with a space. @window.move @player[:row], @player[:col] @window.addstr ' ' @player[:row], @player[:col] = new_player @states.push({:player => @player.dup, :boxes => @boxes.dup}) end
play_level(level)
click to toggle source
# File lib/rsokoban_game.rb, line 82 def play_level(level) @current_level = level.dup @walls = level.walls.dup @boxes = level.boxes.dup @player = level.player.dup @goals = level.goals.dup @states = [{:player => @player.dup, :boxes => @boxes.dup}] draw until level_complete? ch = @window.getch case ch when 'q'.ord exit when 'r'.ord @window.clear return play_level(level) when 'n'.ord return when 'z'.ord undo when Ncurses::KEY_DOWN, 's'.ord, 'j'.ord move :down when Ncurses::KEY_UP, 'w'.ord, 'k'.ord move :up when Ncurses::KEY_RIGHT, 'd'.ord, 'l'.ord move :right when Ncurses::KEY_LEFT, 'a'.ord, 'h'.ord move :left end draw end end
undo()
click to toggle source
# File lib/rsokoban_game.rb, line 122 def undo state = @states.pop @boxes = state[:boxes] @player = state[:player] @window.clear @states.push(state) if @states.empty? end