Skip to content

Instantly share code, notes, and snippets.

@JamesZoft
Created March 28, 2012 14:32
Show Gist options
  • Save JamesZoft/2226652 to your computer and use it in GitHub Desktop.
Save JamesZoft/2226652 to your computer and use it in GitHub Desktop.
Sokoban
#!/usr/bin/ruby
require 'pp'
$rows
$cols
class Sokoban
attr_accessor :crates, :empty_storage, :filled_storage, :playing_grid, :crate_id, :man_id, :wall_id, :floor_id,
:storage_id, :crate_on_storage_id, :man_on_storage_id, :symbols, :workman, :move_coords
def initialize()
$rows = 6
$cols = 6
@crate_id = "o"
@man_id = "@"
@workman = Man.new([3, 3])
@wall_id = "#"
@floor_id = " "
@storage_id = "."
@crate_on_storage_id = "*"
@man_on_storage_id = "+"
@symbols = {"Crate symbol:" => @crate_id, "Man symbol:" => @man_id, "Wall symbol:" => @wall_id, "Floor symbol:" => @floor_id, "Storage symbol:" => @storage_id, "Crate ontop of storage symbol:" => @crate_on_storage_id, "Man ontop of storage symbol:" => @man_on_storage_id}
@playing_grid =
Array.new($rows) do |row|
Array.new($cols) do |col|
if row.zero? || col.zero? || row == $rows - 1 || col == $cols - 1
@wall_id
end
end
end
@move_coords = []
@playing_grid[1][1] = @storage_id
@playing_grid[1][3] = @storage_id
@playing_grid[4][1] = @storage_id
@playing_grid[1][4] = @storage_id
@playing_grid[2][2] = @crate_id
@playing_grid[2][4] = @crate_id
@playing_grid[3][1] = @crate_id
@playing_grid[1][3] = @crate_id
@playing_grid[3][3] = workman
@playing_grid.each do |value|
value.each do |value2|
if value2 == nil
value[value.index(value2)] = @floor_id
end
if value2.object_id == @workman.object_id
value[value.index(value2)] = @man_id
end
end
end
end
def status
pp @playing_grid
end
def handle_move(new_workman_coords)
lh_index = new_workman_coords[0]
rh_index = new_workman_coords[1]
dir = new_workman_coords[2]
cannot_move_crate_string = "You cannot move the crate, something is in the way!"
crate_onto_storage_string = "You moved the crate onto a storage rack!"
future_pos = @playing_grid[lh_index][rh_index]
current_pos = @workman.coordinates
if future_pos == @crate_id
case dir
when "right"
if $cols - 3 == rh_index
puts cannot_move_crate_string
return
end
if [@crate_id, @wall_id].include?(@playing_grid[lh_index][rh_index + 1])
puts cannot_move_crate_string
return
end
if @playing_Grid[lh_index][rh_index + 1] == @storage_id
crate_onto_storage_string
crate_onto_storage([lh_index, rh_index], [lh_index, rh_index + 1])
end
when "left"
if 2 == rh_index
puts cannot_move_crate_string
return
end
if [@crate_id, @wall_id].include?(@playing_grid[lh_index][rh_index - 1])
puts cannot_move_crate_string
return
end
if @playing_Grid[lh_index][rh_index - 1] == @storage_id
crate_onto_storage_string
crate_onto_storage([lh_index, rh_index], [lh_index, rh_index - 1])
end
when "down"
if $rows - 3 == lh_index
puts cannot_move_crate_string
return
end
if [@crate_id, @wall_id].include?(@playing_grid[lh_index + 1][rh_index])
puts cannot_move_crate_string
return
end
if @playing_Grid[lh_index + 1][rh_index] == @storage_id
crate_onto_storage_string
crate_onto_storage([lh_index, rh_index], [lh_index + 1, rh_index])
end
when "up"
if 2 == lh_index
puts cannot_move_crate_string
return
end
if [@crate_id, @wall_id].include?(@playing_grid[lh_index - 1][rh_index])
puts cannot_move_crate_string
return
end
if @playing_Grid[lh_index - 1][rh_index] == @storage_id
crate_onto_storage_string
crate_onto_square([lh_index, rh_index], [lh_index - 1, rh_index], @storage_id)
end
end
elsif future_pos == @wall_id
puts moving_into_wall_string
elsif future_pos == @storage_id
future_pos = @workman_on_storage_id
end
if current_pos == @workman_on_storage_id
current_pos = @storage_id
else
current_pos = @floor_id
end
end
def crate_onto_square(crate_coords, square_coords, square_id)
case square_id
when @floor_id
crate_onto_floor(crate_coords, square_coords)
when @storage_id
crate_onto_storage(crate_coords, square_coords)
end
end
def crate_onto_storage(crate_coords, storage_coords)
@playing_grid[storage_coords[0], storage_coords[1]] = @crate_on_storage_id
@playing_grid[crate_coords[0], crate_coords[1]] = @floor_id
end
def tick
puts "Tick!"
end
def play
puts "Welcome to Sokoban! The aim of the game is to put all of the crates, which are the \'" + @crate_id + "\' symbols onto the storage pallets, which are the \'" + @storage_id + "\' symbols! A list of all the symbols is available if you type \"help\", and the status of the game is available if you type \"status\"."
status()
loop do
input = gets.chomp()
case input.downcase!
when "help"
help()
when "move"
puts "Move where?"
input = gets.chomp()
@move_coords = @workman.move(input)
handle_move(@move_coords)
when "status"
status()
end
tick()
end
end
def help
puts "The symbols are as follows:"
pp symbols
end
end
class Man
attr_accessor :id, :coordinates
def initialize(coords)
@coordinates = coords
@id = "@"
end
def move(direction) #Returns what the new coords would be, Sokoban.handle_move then checks if these are valid
case direction.downcase!
when "up"
move_up()
when "down"
move_down()
when "right"
move_right()
when "left"
move_left()
end
end
#The third entry in these return values are whether the man moved up, down, right or left for the Sokoban.handle_move
def move_up()
[@coordinates.first - 1, @coordinates.last, "up"]
end
def move_down()
[@coordinates.first + 1, @coordinates.last, "down"]
end
def move_right()
[@coordinates.first, @coordinates.last + 1, "right"]
end
def move_left()
[@coordinates.first, @coordinates.last - 1, "left"]
end
end
sok = Sokoban.new()
#pp sok.playing_grid
sok.play()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment