Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[bin/crypt] walking in a direction without an exit

  • Loading branch information...
commit 6dc36736bfbefda2ad41e09f035ba1d4926d42cb 1 parent 4b468fb
Carl Mäsak authored

Showing 1 changed file with 67 additions and 12 deletions. Show diff stats Hide diff stats

  1. 79  bin/crypt
79  bin/crypt
@@ -228,6 +228,10 @@ class Hanoi::Game {
228 228
     }
229 229
 }
230 230
 
  231
+class Adventure::PlayerWalked does Event {
  232
+    has $.to;
  233
+}
  234
+
231 235
 class Adventure::TwoRoomsConnected does Event {
232 236
     has @.rooms;
233 237
     has $.direction;
@@ -237,11 +241,18 @@ class X::Adventure is Exception {
237 241
 }
238 242
 
239 243
 class X::Adventure::NoSuchDirection is X::Adventure {
240  
-    has $.action;
241 244
     has $.direction;
242 245
 
243 246
     method message {
244  
-        "Cannot $.action because direction '$.direction' does not exist"
  247
+        "Cannot connect rooms because direction '$.direction' does not exist"
  248
+    }
  249
+}
  250
+
  251
+class X::Adventure::NoExitThere is X::Adventure {
  252
+    has $.direction;
  253
+
  254
+    method message {
  255
+        "Cannot walk $.direction because there is no exit there"
245 256
     }
246 257
 }
247 258
 
@@ -251,11 +262,36 @@ class Adventure::Engine {
251 262
         northeast northwest southeast southwest
252 263
     >;
253 264
 
  265
+    has $!player_location = 'clearing';
  266
+    has %!exits;
  267
+
254 268
     method connect(@rooms, $direction) {
255 269
         die X::Adventure::NoSuchDirection.new(:action('connect rooms'), :$direction)
256 270
             unless $direction eq any(@possible_directions);
257 271
 
258  
-        Adventure::TwoRoomsConnected.new(:@rooms, :$direction);
  272
+        my @events = Adventure::TwoRoomsConnected.new(:@rooms, :$direction);
  273
+        self!apply($_) for @events;
  274
+        @events;
  275
+    }
  276
+
  277
+    method walk($direction) {
  278
+        my $to = %!exits{$!player_location}{$direction};
  279
+
  280
+        die X::Adventure::NoExitThere.new(:$direction)
  281
+            unless defined $to;
  282
+
  283
+        my @events = Adventure::PlayerWalked.new(:$to);
  284
+        self!apply($_) for @events;
  285
+        @events;
  286
+    }
  287
+
  288
+    # RAKUDO: private multimethods NYI
  289
+    method !apply(Event $_) {
  290
+        when Adventure::TwoRoomsConnected {
  291
+            my ($room1, $room2) = .rooms.list;
  292
+            my $direction = .direction;
  293
+            %!exits{$room1}{$direction} = $room2;
  294
+        }
259 295
     }
260 296
 }
261 297
 
@@ -264,17 +300,22 @@ class Crypt::PlayerLooked does Event {
264 300
     has $.description_of;
265 301
 }
266 302
 
267  
-class Crypt::PlayerWalked does Event {
268  
-    has $.to;
  303
+class X::Crypt is Exception {
269 304
 }
270 305
 
271 306
 class Crypt::Game {
272  
-    method look() {
273  
-        Crypt::PlayerLooked.new(:target<room>, :description_of<clearing>);
  307
+    has $!engine handles <walk>;
  308
+
  309
+    submethod BUILD() {
  310
+        $!engine = Adventure::Engine.new();
  311
+
  312
+        given $!engine {
  313
+            .connect(<clearing hill>, 'east');
  314
+        }
274 315
     }
275 316
 
276  
-    method walk($direction) {
277  
-        Crypt::PlayerWalked.new(:to<hill>);
  317
+    method look() {
  318
+        Crypt::PlayerLooked.new(:target<room>, :description_of<clearing>);
278 319
     }
279 320
 }
280 321
 
@@ -484,7 +525,6 @@ multi MAIN('test') {
484 525
             X::Adventure::NoSuchDirection,
485 526
             'connecting two rooms (-) no such direction',
486 527
             {
487  
-                is .action, 'connect rooms', '.action attribute';
488 528
                 is .direction, $direction, '.direction attribute';
489 529
                 is .message,
490 530
                     "Cannot connect rooms because direction "
@@ -497,10 +537,25 @@ multi MAIN('test') {
497 537
         my $game = Crypt::Game.new();
498 538
 
499 539
         is $game.walk('east'),
500  
-            Crypt::PlayerWalked.new(
  540
+            Adventure::PlayerWalked.new(
501 541
                 :to<hill>,
502 542
             ),
503  
-            'walking east to the hill';
  543
+            'walking (+)';
  544
+    }
  545
+
  546
+    {
  547
+        my $game = Crypt::Game.new();
  548
+
  549
+        throws_exception
  550
+            { $game.walk('south') },
  551
+            X::Adventure::NoExitThere,
  552
+            'walking (-) in a direction without an exit',
  553
+            {
  554
+                is .direction, 'south', '.direction attribute';
  555
+                is .message,
  556
+                    "Cannot walk south because there is no exit there",
  557
+                    '.message attribute';
  558
+            };
504 559
     }
505 560
 
506 561
     done;

0 notes on commit 6dc3673

Please sign in to comment.
Something went wrong with that request. Please try again.