RSokoban 0.74 → 0.76

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. data/NEWS +33 -1
  2. data/README.rdoc +21 -14
  3. data/TODO +6 -12
  4. data/VERSION +1 -1
  5. data/bin/rsokoban +40 -3
  6. data/data/big.xsb +35 -0
  7. data/lib/rsokoban/config.rb +34 -0
  8. data/lib/rsokoban/crate.rb +4 -5
  9. data/lib/rsokoban/exception.rb +2 -0
  10. data/lib/rsokoban/game/game.rb +153 -0
  11. data/lib/rsokoban/game/game_curses.rb +11 -0
  12. data/lib/rsokoban/game/game_factory.rb +23 -0
  13. data/lib/rsokoban/game/game_gui.rb +27 -0
  14. data/lib/rsokoban/game/game_portable.rb +10 -0
  15. data/lib/rsokoban/game/game_tk.rb +11 -0
  16. data/lib/rsokoban/game/game_ui.rb +81 -0
  17. data/lib/rsokoban/game.rb +7 -238
  18. data/lib/rsokoban/install.rb +22 -0
  19. data/lib/rsokoban/layered_map.rb +139 -0
  20. data/lib/rsokoban/level.rb +112 -166
  21. data/lib/rsokoban/level_set.rb +4 -4
  22. data/lib/rsokoban/man.rb +3 -4
  23. data/lib/rsokoban/map.rb +91 -15
  24. data/lib/rsokoban/move_result.rb +2 -2
  25. data/lib/rsokoban/option.rb +4 -4
  26. data/lib/rsokoban/position.rb +1 -1
  27. data/lib/rsokoban/raw_level.rb +11 -2
  28. data/lib/rsokoban/record.rb +51 -0
  29. data/lib/rsokoban/set_loader.rb +108 -0
  30. data/lib/rsokoban/ui/base_ui.rb +1 -0
  31. data/lib/rsokoban/ui/console.rb +56 -25
  32. data/lib/rsokoban/ui/curses_console.rb +59 -33
  33. data/lib/rsokoban/ui/player_action.rb +13 -7
  34. data/lib/rsokoban/ui/skin.rb +105 -0
  35. data/lib/rsokoban/ui/tk_dialogs.rb +104 -18
  36. data/lib/rsokoban/ui/tk_ui.rb +410 -233
  37. data/lib/rsokoban/ui.rb +1 -0
  38. data/lib/rsokoban.rb +14 -2
  39. data/skins/AntiqueDesk/crate.bmp +0 -0
  40. data/skins/AntiqueDesk/crate_store.bmp +0 -0
  41. data/skins/AntiqueDesk/floor.bmp +0 -0
  42. data/skins/AntiqueDesk/man_down.bmp +0 -0
  43. data/skins/AntiqueDesk/man_left.bmp +0 -0
  44. data/skins/AntiqueDesk/man_right.bmp +0 -0
  45. data/skins/AntiqueDesk/man_store_down.bmp +0 -0
  46. data/skins/AntiqueDesk/man_store_left.bmp +0 -0
  47. data/skins/AntiqueDesk/man_store_right.bmp +0 -0
  48. data/skins/AntiqueDesk/man_store_up.bmp +0 -0
  49. data/skins/AntiqueDesk/man_up.bmp +0 -0
  50. data/skins/AntiqueDesk/outside.bmp +0 -0
  51. data/skins/AntiqueDesk/skin.conf +3 -0
  52. data/skins/AntiqueDesk/store.bmp +0 -0
  53. data/skins/AntiqueDesk/wall.bmp +0 -0
  54. data/skins/BlueGranite/outside.bmp +0 -0
  55. data/skins/BlueGranite/skin.conf +3 -0
  56. data/skins/HeavyMetal/crate.bmp +0 -0
  57. data/skins/HeavyMetal/crate_store.bmp +0 -0
  58. data/skins/HeavyMetal/floor.bmp +0 -0
  59. data/skins/HeavyMetal/man.bmp +0 -0
  60. data/skins/HeavyMetal/man_store.bmp +0 -0
  61. data/skins/HeavyMetal/outside.bmp +0 -0
  62. data/skins/HeavyMetal/skin.conf +3 -0
  63. data/skins/HeavyMetal/store.bmp +0 -0
  64. data/skins/HeavyMetal/wall.bmp +0 -0
  65. data/skins/HeavyMetal/wall_d.bmp +0 -0
  66. data/skins/HeavyMetal/wall_dl.bmp +0 -0
  67. data/skins/HeavyMetal/wall_dlr.bmp +0 -0
  68. data/skins/HeavyMetal/wall_dr.bmp +0 -0
  69. data/skins/HeavyMetal/wall_l.bmp +0 -0
  70. data/skins/HeavyMetal/wall_lr.bmp +0 -0
  71. data/skins/HeavyMetal/wall_r.bmp +0 -0
  72. data/skins/HeavyMetal/wall_u.bmp +0 -0
  73. data/skins/HeavyMetal/wall_ud.bmp +0 -0
  74. data/skins/HeavyMetal/wall_udl.bmp +0 -0
  75. data/skins/HeavyMetal/wall_udlr.bmp +0 -0
  76. data/skins/HeavyMetal/wall_udr.bmp +0 -0
  77. data/skins/HeavyMetal/wall_ul.bmp +0 -0
  78. data/skins/HeavyMetal/wall_ulr.bmp +0 -0
  79. data/skins/HeavyMetal/wall_ur.bmp +0 -0
  80. data/test/record/original.yaml +2 -0
  81. data/test/tc_game.rb +24 -15
  82. data/test/tc_game_factory.rb +40 -0
  83. data/test/tc_game_gui.rb +26 -0
  84. data/test/tc_game_ui.rb +153 -0
  85. data/test/tc_install.rb +12 -0
  86. data/test/tc_layered_map.rb +105 -0
  87. data/test/tc_level.rb +109 -107
  88. data/test/tc_level_set.rb +4 -4
  89. data/test/tc_map.rb +46 -10
  90. data/test/tc_record.rb +100 -0
  91. data/test/{tc_level_loader.rb → tc_set_loader.rb} +25 -24
  92. data/test/test.rb +9 -2
  93. data/test/ui/tc_skin.rb +71 -0
  94. metadata +89 -26
  95. data/lib/rsokoban/level_loader.rb +0 -81
  96. data/lib/rsokoban/ui/tk_box.rb +0 -21
  97. data/skins/default/outside.bmp +0 -0
  98. data/skins/default/readme +0 -1
  99. /data/skins/{default → BlueGranite}/crate.bmp +0 -0
  100. /data/skins/{default → BlueGranite}/crate_store.bmp +0 -0
  101. /data/skins/{default → BlueGranite}/floor.bmp +0 -0
  102. /data/skins/{default → BlueGranite}/man_down.bmp +0 -0
  103. /data/skins/{default → BlueGranite}/man_left.bmp +0 -0
  104. /data/skins/{default → BlueGranite}/man_right.bmp +0 -0
  105. /data/skins/{default → BlueGranite}/man_store_down.bmp +0 -0
  106. /data/skins/{default → BlueGranite}/man_store_left.bmp +0 -0
  107. /data/skins/{default → BlueGranite}/man_store_right.bmp +0 -0
  108. /data/skins/{default → BlueGranite}/man_store_up.bmp +0 -0
  109. /data/skins/{default → BlueGranite}/man_up.bmp +0 -0
  110. /data/skins/{default → BlueGranite}/store.bmp +0 -0
  111. /data/skins/{default → BlueGranite}/wall.bmp +0 -0
data/NEWS CHANGED
@@ -1,6 +1,38 @@
1
+ version 0.76 2011-02-21
2
+
3
+ * All UIs
4
+ + save/display score
5
+ + program opens on the last played level
6
+
7
+ * Tk GUI
8
+ + you can change the skin
9
+ + 3 skins shipped with the software
10
+ + you can add your own skins
11
+ + skins are of any size
12
+ + better integration of Tk (new dependence: tk-tile library)
13
+
14
+
15
+ version 0.75.1 2011-02-12
16
+
17
+ * Tk GUI
18
+ + unlimited map size
19
+ + auto scrolling
20
+ + user scrolling
21
+ + window size follows map size
22
+
23
+ * fix
24
+ + bug#3
25
+ + bug#9
26
+
27
+
28
+ version 0.74.1 2011-02-09
29
+
30
+ * Tk GUI: nicer background
31
+
32
+
1
33
  version 0.74 2011-01-31
2
34
 
3
- * New: redo feature (only available with Tk GUI)
35
+ * New: redo feature (only available with Tk GUI)
4
36
 
5
37
  * Tk GUI
6
38
  + add a 'next level' feature
data/README.rdoc CHANGED
@@ -1,33 +1,42 @@
1
1
  = Welcome to RSokoban !
2
2
 
3
3
  RSokoban is a clone of the famous {Sokoban}[http://en.wikipedia.org/wiki/Sokoban] game.
4
- I wrote this program just to improve my skills in Ruby.
4
+ I wrote this program just to improve my skills in Ruby with GUI.
5
5
 
6
6
  *Features*
7
7
  * Graphical user interface with Tk
8
- * Two console user interfaces (curses and straight text mode)
8
+ * Skinning
9
9
  * 200+ levels
10
10
  * Undo/redo
11
11
  * Use xsb file format to load sets of levels
12
+ * Additional console user interfaces (curses and straight text mode)
12
13
 
13
14
  Enjoy the game.
14
15
 
15
16
 
16
17
  == Documentation
17
18
 
18
- Players can look at {the wiki}[https://github.com/lkdjiin/RSokoban/wiki].
19
+ Look at {the wiki}[https://github.com/lkdjiin/RSokoban/wiki].
19
20
 
20
- Developpers can look at Level, Game and TkUI.
21
21
 
22
+ == Installing
22
23
 
23
- == Dependancies
24
+ === Installing dependencies
24
25
 
25
- Ruby >= 1.8.7
26
+ You need Ruby >= 1.8.7
26
27
 
28
+ To play with the graphical user interface you need to be sre that the following
29
+ packages are installed on your system:
27
30
 
28
- == Installing RSokoban
31
+ * libtcltk-ruby
32
+ * libtk-img
33
+ * tk-tile
29
34
 
30
- *First method*
35
+
36
+ === Installing RSokoban
37
+
38
+ <b>First method, install from the sources</b>
39
+ This is the method I recommend.
31
40
  To install RSokoban from the source, go to the RSokoban folder and build the gem:
32
41
 
33
42
  gem build rsokoban.gemspec
@@ -45,17 +54,15 @@ If you prefer using rake to build and install:
45
54
  rake build
46
55
  rake install
47
56
 
48
- *Second method*
57
+ <b>Second method</b>
49
58
  Or install via RubyGem in one command (you need ruby 1.9 or higher).
50
- Note that I don't certify you will get the latest release:
59
+ <em>Note that I don't certify you will get the latest release</em>:
51
60
 
52
61
  gem install RSokoban
53
62
 
54
- *Third method*
55
- Or you can play without installing it. Go to the RSokoban/bin folder and type:
56
-
57
- ./rsokoban
63
+ == Licence
58
64
 
65
+ GPLv3
59
66
 
60
67
  == Questions and/or Comments
61
68
 
data/TODO CHANGED
@@ -1,18 +1,12 @@
1
- * tk: use one image for rendering, not an array (if possible ?)
2
- * don't restrict map size
1
+
2
+ -------------------------------------------------------
3
+ Think about:
3
4
  * gnome GUI (gtk only to be windows compatible ?)
4
5
  * give a try to rubygame ?
5
- * skining
6
- + load skin
7
- + several size of tiles or resizing ?)
8
- * Console UI should provide a way to know names of sets
9
- * save a game
10
- * reload a saved game
11
- * multi player support
12
- * save score
13
- * scoring moves and pushes
14
- * level preview
6
+ * scoring moves and pushes ?
7
+ * level preview ?
15
8
  * solver (plugin ?)
9
+ * zoom ?
16
10
  * format fichier niveau xml (.slc)
17
11
  * other GUI(s) ?
18
12
  * mouse support
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.74
1
+ 0.76
data/bin/rsokoban CHANGED
@@ -24,10 +24,21 @@ $RSOKOBAN_DATA_PATH = File.expand_path(File.dirname(__FILE__) + '/../data')
24
24
 
25
25
  require 'rsokoban'
26
26
 
27
+ unless File.exist? File.join(RSokoban::CONFIG_FOLDER, RSokoban::CONFIG_FILE)
28
+ RSokoban::Install.create_config RSokoban::CONFIG_FOLDER
29
+ end
30
+
31
+ unless File.exist? RSokoban::RECORD_FOLDER
32
+ RSokoban::Install.create_folder RSokoban::RECORD_FOLDER
33
+ end
34
+
27
35
  tk_failed=<<EOS
28
36
  Sorry, failed to load tk or tkimg library.
29
- Please, be sure that libtcltk-ruby and libtk-img are correctly installed on
30
- your system.
37
+ Please, be sure that:
38
+ libtcltk-ruby
39
+ libtk-img
40
+ tk-tile
41
+ are correctly installed on your system.
31
42
  Now trying to start with curses library:
32
43
  rsokoban --curses
33
44
 
@@ -51,6 +62,7 @@ if option[:ui] == :tk
51
62
  begin
52
63
  require 'tk'
53
64
  require 'tkextlib/tkimg'
65
+ require 'tkextlib/tile'
54
66
  rescue LoadError => e
55
67
  puts tk_failed
56
68
  option.interface = :curses
@@ -68,5 +80,30 @@ if option[:ui] == :curses
68
80
  end
69
81
  end
70
82
 
71
- game = RSokoban::Game.new option[:ui]
83
+ # Find last set
84
+ conf = RSokoban::Config.new
85
+ last_set = conf['set']
86
+ conf = nil # to be GCed ?
87
+
88
+ case option[:ui]
89
+ when :curses
90
+ require "rsokoban/ui/curses_console"
91
+ ui = RSokoban::UI::CursesConsole.new
92
+ game = RSokoban::GameFactory.create RSokoban::GameCurses, ui, last_set
93
+ when :portable
94
+ require "rsokoban/ui/console"
95
+ ui = RSokoban::UI::Console.new
96
+ game = RSokoban::GameFactory.create RSokoban::GamePortable, ui, last_set
97
+ when :tk
98
+ require "rsokoban/ui/tk_ui"
99
+ require "rsokoban/ui/tk_dialogs"
100
+ game = RSokoban::GameFactory.create RSokoban::GameTk, 'fake ui', last_set
101
+ game.ui = RSokoban::UI::TkUI.new(game)
102
+ end
103
+
104
+ at_exit do
105
+ conf = RSokoban::Config.new
106
+ conf.save_set_and_level game.set_name, game.level_number
107
+ end
108
+
72
109
  game.run
data/data/big.xsb ADDED
@@ -0,0 +1,35 @@
1
+ ; Big maps test file
2
+
3
+ ; Some big maps without interests except for testing purposes.
4
+
5
+ ##############################
6
+ # #
7
+ # #
8
+ # #
9
+ # @ .. #
10
+ # #
11
+ # $ #
12
+ # #
13
+ # #
14
+ # #
15
+ # #
16
+ # #
17
+ # #
18
+ # #
19
+ # #
20
+ # #
21
+ # #
22
+ # #
23
+ # #
24
+ # #
25
+ # #
26
+ # #
27
+ # #
28
+ # #
29
+ # $ #
30
+ # #
31
+ # #
32
+ # #
33
+ # #
34
+ ##############################
35
+ ; 30x30 square
@@ -0,0 +1,34 @@
1
+ module RSokoban
2
+
3
+ class Config
4
+
5
+ def initialize
6
+ @conf = YAML.load_file File.join(CONFIG_FOLDER, CONFIG_FILE)
7
+ end
8
+
9
+ def [](key)
10
+ @conf[key]
11
+ end
12
+
13
+ def []= (key, value)
14
+ @conf[key] = value
15
+ write_config
16
+ end
17
+
18
+ def save_set_and_level setname, level_number
19
+ @conf['set'] = setname
20
+ @conf['level'] = level_number
21
+ write_config
22
+ end
23
+
24
+ private
25
+
26
+ def write_config
27
+ f = File.new(File.join(CONFIG_FOLDER, CONFIG_FILE), "w")
28
+ f.write @conf.to_yaml
29
+ f.close
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -2,14 +2,13 @@ require "rsokoban/moveable"
2
2
 
3
3
  module RSokoban
4
4
 
5
- # I am a moveable crate.
5
+ # I am a positionable, moveable crate.
6
6
  class Crate < Position
7
7
  include RSokoban::Moveable
8
8
 
9
- # @param [Fixnum] x la coordonnée x
10
- # @param [Fixnum] y la coordonnée y
11
- def initialize x, y
12
- super(x, y)
9
+ # Coordinates must be Fixnum
10
+ def initialize x_coord, y_coord
11
+ super(x_coord, y_coord)
13
12
  end
14
13
  end
15
14
 
@@ -1,7 +1,9 @@
1
1
  module RSokoban
2
+ # Used when we try to load a file that doesn't exist.
2
3
  class NoFileError < ArgumentError
3
4
  end
4
5
 
6
+ # Used when we try to load a level (from a set of levels) that is out of limit.
5
7
  class LevelNumberTooHighError < ArgumentError
6
8
  end
7
9
 
@@ -0,0 +1,153 @@
1
+ module RSokoban
2
+
3
+ # I provide the basic API to run a game.
4
+ # I am user interface agnostic.
5
+ # @since 0.74.1
6
+ module Game
7
+ # @return [Fixnum]
8
+ attr_reader :level_number, :set_name
9
+
10
+ # Construct a new game that you can later run.
11
+ # @param [UI] the user interface associated to this game
12
+ # @param [String] setname The set of levels to begin with
13
+ def initialize ui, setname = 'microban.xsb'
14
+ @set_name = setname
15
+ @level_loader = SetLoader.new setname
16
+ conf = Config.new
17
+ @level_number = conf['level']
18
+ @ui = ui
19
+ end
20
+
21
+ # Start the game loop.
22
+ # @note You must override me in a concrete class.
23
+ def run
24
+ raise NotImplementedError
25
+ end
26
+
27
+ # @return [Fixnum]
28
+ def level_width
29
+ @level.width
30
+ end
31
+
32
+ # @return [Fixnum]
33
+ def level_height
34
+ @level.height
35
+ end
36
+
37
+ # @return [String]
38
+ def level_title
39
+ @level.title
40
+ end
41
+
42
+ # Get current map of the game as an array of strings
43
+ # @return [Array<String>]
44
+ def map_as_array
45
+ @level.map_as_array
46
+ end
47
+
48
+ # Get x coordinate of the man
49
+ # @return [Fixnum]
50
+ def man_x
51
+ @level.man.x
52
+ end
53
+
54
+ # Get y coordinate of the man
55
+ # @return [Fixnum]
56
+ def man_y
57
+ @level.man.y
58
+ end
59
+
60
+ # Get result of the move
61
+ # @param [:up|:down|:right|:left] direction
62
+ # @return [Object]
63
+ def move direction
64
+ @level.move direction
65
+ end
66
+
67
+ # Get current move number
68
+ # @return [Fixnum]
69
+ def move_number
70
+ @level.move_number
71
+ end
72
+
73
+ # Get result of undo last move
74
+ # @return [MoveResult]
75
+ def undo
76
+ @level.undo
77
+ end
78
+
79
+ # Get result of redo last undone move
80
+ # @return [MoveResult]
81
+ def redo
82
+ @level.redo
83
+ end
84
+
85
+ # Get title of the current set
86
+ # @return [String]
87
+ def set_title
88
+ @level_loader.title
89
+ end
90
+
91
+ # Get numbers of level from the current set
92
+ # @return [Fixnum]
93
+ def set_size
94
+ @level_loader.size
95
+ end
96
+
97
+ # @note You must override me.
98
+ def start_level
99
+ raise NotImplementedError
100
+ end
101
+
102
+ # Load and start the next level of the set
103
+ # @return See the implementation of start_level in a descendant module (GameUI or GameGUI).
104
+ def next_level
105
+ @level_number += 1
106
+ start_level
107
+ end
108
+
109
+ # Load a level from the current set.
110
+ # @param [Fixnum] num the number of the set (base 1)
111
+ # @return See the implementation of start_level in a descendant module (GameUI or GameGUI).
112
+ def load_level num
113
+ @level_number = num
114
+ start_level
115
+ end
116
+
117
+ # Restart current set from level 1.
118
+ # @return See the implementation of start_level in a descendant module (GameUI or GameGUI).
119
+ def restart_set
120
+ @level_number = 1
121
+ start_level
122
+ end
123
+
124
+ # Load a new set of levels and start its first level.
125
+ # @param [String] setname the name of the set (with .xsb extension)
126
+ def load_a_new_set setname
127
+ @set_name = setname
128
+ @level_loader = SetLoader.new setname
129
+ @level_number = 1
130
+ @level = @level_loader.level(@level_number)
131
+ end
132
+
133
+ # Get record for current level (in # of moves)
134
+ # @since 0.76
135
+ def record
136
+ @level.record
137
+ end
138
+
139
+ # Update record if needed.
140
+ # @return true if old record is beaten.
141
+ # @since 0.76
142
+ def update_record
143
+ if record.nil? or move_number < record
144
+ @level.update_record
145
+ true
146
+ else
147
+ false
148
+ end
149
+ end
150
+
151
+ end
152
+
153
+ end
@@ -0,0 +1,11 @@
1
+ module RSokoban
2
+
3
+ # I am a game to run in a window with the curses library
4
+ # @since 0.74.1
5
+ class GameCurses
6
+ include GameUI
7
+
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,23 @@
1
+ module RSokoban
2
+
3
+ # @since 0.74.1
4
+ module GameFactory
5
+
6
+ # @param [GamePortable|GameCurses|GameTk] a_class
7
+ # @param [UI] ui associated user interface
8
+ # @param [String] level_set set to start playing with
9
+ def self.create a_class, ui, level_set = 'microban.xsb'
10
+ if GamePortable == a_class
11
+ GamePortable.new(ui, level_set)
12
+ elsif GameCurses == a_class
13
+ GameCurses.new(ui, level_set)
14
+ elsif GameTk == a_class
15
+ GameTk.new(ui, level_set)
16
+ else
17
+ raise ArgumentError
18
+ end
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,27 @@
1
+ module RSokoban
2
+
3
+ # I extends/implements the API of module Game, to run the game
4
+ # within a GUI. I don't define the user interface, you can use me
5
+ # to run game with Tk, Gnome, etc.
6
+ # @since 0.74.1
7
+ module GameGUI
8
+ include Game
9
+
10
+ attr_writer :ui
11
+
12
+ def initialize ui, setname = 'microban.xsb'
13
+ super(ui, setname)
14
+ end
15
+
16
+ def run
17
+ @ui.run
18
+ end
19
+
20
+ def start_level
21
+ @level = @level_loader.level(@level_number)
22
+ nil
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,10 @@
1
+ module RSokoban
2
+
3
+ # I am a game to run in a straight console window
4
+ # @since 0.74.1
5
+ class GamePortable
6
+ include GameUI
7
+
8
+ end
9
+
10
+ end
@@ -0,0 +1,11 @@
1
+ module RSokoban
2
+
3
+ # I am a game to run with the Tk library
4
+ # @since 0.74.1
5
+ class GameTk
6
+ include GameGUI
7
+
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,81 @@
1
+ module RSokoban
2
+
3
+ # I extends/implements the API of module Game, to run the game
4
+ # in a console window. I don't define the user interface, you can use me
5
+ # to run game with curses, n-curses, straight text-mode, etc.
6
+ # @since 0.74.1
7
+ module GameUI
8
+ include Game
9
+
10
+ def initialize ui, setname = 'microban.xsb'
11
+ super(ui, setname)
12
+ end
13
+
14
+ # I am the game loop for UIs.
15
+ def run
16
+ player_action = start_level
17
+ loop do
18
+ if player_action.level_number?
19
+ player_action = load_level player_action.action
20
+ next
21
+ elsif player_action.set_name?
22
+ player_action = load_a_new_set player_action.action
23
+ next
24
+ elsif player_action.quit?
25
+ break
26
+ elsif player_action.next?
27
+ player_action = next_level
28
+ next
29
+ elsif player_action.retry?
30
+ player_action = start_level
31
+ next
32
+ elsif player_action.move?
33
+ result = @level.move(player_action.action)
34
+ elsif player_action.undo?
35
+ result = @level.undo
36
+ end
37
+
38
+ hash = {:map=>@level.map_as_array, :move=>result[:move_number]}
39
+ case result[:status]
40
+ when :win
41
+ update_record
42
+ player_action = @ui.get_action(hash.merge({:type=>:win}))
43
+ when :ok then player_action = @ui.get_action(hash.merge({:type=>:display}))
44
+ else
45
+ player_action = @ui.get_action(:type=>:display, :map=>@level.map_as_array, :error=>result[:message])
46
+ end
47
+
48
+ end
49
+ true
50
+ end
51
+
52
+ # @return [PlayerAction]
53
+ def start_level
54
+ begin
55
+ @level = @level_loader.level(@level_number)
56
+ @ui.get_action(get_hash_after_loading_set)
57
+ rescue LevelNumberTooHighError
58
+ @ui.get_action(:type=>:end_of_set, :map=>Map.new)
59
+ end
60
+ end
61
+
62
+ def load_a_new_set setname
63
+ begin
64
+ super(setname)
65
+ @ui.get_action(get_hash_after_loading_set)
66
+ rescue NoFileError
67
+ error = "Error, no such file : #{setname}"
68
+ @ui.get_action(get_hash_after_loading_set.merge({:error=>error}))
69
+ end
70
+ end
71
+
72
+ private
73
+
74
+ def get_hash_after_loading_set
75
+ {:type=>:start, :map=>@level.map_as_array, :title=>@level.title, :set=>@level_loader.title,
76
+ :number=>@level_number, :total=>@level_loader.size, :record => @level.record}
77
+ end
78
+
79
+ end
80
+
81
+ end