@@ -162,6 +162,7 @@ def rule_match(state, rules):
162
162
163
163
# ______________________________________________________________________________
164
164
165
+
165
166
loc_A , loc_B = (0 , 0 ), (1 , 0 ) # The two locations for the Vacuum world
166
167
167
168
@@ -394,8 +395,9 @@ def things_near(self, location, radius=None):
394
395
if radius is None :
395
396
radius = self .perceptible_distance
396
397
radius2 = radius * radius
397
- return [(thing , radius2 - distance_squared (location , thing .location )) for thing in self .things
398
- if distance_squared (location , thing .location ) <= radius2 ]
398
+ return [(thing , radius2 - distance_squared (location , thing .location ))
399
+ for thing in self .things if distance_squared (
400
+ location , thing .location ) <= radius2 ]
399
401
400
402
def percept (self , agent ):
401
403
"""By default, agent perceives things within a default radius."""
@@ -435,33 +437,28 @@ def move_to(self, thing, destination):
435
437
t .location = destination
436
438
return thing .bump
437
439
438
- # def add_thing(self, thing, location=(1, 1)):
439
- # super(XYEnvironment, self).add_thing(thing, location)
440
- # thing.holding = []
441
- # thing.held = None
442
- # for obs in self.observers:
443
- # obs.thing_added(thing)
444
-
445
440
def add_thing (self , thing , location = (1 , 1 ), exclude_duplicate_class_items = False ):
446
441
"""Adds things to the world. If (exclude_duplicate_class_items) then the item won't be
447
442
added if the location has at least one item of the same class."""
448
443
if (self .is_inbounds (location )):
449
444
if (exclude_duplicate_class_items and
450
- any (isinstance (t , thing .__class__ ) for t in self .list_things_at (location ))):
451
- return
445
+ any (isinstance (t , thing .__class__ ) for t in self .list_things_at (location ))):
446
+ return
452
447
super ().add_thing (thing , location )
453
448
454
449
def is_inbounds (self , location ):
455
450
"""Checks to make sure that the location is inbounds (within walls if we have walls)"""
456
- x ,y = location
451
+ x , y = location
457
452
return not (x < self .x_start or x >= self .x_end or y < self .y_start or y >= self .y_end )
458
453
459
454
def random_location_inbounds (self , exclude = None ):
460
455
"""Returns a random location that is inbounds (within walls if we have walls)"""
461
- location = (random .randint (self .x_start , self .x_end ), random .randint (self .y_start , self .y_end ))
456
+ location = (random .randint (self .x_start , self .x_end ),
457
+ random .randint (self .y_start , self .y_end ))
462
458
if exclude is not None :
463
459
while (location == exclude ):
464
- location = (random .randint (self .x_start , self .x_end ), random .randint (self .y_start , self .y_end ))
460
+ location = (random .randint (self .x_start , self .x_end ),
461
+ random .randint (self .y_start , self .y_end ))
465
462
return location
466
463
467
464
def delete_thing (self , thing ):
@@ -514,19 +511,21 @@ class Wall(Obstacle):
514
511
515
512
# ______________________________________________________________________________
516
513
514
+
517
515
try :
518
516
from ipythonblocks import BlockGrid
519
517
from IPython .display import HTML , display
520
518
from time import sleep
521
519
except :
522
520
pass
523
521
522
+
524
523
class GraphicEnvironment (XYEnvironment ):
525
524
def __init__ (self , width = 10 , height = 10 , boundary = True , color = {}, display = False ):
526
525
"""define all the usual XYEnvironment characteristics,
527
526
but initialise a BlockGrid for GUI too"""
528
527
super ().__init__ (width , height )
529
- self .grid = BlockGrid (width , height , fill = (200 ,200 ,200 ))
528
+ self .grid = BlockGrid (width , height , fill = (200 , 200 , 200 ))
530
529
if display :
531
530
self .grid .show ()
532
531
self .visible = True
@@ -535,11 +534,6 @@ def __init__(self, width=10, height=10, boundary=True, color={}, display=False):
535
534
self .bounded = boundary
536
535
self .colors = color
537
536
538
- #def list_things_at(self, location, tclass=Thing): # need to override because locations
539
- # """Return all things exactly at a given location."""
540
- # return [thing for thing in self.things
541
- # if thing.location == location and isinstance(thing, tclass)]
542
-
543
537
def get_world (self ):
544
538
"""Returns all the items in the world in a format
545
539
understandable by the ipythonblocks BlockGrid"""
@@ -589,34 +583,24 @@ def update(self, delay=1):
589
583
def reveal (self ):
590
584
"""display the BlockGrid for this world - the last thing to be added
591
585
at a location defines the location color"""
592
- #print("Grid={}".format(self.grid))
593
586
self .draw_world ()
594
- #if not self.visible == True:
595
- # self.grid.show()
596
587
self .grid .show ()
597
- self .visible == True
588
+ self .visible = True
598
589
599
590
def draw_world (self ):
600
591
self .grid [:] = (200 , 200 , 200 )
601
592
world = self .get_world ()
602
- #print("world {}".format(world))
603
593
for x in range (0 , len (world )):
604
594
for y in range (0 , len (world [x ])):
605
595
if len (world [x ][y ]):
606
596
self .grid [y , x ] = self .colors [world [x ][y ][- 1 ].__class__ .__name__ ]
607
- #print('location: ({}, {}) got color: {}'
608
- #.format(y, x, self.colors[world[x][y][-1].__class__.__name__]))
609
597
610
598
def conceal (self ):
611
599
"""hide the BlockGrid for this world"""
612
600
self .visible = False
613
601
display (HTML ('' ))
614
602
615
603
616
-
617
-
618
-
619
-
620
604
# ______________________________________________________________________________
621
605
# Continuous environment
622
606
@@ -733,21 +717,27 @@ def __eq__(self, rhs):
733
717
return rhs .__class__ == Gold
734
718
pass
735
719
720
+
736
721
class Bump (Thing ):
737
722
pass
738
723
724
+
739
725
class Glitter (Thing ):
740
726
pass
741
727
728
+
742
729
class Pit (Thing ):
743
730
pass
744
731
732
+
745
733
class Breeze (Thing ):
746
734
pass
747
735
736
+
748
737
class Arrow (Thing ):
749
738
pass
750
739
740
+
751
741
class Scream (Thing ):
752
742
pass
753
743
@@ -756,6 +746,7 @@ class Wumpus(Agent):
756
746
screamed = False
757
747
pass
758
748
749
+
759
750
class Stench (Thing ):
760
751
pass
761
752
@@ -772,7 +763,7 @@ def can_grab(self, thing):
772
763
773
764
774
765
class WumpusEnvironment (XYEnvironment ):
775
- pit_probability = 0.2 # Probability to spawn a pit in a location. (From Chapter 7.2)
766
+ pit_probability = 0.2 # Probability to spawn a pit in a location. (From Chapter 7.2)
776
767
# Room should be 4x4 grid of rooms. The extra 2 for walls
777
768
778
769
def __init__ (self , agent_program , width = 6 , height = 6 ):
@@ -805,7 +796,6 @@ def init_world(self, program):
805
796
806
797
"GOLD"
807
798
self .add_thing (Gold (), self .random_location_inbounds (exclude = (1 , 1 )), True )
808
- #self.add_thing(Gold(), (2,1), True) Making debugging a whole lot easier
809
799
810
800
"AGENT"
811
801
self .add_thing (Explorer (program ), (1 , 1 ), True )
@@ -814,7 +804,12 @@ def get_world(self, show_walls=True):
814
804
"""Returns the items in the world"""
815
805
result = []
816
806
x_start , y_start = (0 , 0 ) if show_walls else (1 , 1 )
817
- x_end , y_end = (self .width , self .height ) if show_walls else (self .width - 1 , self .height - 1 )
807
+
808
+ if show_walls :
809
+ x_end , y_end = self .width , self .height
810
+ else :
811
+ x_end , y_end = self .width - 1 , self .height - 1
812
+
818
813
for x in range (x_start , x_end ):
819
814
row = []
820
815
for y in range (y_start , y_end ):
@@ -837,7 +832,6 @@ def percepts_from(self, agent, location, tclass=Thing):
837
832
if location != agent .location :
838
833
thing_percepts [Gold ] = None
839
834
840
-
841
835
result = [thing_percepts .get (thing .__class__ , thing ) for thing in self .things
842
836
if thing .location == location and isinstance (thing , tclass )]
843
837
return result if len (result ) else [None ]
@@ -916,18 +910,19 @@ def in_danger(self, agent):
916
910
def is_done (self ):
917
911
"""The game is over when the Explorer is killed
918
912
or if he climbs out of the cave only at (1,1)."""
919
- explorer = [agent for agent in self .agents if isinstance (agent , Explorer ) ]
913
+ explorer = [agent for agent in self .agents if isinstance (agent , Explorer )]
920
914
if len (explorer ):
921
915
if explorer [0 ].alive :
922
- return False
916
+ return False
923
917
else :
924
918
print ("Death by {} [-1000]." .format (explorer [0 ].killed_by ))
925
919
else :
926
920
print ("Explorer climbed out {}."
927
- .format ("with Gold [+1000]!" if Gold () not in self .things else "without Gold [+0]" ))
921
+ .format (
922
+ "with Gold [+1000]!" if Gold () not in self .things else "without Gold [+0]" ))
928
923
return True
929
924
930
- #Almost done. Arrow needs to be implemented
925
+ # Almost done. Arrow needs to be implemented
931
926
# ______________________________________________________________________________
932
927
933
928
@@ -952,6 +947,7 @@ def score(env):
952
947
953
948
# _________________________________________________________________________
954
949
950
+
955
951
__doc__ += """
956
952
>>> a = ReflexVacuumAgent()
957
953
>>> a.program((loc_A, 'Clean'))
0 commit comments