Class: RSokoban::Level

Inherits:
Object
  • Object
show all
Defined in:
lib/rsokoban/level.rb

Overview

I am a level of the game.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(raw_level) ⇒ Level

I build the level from a RawLevel object.

Parameters:

  • raw_level (RawLevel)

    A RawLevel object, containing a title and a map.



19
20
21
22
23
24
25
26
27
# File 'lib/rsokoban/level.rb', line 19

def initialize raw_level
	@title = raw_level.title
	@width = raw_level.map.width
	@height = raw_level.map.height
	@layered_map = LayeredMap.new raw_level.map
	@move = 0
	@map = nil
	@move_recorder = MoveRecorder.new
end

Instance Attribute Details

#heightFixnum (readonly)

Get map height of this level, in cells

Returns:

  • (Fixnum)


13
14
15
# File 'lib/rsokoban/level.rb', line 13

def height
  @height
end

#numberObject

Returns the value of attribute number.



15
16
17
# File 'lib/rsokoban/level.rb', line 15

def number
  @number
end

#titleObject (readonly)

Returns the value of attribute title.



5
6
7
# File 'lib/rsokoban/level.rb', line 5

def title
  @title
end

#widthFixnum (readonly)

Get map width of this level, in cells

Returns:

  • (Fixnum)


9
10
11
# File 'lib/rsokoban/level.rb', line 9

def width
  @width
end

Instance Method Details

#==(obj) ⇒ false|true

Two Level objects are equals if their @title, @floor, @layered_map.man, @layered_map.crates and @layered_map.storages are equals.

Parameters:

  • obj (Object)

Returns:

  • (false|true)


61
62
63
64
# File 'lib/rsokoban/level.rb', line 61

def ==(obj)
	return false unless obj.kind_of?(Level)
	@layered_map.floor == obj.floor and @layered_map.man == obj.man and @layered_map.crates == obj.crates and @layered_map.storages == obj.storages and @title == obj.title
end

#cratesObject



54
55
56
# File 'lib/rsokoban/level.rb', line 54

def crates
	@layered_map.crates
end

#eql?(obj) ⇒ Boolean

Synonym of #==

Returns:

  • (Boolean)

See Also:



68
69
70
# File 'lib/rsokoban/level.rb', line 68

def eql?(obj)
	self == obj
end

#floorObject



46
47
48
# File 'lib/rsokoban/level.rb', line 46

def floor
	@layered_map.floor
end

#manObject



50
51
52
# File 'lib/rsokoban/level.rb', line 50

def man
	@layered_map.man
end

#map_as_arrayMap

Get an instant map of the game.

Returns:

  • (Map)

    the map, after X turns of game.



74
75
76
# File 'lib/rsokoban/level.rb', line 74

def map_as_array
	@layered_map.map_as_array
end

#move(direction) ⇒ MoveResult

Move the man one box direction.

Parameters:

  • direction (:up|:down|:right|:left)

Returns:



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/rsokoban/level.rb', line 81

def move direction
	return MoveResult.new(:status => :error, :message => 'wall') if wall?(direction)
	return MoveResult.new(:status => :error, :message => 'wall behind crate') if wall_behind_crate?(direction)
	return MoveResult.new(:status => :error, :message => 'double crate') if double_crate?(direction)
	@move += 1
	@layered_map.man.send(direction)
	if @layered_map.crates.include?(Crate.new(@layered_map.man.x, @layered_map.man.y))
		idx = @layered_map.crates.index(Crate.new(@layered_map.man.x, @layered_map.man.y))
		@layered_map.crates[idx].send(direction)
		@move_recorder.record direction, :push
	else
		@move_recorder.record direction
	end
	
	return MoveResult.new(:status => :win, :move_number => @move) if win?
	MoveResult.new(:status => :ok, :move_number => @move)
end

#move_numberFixnum

Get current move number

Returns:

  • (Fixnum)

Since:

  • 0.74



156
157
158
# File 'lib/rsokoban/level.rb', line 156

def move_number
	@move
end

#recordObject



38
39
40
# File 'lib/rsokoban/level.rb', line 38

def record
	@record.record_of_level @number
end

#redoObject

Redo the last undo

Since:

  • 0.74



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/rsokoban/level.rb', line 101

def redo
	begin
		case @move_recorder.redo
			when :up, :UP then direction = :up
			when :down, :DOWN then direction = :down
			when :left, :LEFT then direction = :left
			when :right, :RIGHT then direction = :right
		end
		@layered_map.man.send(direction)
		@move += 1
		if @layered_map.crates.include?(Crate.new(@layered_map.man.x, @layered_map.man.y))
			idx = @layered_map.crates.index(Crate.new(@layered_map.man.x, @layered_map.man.y))
			@layered_map.crates[idx].send(direction)
		end
	rescue EmptyRedoError
		# Nothing to do
	end
	MoveResult.new(:status => :ok, :move_number => @move)
end

#set_filename=(filename) ⇒ Object



29
30
31
32
33
34
35
36
# File 'lib/rsokoban/level.rb', line 29

def set_filename= filename
	begin
		full_path = File.join(RECORD_FOLDER, filename + '.yaml')
		@record = Record.load_file full_path
	rescue ArgumentError => e
		@record = Record.create full_path
	end
end

#storagesObject



42
43
44
# File 'lib/rsokoban/level.rb', line 42

def storages
	@layered_map.storages
end

#undoObject

Undo last move



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/rsokoban/level.rb', line 122

def undo
	begin
		case @move_recorder.undo
			when :up then @layered_map.man.down
			when :down then @layered_map.man.up
			when :left then @layered_map.man.right
			when :right then @layered_map.man.left
			when :UP
				idx = @layered_map.crates.index(Crate.new(@layered_map.man.x, @layered_map.man.y-1))
				@layered_map.crates[idx].down
				@layered_map.man.down
			when :DOWN
				idx = @layered_map.crates.index(Crate.new(@layered_map.man.x, @layered_map.man.y+1))
				@layered_map.crates[idx].up
				@layered_map.man.up
			when :LEFT
				idx = @layered_map.crates.index(Crate.new(@layered_map.man.x-1, @layered_map.man.y))
				@layered_map.crates[idx].right
				@layered_map.man.right
			when :RIGHT
				idx = @layered_map.crates.index(Crate.new(@layered_map.man.x+1, @layered_map.man.y))
				@layered_map.crates[idx].left
				@layered_map.man.left
		end
		@move -= 1
	rescue EmptyMoveQueueError
		# Nothing to do
	end
	MoveResult.new(:status => :ok, :move_number => @move)
end

#update_recordObject

Since:

  • 0.76



161
162
163
# File 'lib/rsokoban/level.rb', line 161

def update_record
	@record.add @number, @move
end