RSokoban 0.74 → 0.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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