From b3c900318b3711eac5844156034cf63015d4ae4b Mon Sep 17 00:00:00 2001 From: Quang Le Date: Thu, 19 Aug 2021 00:10:24 -0700 Subject: [PATCH] Completed simple virtual world --- .DS_Store | Bin 6148 -> 8196 bytes .../__pycache__/runner.cpython-38.pyc | Bin 0 -> 16916 bytes .../__pycache__/virtual_world.cpython-38.pyc | Bin 0 -> 5281 bytes simple_virtual_world/runner.py | 123 +------ simple_virtual_world/runner_sample.py | 332 +++++++++++++++++ simple_virtual_world/server.py | 15 +- simple_virtual_world/virtual_world.py | 344 ++---------------- 7 files changed, 367 insertions(+), 447 deletions(-) create mode 100644 simple_virtual_world/__pycache__/runner.cpython-38.pyc create mode 100644 simple_virtual_world/__pycache__/virtual_world.cpython-38.pyc create mode 100644 simple_virtual_world/runner_sample.py diff --git a/.DS_Store b/.DS_Store index 0ff2cc69e9abad0fe618f41aad7a029ea514c3f5..e8417f256bb8ceac6ca78b20ea4027b76887146c 100644 GIT binary patch literal 8196 zcmeHM%}*0S6n}##TTxk%Dt;U`5)%{gqeetyh_zz0F@|ahf{10i9m>Y-PP4nE7R2=6 zKj2;e1ohz2qZebmdounBdiA7lKFUX-M$s6fGs(+D#RdC z9s4aMmsD7nDAj?e;De}{iHcB&m>um~LL5j^qAoQ9nt}BUaChm%XgvpIsI7_Lb7_w` zd5`5$f=ivpeB`T0SOe&V5L_sso+sk{d29s`K?T17cxbN*4BH+Qn(RD7-Q%0Fldpzl zwVrqRvgd};$&>F%+m`mN+d2%x=rnd3)7d#z%|>=q2~&13#akIWn#-&D7-QaY-Oi7@ zw3;(}FEKx|U7rR**)32MxpT|)3#^)A6~7P)J6Smpi^Yss&OETVcq}n^c5uKtdv0iH zz*6hm=zxMfT;Csw3;(9rcJD_>DIk@{GsIA>= zgnxxPvudxk)cc3`R?BC0oq6R?|%$FvW3xDMlR4;J7tJcSqV3f{m6_yk`_2QkSZa+I7V z!{h?FO48&S$&ef5wp4Fx92*B4Q%EFJh%JBG4UUPHva62;=WYD_qiJz0d`Eue82AzS z4cxw^?It&0`^dWWn;F<5?e+2a|8nc^|G#-wZB8?w8TgwRAnhaBkrb||ao032j>p;- z<{8X9ak;ugp@M}7#}P$1j=21XA=WJv5qR1z!w62|MLJ%y)x_jU+lyG Gt@sAETL_&1 delta 127 zcmZp1XfcprU|?W$DortDU=RQ@Ie-{Mvv5r;6q~50$jGrVU^g=($7UV@2Sx!yLvyoQ z9ffLha|0a(6JxW@F@mX#n^%arF)n83;1Fa6Y6JoSZXn?bGGk-mcjn3bGM*q48JHlZ NgDhm&9M3a{832Q?6(axu diff --git a/simple_virtual_world/__pycache__/runner.cpython-38.pyc b/simple_virtual_world/__pycache__/runner.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9e8062e060b3cff9c8a46e78aeb3b82fc3495733 GIT binary patch literal 16916 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 literal 0 HcmV?d00001 diff --git a/simple_virtual_world/runner.py b/simple_virtual_world/runner.py index ceffe5e..ca243c4 100644 --- a/simple_virtual_world/runner.py +++ b/simple_virtual_world/runner.py @@ -9,12 +9,11 @@ class RunnerAgent(Agent): def __init__(self, unique_id, model): super().__init__(unique_id, model) - self.type = 'type1' - # self.type = self.random.choice(['type1', 'type2']) + # self.type = 'type1' + self.type = self.random.choice(['type1', 'type2']) if self.type == 'type2': self.on_road = True self.on_trail = False - # self.on_way_running = True self.on_way_home = False self.entrance_trail_pos = None self.exit_trail_pos = None @@ -22,13 +21,11 @@ def __init__(self, unique_id, model): self.ready_to_exit_trail = False self.start_the_trail_run = False self.exit_the_trail_going_home = False - # self.get_to_the_first_intersection = False self.direction = None self.count = 0 self.distance_goal = 160 self.want_to_go_home = False # for type 1 & TYPE 2 - # {(x,y):[(),(),(),..] self.intersection_memory = {} # for type 1 & TYPE 2 self.memory_on_way_home = {} # for type 1 & TYPE 2 self.num_intersection_from_going_home_point = 0 # for type 1 & TYPE 2 @@ -45,7 +42,6 @@ def step(self): self.count += 1 - # try: if self.type == 'type1': if self.state == '_continue_forward': self.continue_forward() @@ -58,9 +54,6 @@ def step(self): elif self.state == '_decide_way_go_home': self.decide_way_go_home() - # elif self.state == 'rest': - # print('ID: ', self.unique_id, 'DONE\n\n\next_pos') - if self.type == 'type2': if self.state == '_decide_way_to_get_to_trail_entrance': self.decide_way_to_get_to_trail_entrance() @@ -76,8 +69,6 @@ def step(self): self.decide_way_to_get_to_trail_exit() elif self.state == '_decide_way_go_home': self.decide_way_go_home() - # elif self.state == 'rest': - # print('ID: ', self.unique_id, 'DONE\n\n\next_pos') if self.pos == self.init_position and self.count >= self.distance_goal: self.state = 'rest' @@ -85,7 +76,6 @@ def step(self): def continue_forward(self): '''MOVING FORWARD''' # Initially, start with no direction - # print('continue - type 1') if self.direction == None: # if start at a dead end, then runner memorize to mark road out of intersection @@ -122,13 +112,10 @@ def _check_to_change_state(self): # CHANGE STATE IF NECESSARY # facing trail, dead end if len(self._get_road_cell_around()) == 1: - # print('CHANGE STATE 1') self.state = '_dead_end' # at the corner of road elif len(self._get_road_cell_around()) == 2 and self._get_road_cell_forward() == False: - # print('CHANGE STATE 2') if self.count >= self.distance_goal and self.want_to_go_home == False: - # print('corner and want to go home') self.state = '_decide_way_go_home' self.want_to_go_home = True self.num_intersection_from_going_home_point += 1 @@ -136,18 +123,13 @@ def _check_to_change_state(self): self.state = '_corner_of_road' # at the intersection and have to turn elif len(self._get_road_cell_around()) > 2: - # print('CHANGE STATE 3') - - # print(self.intersection_memory) # STORE DEAD END ROAD if on the way getting out of it and at intersection if self.getting_out_of_deadend: self.road_to_dead_end.append(self._get_road_cell_behind()) self.getting_out_of_deadend = False - # print(self.road_to_dead_end) if self.count >= self.distance_goal: - # print('FIND WAY HOME') self.state = '_decide_way_go_home' self.want_to_go_home = True self.num_intersection_from_going_home_point += 1 @@ -159,37 +141,23 @@ def _check_to_change_state(self): # Continue forward for type 2 def continue_forward_type2(self): - # THIS PART IS USED FOR TYPE 2 - # At the entrance of trail, enter it if self.ready_to_enter_trail: next_position = self._get_trail_cell_around()[0] self.exit_trail_pos = next_position - # print('Exit trail position: ', self.exit_trail_pos) self.ready_to_enter_trail = False - # self.on_way_running = False self.start_the_trail_run = True - # self.get_to_the_first_intersection = True self.on_road = False self.on_trail = True # At the exit of trail, READY TO ENTERING ROAD AGAIN TO GO HOME elif self.ready_to_exit_trail: - # print('Get position') next_position = self._get_road_cell_around()[0] self.ready_to_exit_trail = False self.exit_the_trail_going_home = True self.on_road = True self.on_trail = False - # # Go forward after entering the trail - # elif self.ready_to_enter_trail == False and self.on_trail: - # next_position = self._get_trail_cell_forward() - - # # Go forward after exiting the trail - # elif self.ready_to_enter_trail == False and self.on_trail: - # next_position = self._get_trail_cell_forward() - # on road, start, haven't got to trail yet (NORMAL) elif self.on_road: next_position = self._get_road_cell_forward() @@ -202,17 +170,13 @@ def continue_forward_type2(self): if self.getting_out_of_deadend == True and self.pos == self.init_position: self.getting_out_of_deadend = False self.start_from_dead_end_road = True - # print('Set to False again') # at the entrance trail, about to start the trail running if self.pos == self.entrance_trail_pos and self.count < self.distance_goal: - # print('READY TO Enter') self.ready_to_enter_trail = True - # self.on_road = False # at the exit trail, about to get on the road and go home if self.pos == self.exit_trail_pos and self.count >= self.distance_goal: - # print('READY TO EXIT') self.ready_to_exit_trail = True self._check_to_change_state_type2() @@ -226,24 +190,19 @@ def _check_to_change_state_type2(self): self.state = '_continue_forward_type2' # just start going home from the entrance elif len(self._get_trail_cell_around()) == 1 and self.exit_the_trail_going_home: - # print('Change state to go forward') self.state = '_continue_forward_type2' self.exit_the_trail_going_home = False # facing dead end elif len(self._get_road_cell_around()) == 1: - # print('CHANGE STATE to dead end') self.state = '_dead_end' # still on road elif len(self._get_road_cell_around()) == 2 and self._get_road_cell_forward() != False: - # print('CHANGE STATE to CONTINUE FORWARD') self.state = '_continue_forward_type2' # at the corner of road elif len(self._get_road_cell_around()) == 2 and self._get_road_cell_forward() == False: - # print('CHANGE STATE to CORNER of road') self.state = '_corner_of_road' # at intersection on road elif len(self._get_road_cell_around()) > 2: - # print('KEEP') # on way home, at intersection, need the closest way to home if self.count >= self.distance_goal: @@ -258,7 +217,6 @@ def _check_to_change_state_type2(self): # store the dead end road if on the way getting out of it and at intersection if self.getting_out_of_deadend: - # print('RUN') if self._get_road_cell_behind() not in self.road_to_dead_end: self.road_to_dead_end.append( self._get_road_cell_behind()) @@ -274,20 +232,16 @@ def _check_to_change_state_type2(self): # just start running at the trail elif len(self._get_trail_cell_around()) == 1 and self.start_the_trail_run: - # print('Change state to go forward') self.state = '_continue_forward_type2' self.start_the_trail_run = False # facing dead end elif len(self._get_trail_cell_around()) == 1: - # print('Change state to dead end') self.state = '_dead_end' # still on trail elif len(self._get_trail_cell_around()) == 2 and self._get_trail_cell_forward() != False: - # print('Change state to continue forward') self.state = '_continue_forward_type2' # at the corner of trail elif len(self._get_trail_cell_around()) == 2 and self._get_trail_cell_forward() == False: - # print('Change state to corner of road') # Pass the distance goal if self.count >= self.distance_goal and self.num_intersection_from_going_home_point == 0: @@ -302,7 +256,6 @@ def _check_to_change_state_type2(self): # at intersection on trail elif len(self._get_trail_cell_around()) > 2: - # print('KEEP') # Pass the distance goal if self.count >= self.distance_goal: @@ -315,13 +268,9 @@ def _check_to_change_state_type2(self): else: # Normally self.state = '_intersection_on_trail' - # if self.get_to_the_first_intersection: - # self.trail_cell_behind_first_intersection = self._get_trail_cell_behind() - # self.get_to_the_first_intersection = False # store the dead end road if on the way getting out of it and at intersection if self.getting_out_of_deadend: - # print('RUN') if self._get_trail_cell_behind() not in self.road_to_dead_end: self.road_to_dead_end.append( self._get_trail_cell_behind()) @@ -339,8 +288,6 @@ def dead_end(self): elif self.type == 'type2' and self.on_trail: next_position = self._get_trail_cell_behind() - # print('TYPE2 ', self.pos, ' ', self.exit_trail_pos) - # let runner memorize this is dead end to store infor once getting to the intersection self.getting_out_of_deadend = True @@ -401,7 +348,6 @@ def decide_way_go_home(self): direction = self._check_direction_of_point( self.pos, self.init_position) road_cells = self._get_road_cell_around() - # print('ROAD CELLS: ', road_cells) prefer_roads = [] # set a prefer roads list to take consideration @@ -409,7 +355,6 @@ def decide_way_go_home(self): # choose a road randomly from the prefer road, if don't have prefer road, choose one of the other non-prefer roads # without considering roads leading to dead end and road just passed - # print(direction) # remove roads leading to dead_end but not home if len(self.road_to_dead_end) > 0: @@ -418,7 +363,6 @@ def decide_way_go_home(self): prefer_roads.remove(cell) if cell in road_cells: road_cells.remove(cell) - # print('ROAD TO DEAD END: ', self.road_to_dead_end) road_consider = road_cells.copy() @@ -430,8 +374,6 @@ def decide_way_go_home(self): if cell in road_consider: road_consider.remove(cell) - # print('PREFER ROAD: ', prefer_roads) - if len(prefer_roads) > 0: next_position = self.random.choice(prefer_roads) # print('CHOOSE: ', next_position) @@ -439,9 +381,6 @@ def decide_way_go_home(self): next_position = self.random.choice(road_consider) elif len(road_cells) > 0: next_position = self.random.choice(road_cells) - # else: - # next_position = self.random.choice(self._get_road_cell_around()) - # self._get_road_cell_around()) # place agent, set new direction, change state self._set_new_direction_place_agent(next_position) @@ -456,38 +395,17 @@ def decide_way_go_home(self): def intersection_on_trail(self): # CHOOSE PREFER TRAIL: STRAIGHT, RIGHT, LEFT, THEN CHOOSE ONE FIRST USE TO ENTER INTERS - if not self.on_way_home: # still running and experiencing the trail - if self._get_trail_cell_forward() and self._get_trail_cell_forward() not in self.intersection_memory[self.pos]: - next_position = self._get_trail_cell_forward() - elif self._get_trail_cell_right() and (self._get_trail_cell_right() not in self.intersection_memory[self.pos]): - next_position = self._get_trail_cell_right() - elif self._get_trail_cell_left() and (self._get_trail_cell_left() not in self.intersection_memory[self.pos]): - next_position = self._get_trail_cell_left() - # elif (self.intersection_memory[self.pos][0] not in self.road_to_dead_end) and (self.intersection_memory[self.pos][0] not in self.mark_road_to_home_dead_end): - # next_position = self.intersection_memory[self.pos][0] - else: - possible_steps = self._get_trail_cell_around() - possible_steps.remove(self._get_trail_cell_behind()) - - next_position = self.random.choice(possible_steps) - - # elif self.on_way_to_home: - # if self._get_trail_cell_forward() and self._get_trail_cell_forward() not in self.intersection_memory[self.pos]: - # next_position = self._get_trail_cell_forward() - # elif self._get_trail_cell_right() and (self._get_trail_cell_right() not in self.intersection_memory[self.pos]): - # next_position = self._get_trail_cell_right() - # elif self._get_trail_cell_left() and (self._get_trail_cell_left() not in self.intersection_memory[self.pos]): - # next_position = self._get_trail_cell_left() - # elif (self.intersection_memory[self.pos][0] not in self.road_to_dead_end) and (self.intersection_memory[self.pos][0] not in self.mark_road_to_home_dead_end): - # next_position = self.intersection_memory[self.pos][0] - # else: - # possible_steps = self._get_trail_cell_around() - - # if self._get_trail_cell_behind() != self.intersection_memory[self.pos][0]: - # possible_steps.remove(self._get_trail_cell_behind()) - # possible_steps.remove(self.intersection_memory[self.pos][0]) + if self._get_trail_cell_forward() and self._get_trail_cell_forward() not in self.intersection_memory[self.pos]: + next_position = self._get_trail_cell_forward() + elif self._get_trail_cell_right() and (self._get_trail_cell_right() not in self.intersection_memory[self.pos]): + next_position = self._get_trail_cell_right() + elif self._get_trail_cell_left() and (self._get_trail_cell_left() not in self.intersection_memory[self.pos]): + next_position = self._get_trail_cell_left() + else: + possible_steps = self._get_trail_cell_around() + possible_steps.remove(self._get_trail_cell_behind()) - # next_position = self.random.choice(possible_steps) + next_position = self.random.choice(possible_steps) # set new direction and move agent self._set_new_direction_place_agent(next_position) @@ -576,7 +494,6 @@ def decide_way_to_get_to_trail_entrance(self): # Start at entrance trail (rare case but possible) if self.pos == self.entrance_trail_pos: self.ready_to_enter_trail = True - # self.on_road = False # Otherwise, do normal else: @@ -595,10 +512,7 @@ def decide_way_to_get_to_trail_entrance(self): direction = self._check_direction_of_point( self.pos, self.target_point) road_cells = self._get_road_cell_around() - # print('ROAD CELLS: ', road_cells) prefer_roads = [] - # print('Select entrance: ', self.entrance_trail_pos) - # print(direction) # set a prefer roads list to take consideration self._set_prefer_roads(prefer_roads, direction, road_cells) @@ -610,7 +524,6 @@ def decide_way_to_get_to_trail_entrance(self): prefer_roads.remove(cell) if cell in road_cells: road_cells.remove(cell) - # print('ROAD TO DEAD END: ', self.road_to_dead_end) road_consider = road_cells.copy() @@ -621,13 +534,9 @@ def decide_way_to_get_to_trail_entrance(self): prefer_roads.remove(cell) if cell in road_consider: road_consider.remove(cell) - # print('AFTER REMOVE ROADS HAVE BEEN USED') - - # print('PREFER ROAD: ', prefer_roads) if len(prefer_roads) > 0: next_position = self.random.choice(prefer_roads) - # print('CHOOSE: ', next_position) elif len(road_consider) > 0: next_position = self.random.choice(road_consider) elif len(road_cells) > 0: @@ -639,7 +548,6 @@ def decide_way_to_get_to_trail_entrance(self): # get to entrance trail at step 2 (rare case but possible) if self.pos == self.entrance_trail_pos: self.ready_to_enter_trail = True - # self.on_road = False # check and update intersection memory that has been passed self._set_memory_over_intersection_one_step() @@ -657,10 +565,7 @@ def decide_way_to_get_to_trail_exit(self): direction = self._check_direction_of_point( self.pos, self.exit_trail_pos) trail_cells = self._get_trail_cell_around() - # print('TRAIL CELLS AROUND: ', trail_cells) prefer_trails = [] - # print('Trail exit: ', self.exit_trail_pos) - # print(direction) # set a prefer roads list to take consideration self._set_prefer_roads(prefer_trails, direction, trail_cells) @@ -672,7 +577,6 @@ def decide_way_to_get_to_trail_exit(self): prefer_trails.remove(cell) if cell in trail_cells: trail_cells.remove(cell) - # print('ROAD TO DEAD END: ', self.road_to_dead_end) trail_consider = trail_cells.copy() @@ -688,7 +592,6 @@ def decide_way_to_get_to_trail_exit(self): if len(prefer_trails) > 0: next_position = self.random.choice(prefer_trails) - # print('CHOOSE: ', next_position) # consider roads with that no dead end, no road used before elif len(trail_consider) > 0: next_position = self.random.choice(trail_consider) @@ -715,7 +618,6 @@ def _select_closest_trail(self): if min_distance == None or (estimate_distance < min_distance): min_distance = estimate_distance prefer_entrance = entrance_pos - # print(prefer_entrance) return prefer_entrance @@ -847,7 +749,6 @@ def _get_trail_cell_around(self): # List contains position of road cells that are from those 4 cells above possible_trails = [] for pos in cells_around: - # x, y = pos for cell_object in self.model.background_cells: if cell_object.pos == pos and cell_object.type == 'trail': possible_trails.append(pos) diff --git a/simple_virtual_world/runner_sample.py b/simple_virtual_world/runner_sample.py new file mode 100644 index 0000000..e9fc3d8 --- /dev/null +++ b/simple_virtual_world/runner_sample.py @@ -0,0 +1,332 @@ +from mesa import Agent, Model +from mesa.space import MultiGrid + + +class RunnerAgent(Agent): + ''' This class will represent runners in this model ''' + + def __init__(self, unique_id, model): + super().__init__(unique_id, model) + self.type = 'runner' + self.direction = None + self.count = 0 + self.distance_goal = 100 + self.want_to_go_home = True + # {(x,y):[(),(),(),..] + self.intersection_memory = {} + self.road_to_dead_end = [] + self.getting_out_of_deadend = False + self.state = '_continue_forward' + + def step(self): + + if self.state == '_continue_forward': + self.continue_forward() + elif self.state == '_intersection': + self.intersection() + elif self.state == '_corner_of_road': + self.corner_of_road() + elif self.state == '_dead_end': + self.dead_end() + elif self.state == '_decide_way_go_home': + self.decide_way_go_home() + + elif self.state == 'rest': + pass + + self.count += 1 + + if self.pos == self.init_position and self.count >= self.distance_goal: + self.state = 'rest' + print('FINISH') + + def continue_forward(self): + '''MOVING FORWARD''' + # Initially, start with no direction + if self.direction == None: + + # if start at a dead end, then runner memorize and set memory once get to intersection + if len(self._get_road_cell_around()) == 1: + self.getting_out_of_deadend = True + # if start at intersection, then create memory at that intersection + if len(self._get_road_cell_around()) > 2: + self.intersection_memory[self.pos] = [] + + next_position = self.random.choice(self._get_road_cell_around()) + + # check and update intersection memory just passed + if self.pos in self.intersection_memory: + self.intersection_memory[self.pos].append(next_position) + + self._set_new_direction_place_agent(next_position) + + # Already having a direction and have road ahead + elif self._get_road_cell_forward(): + next_position = self._get_road_cell_forward() + self._set_new_direction_place_agent(next_position) + + # CHANGE STATE IF NECESSARY + # facing trail, dead end + if len(self._get_road_cell_around()) == 1: + print('CHANGE STATE 1') + self.state = '_dead_end' + # at the corner of road + elif len(self._get_road_cell_around()) == 2 and self._get_road_cell_forward() == False: + print('CHANGE STATE 2') + self.state = '_corner_of_road' + # at the intersection and have to turn + elif len(self._get_road_cell_around()) > 2: + print('CHANGE STATE 3') + # key: intersection center cell - is not created yet + self._set_memory_at_intersection() + if self.count >= self.distance_goal: + print('FIND WAY HOME') + self.state = '_decide_way_go_home' + self.want_to_go_home = True + else: + self.state = '_intersection' + + def dead_end(self): + ''' make a U-turn since this type of runner avoids trail, also avoid dead end ''' + + next_position = self._get_road_cell_behind() + print('U TURN: ', next_position) + # let runner memorize this is dead end to store infor once getting to the intersection + self.getting_out_of_deadend = True + # set new direction and move agent + self._set_new_direction_place_agent(next_position) + # after making a U-turn, set state back to _continue_forward + self.state = '_continue_forward' + + def intersection(self): + ''' Prefer turn right, then left, if both roads have been gone, choose the one first used to enter this intersection to get out ''' + + # store the dead end road if on the way getting out of it + if self.getting_out_of_deadend: + self.road_to_dead_end.append(self._get_road_cell_behind()) + self.getting_out_of_deadend = False + + # CHOOSE PREFER ROAD: STRAIGHT, RIGHT, LEFT, THEN CHOOSE ONE FIRST USE TO ENTER INTERS. + if self._get_road_cell_forward() and self._get_road_cell_forward() not in self.intersection_memory[self.pos]: + next_position = self._get_road_cell_forward() + elif self._get_road_cell_right() and (self._get_road_cell_right() not in self.intersection_memory[self.pos]): + next_position = self._get_road_cell_right() + elif self._get_road_cell_left() and (self._get_road_cell_left() not in self.intersection_memory[self.pos]): + next_position = self._get_road_cell_left() + else: + next_position = self.intersection_memory[self.pos][0] + + # check and update intersection memory just passed + if next_position not in self.intersection_memory[self.pos]: + self.intersection_memory[self.pos].append(next_position) + + # set new direction and move agent + self._set_new_direction_place_agent(next_position) + # after making a turn, set state back to _continue_forward + self.state = '_continue_forward' + print(self.intersection_memory) + + def decide_way_go_home(self): + ''' Try to direct runner to home as close as possible ''' + # x, y = self.pos + + # Find prefer direction based on the 2 position (currrent and initial) + direction = self._check_direction_of_point( + self.pos, self.init_position) + road_cells = self._get_road_cell_around() + print('ROAD CELLS: ', road_cells) + prefer_roads = [] + + # append prefer road based on the direction toward init pos + if direction == 'up': + if self._get_cell('up') in road_cells: + prefer_roads.append(self._get_cell('up')) + elif direction == 'up_right': + if self._get_cell('up') in road_cells: + prefer_roads.append(self._get_cell('up')) + if self._get_cell('right') in road_cells: + prefer_roads.append(self._get_cell('right')) + elif direction == 'right': + if self._get_cell('right') in road_cells: + prefer_roads.append(self._get_cell('right')) + elif direction == 'down_right': + if self._get_cell('down') in road_cells: + prefer_roads.append(self._get_cell('down')) + if self._get_cell('right') in road_cells: + prefer_roads.append(self._get_cell('right')) + elif direction == 'down': + if self._get_cell('down') in road_cells: + prefer_roads.append(self._get_cell('down')) + elif direction == 'down_left': + if self._get_cell('down') in road_cells: + prefer_roads.append(self._get_cell('down')) + if self._get_cell('left') in road_cells: + prefer_roads.append(self._get_cell('left')) + elif direction == 'left': + if self._get_cell('left') in road_cells: + prefer_roads.append(self._get_cell('left')) + elif direction == 'up_left': + if self._get_cell('up') in road_cells: + prefer_roads.append(self._get_cell('up')) + if self._get_cell('left') in road_cells: + prefer_roads.append(self._get_cell('left')) + + # choose a road randomly from the prefer road, if don't have prefer road, choose one of the other non-prefer roads + # without considering roads leading to dead end + print(direction) + print('PREFER ROAD: ', prefer_roads) + + if len(self.road_to_dead_end) > 0: + for cell in self.road_to_dead_end: + if cell in prefer_roads: + prefer_roads.remove(cell) + if cell in road_cells: + road_cells.remove(cell) + + if len(prefer_roads) > 0: + next_position = self.random.choice(prefer_roads) + print('CHOOSE: ', next_position) + else: + next_position = self.random.choice(road_cells) + + # place agent, set new direction, change state + self._set_new_direction_place_agent(next_position) + self.state = '_continue_forward' + + def corner_of_road(self): + ''' Have to turn at the corner of road ''' + + possible_steps = self._get_road_cell_around() + possible_steps.remove(self._get_road_cell_behind()) + + next_position = possible_steps[0] + print(next_position) + # set new direction and move agent + self._set_new_direction_place_agent(next_position) + # after making a turn, set state back to _continue_forward + self.state = '_continue_forward' + + def _set_memory_at_intersection(self): + # create a key as the intersection center cell if it's created yet, then append road cell passed + if self.pos not in self.intersection_memory: + self.intersection_memory[self.pos] = [] + if self._get_road_cell_behind() not in self.intersection_memory[self.pos]: + self.intersection_memory[self.pos].append( + self._get_road_cell_behind()) + + def _set_new_direction_place_agent(self, next_pos): + # Unpack tuple position + x, y = self.pos + a, b = next_pos + # Set new direction + if a > x: + self.direction = 'right' + elif a < x: + self.direction = 'left' + elif b > y: + self.direction = 'up' + else: + self.direction = 'down' + # Place agent to new position + self.model.grid.move_agent(self, next_pos) + + def _get_road_cell_around(self): + # List contains position of 4 cells around (top, bottom, left, right) + cells_around = self.model.grid.get_neighborhood( + self.pos, moore=False, include_center=False) + # List contains position of road cells that are from those 4 cells above + possible_roads = [] + for pos in cells_around: + # x, y = pos + for cell_object in self.model.background_cells: + if cell_object.pos == pos and cell_object.type == 'road': + possible_roads.append(pos) + return possible_roads + + def _get_road_cell_behind(self): + if self.direction == 'right': + return (self.pos[0] - 1, self.pos[1]) + elif self.direction == 'left': + return (self.pos[0] + 1, self.pos[1]) + elif self.direction == 'up': + return (self.pos[0], self.pos[1] - 1) + elif self.direction == 'down': + return (self.pos[0], self.pos[1] + 1) + + def _get_road_cell_forward(self): + if self.direction == 'right' and self._check_cell_is_road((self.pos[0] + 1, self.pos[1])): + return (self.pos[0] + 1, self.pos[1]) + elif self.direction == 'left' and self._check_cell_is_road((self.pos[0] - 1, self.pos[1])): + return (self.pos[0] - 1, self.pos[1]) + elif self.direction == 'up' and self._check_cell_is_road((self.pos[0], self.pos[1] + 1)): + return (self.pos[0], self.pos[1] + 1) + elif self.direction == 'down' and self._check_cell_is_road((self.pos[0], self.pos[1] - 1)): + return (self.pos[0], self.pos[1] - 1) + else: + return False + + def _get_road_cell_right(self): + if self.direction == 'right' and self._check_cell_is_road((self.pos[0], self.pos[1] - 1)): + return (self.pos[0], self.pos[1] - 1) + elif self.direction == 'left' and self._check_cell_is_road((self.pos[0], self.pos[1] + 1)): + return (self.pos[0], self.pos[1] + 1) + elif self.direction == 'up' and self._check_cell_is_road((self.pos[0] + 1, self.pos[1])): + return (self.pos[0] + 1, self.pos[1]) + elif self.direction == 'down' and self._check_cell_is_road((self.pos[0] - 1, self.pos[1])): + return (self.pos[0] - 1, self.pos[1]) + else: + return False + + def _get_road_cell_left(self): + if self.direction == 'right' and self._check_cell_is_road((self.pos[0], self.pos[1] + 1)): + return (self.pos[0], self.pos[1] + 1) + elif self.direction == 'left' and self._check_cell_is_road((self.pos[0], self.pos[1] - 1)): + return (self.pos[0], self.pos[1] - 1) + elif self.direction == 'up' and self._check_cell_is_road((self.pos[0] - 1, self.pos[1])): + return (self.pos[0] - 1, self.pos[1]) + elif self.direction == 'down' and self._check_cell_is_road((self.pos[0] + 1, self.pos[1])): + return (self.pos[0] + 1, self.pos[1]) + else: + return False + + def _get_cell(self, type): + x, y = self.pos + if type == 'up': + return (x, y + 1) + elif type == 'down': + return (x, y - 1) + elif type == 'left': + return (x - 1, y) + elif type == 'right': + return (x + 1, y) + + def _check_cell_is_road(self, cell_position): + possible_roads = self._get_road_cell_around() + if cell_position in possible_roads: + return True + else: + return False + + def _check_direction_of_point(self, current_pos, init_position): + x, y = current_pos + a, b = init_position + + distance_x = a - x + distance_y = b - y + + if distance_y > 0 and distance_x == 0: + return 'up' + elif distance_y > 0 and distance_x > 0: + return 'up_right' + elif distance_y == 0 and distance_x > 0: + return 'right' + elif distance_y < 0 and distance_x > 0: + return 'down_right' + elif distance_y < 0 and distance_x == 0: + return 'down' + elif distance_y < 0 and distance_x < 0: + return 'down_left' + elif distance_y == 0 and distance_x < 0: + return 'left' + elif distance_y > 0 and distance_x < 0: + return 'up_left' diff --git a/simple_virtual_world/server.py b/simple_virtual_world/server.py index 642cce7..eb40e21 100644 --- a/simple_virtual_world/server.py +++ b/simple_virtual_world/server.py @@ -22,12 +22,7 @@ def cell(agent): elif agent.type == 'grass': portrayal['Color'] = '#4ECA24' - -<< << << < Updated upstream - elif agent.type == 'runner': -== == == = elif agent.type == 'type1': ->>>>>> > Stashed changes portrayal['Shape'] = 'circle' portrayal['r'] = '0.7' portrayal['Layer'] = 1 @@ -43,14 +38,8 @@ def cell(agent): grid = CanvasGrid(cell, 50, 50, 600, 600) -# chart = ChartModule([{'Label': 'Num_mov_agents', 'Color': 'Black'}]) - -<<<<<<< Updated upstream -server = ModularServer(VirtualWorldModel, [grid], "Virtual World", {'N': 1, -======= -server = ModularServer(VirtualWorldModel, [grid], "Virtual World", {'N': 10, ->>>>>>> Stashed changes - 'width': 50, 'height': 50}) +server = ModularServer(VirtualWorldModel, [grid], "Virtual World", { + 'N': 50, 'width': 50, 'height': 50}) server.port = 8000 server.launch() diff --git a/simple_virtual_world/virtual_world.py b/simple_virtual_world/virtual_world.py index 15ccada..17a41fd 100644 --- a/simple_virtual_world/virtual_world.py +++ b/simple_virtual_world/virtual_world.py @@ -1,287 +1,10 @@ from mesa import Agent, Model from mesa.space import MultiGrid from mesa.time import RandomActivation - - -class RunnerAgent(Agent): - ''' This class will represent runners in this model ''' - - def __init__(self, unique_id, model): - super().__init__(unique_id, model) - self.type = 'runner' - self.direction = None - self.count = 0 - # {(x,y):[(),(),(),..] - self.intersection_memory = {} - self.state = 'run' - - def step(self): - - if self.state == 'run': - self.go_forward() - - def go_forward(self): - # List contains position of 4 cells around (top, bottom, left, right) - cells_around = self.model.grid.get_neighborhood( - self.pos, moore=False, include_center=False) - # List contains position of road cells that are from those 4 cells above - possible_steps = [] - for pos in cells_around: - # x, y = pos - for cell_object in self.model.background_cells: - if cell_object.pos == pos and cell_object.type == 'road': - possible_steps.append(pos) - - # Runner has to choose a direction at first - if self.direction == None: - next_position = self.random.choice(possible_steps) - - # Runner already had a direction - else: - x, y = self.pos # unpack current position - - # In the right (east) direction - if self.direction == 'right': - - # continue forward if having road and that road haven't been gone through - if (((x + 1, y) in possible_steps) and (self.pos not in self.intersection_memory)) or (((x + 1, y) in possible_steps) and (self.pos in self.intersection_memory) and ((x + 1, y) not in self.intersection_memory[self.pos])): - next_position = (x + 1, y) - # At the intersection, or over the center 1 cell, store a center cell, and the cells around that have been gone through - if len(possible_steps) > 2: - # create key-value inside - if self.pos not in self.intersection_memory: - # key: center cell's position, value: list of around road cells position that have been gone through - self.intersection_memory[self.pos] = [] - - self.intersection_memory[self.pos].append((x - 1, y)) - - # Append the current pos once passed the intersection - elif (self.pos[0] - 1, self.pos[1]) in self.intersection_memory: - self.intersection_memory[( - self.pos[0] - 1, self.pos[1])].append(self.pos) - - # either one-way road or at the intersection that runner must turn - else: - # facing trail or dead end --> make a U-turn - if len(possible_steps) == 1: - next_position = (x - 1, y) - # at the corner and have to turn either left or right - elif len(possible_steps) == 2: - # remove the behind step and assign the turning road - possible_steps.remove((x - 1, y)) - next_position = possible_steps[0] - # at intersection and have to turn and also avoid repeated route - else: - # Create key memory for that intersection if not yet created - if self.pos not in self.intersection_memory: - self.intersection_memory[self.pos] = [] - # Prefer turn right first - if ((x, y - 1) in possible_steps) and ((x, y - 1) not in self.intersection_memory[self.pos]): - next_position = (x, y - 1) - # append the cell behind which just passed through before entering this center - self.intersection_memory[self.pos].append( - (x - 1, y)) - # Turn left instead if already turned right - elif ((x, y + 1) in possible_steps) and (x, y + 1) not in self.intersection_memory[self.pos]: - next_position = (x, y + 1) - # append the cell behind which just passed through before entering this center - self.intersection_memory[self.pos].append( - (x - 1, y)) - # Choose the first route that the runner used to enter this intersection to get out of this loop - else: - num_routes = len( - self.intersection_memory[self.pos]) - for i in range(num_routes - 1): - self.intersection_memory[self.pos].pop() - # set position by the remained position (first route) - next_position = self.intersection_memory[self.pos][0] - - # In the left (west) direction - elif self.direction == 'left': - - # continue forward if having road and that road haven't been gone through - if (((x - 1, y) in possible_steps) and (self.pos not in self.intersection_memory)) or (((x - 1, y) in possible_steps) and (self.pos in self.intersection_memory) and ((x - 1, y) not in self.intersection_memory[self.pos])): - next_position = (x - 1, y) - # At the intersection, or over the center 1 cell, store a center cell, and the cells around that have been gone through - if len(possible_steps) > 2: - # create key-value inside - if self.pos not in self.intersection_memory: - # key: center cell's position, value: list of around road cells position that have been gone through - self.intersection_memory[self.pos] = [] - - self.intersection_memory[self.pos].append((x + 1, y)) - - # Append the current pos once passed the intersection - elif (self.pos[0] + 1, self.pos[1]) in self.intersection_memory: - self.intersection_memory[( - self.pos[0] + 1, self.pos[1])].append(self.pos) - - # either one-way road or at the intersection that runner must turn - else: - # facing trail or dead end --> make a U-turn - if len(possible_steps) == 1: - next_position = (x + 1, y) - # at the corner and have to turn either left or right - elif len(possible_steps) == 2: - # remove the behind step and assign the turning road - possible_steps.remove((x + 1, y)) - next_position = possible_steps[0] - # at intersection and have to turn and also avoid repeated route - else: - # create key memory for that intersection if not yet created - if self.pos not in self.intersection_memory: - self.intersection_memory[self.pos] = [] - # Prefer turn right first - if ((x, y + 1) in possible_steps) and ((x, y + 1) not in self.intersection_memory[self.pos]): - next_position = (x, y + 1) - # append the cell behind which just passed through before entering this center - self.intersection_memory[self.pos].append( - (x + 1, y)) - # Turn left instead if already turned right - elif ((x, y - 1) in possible_steps) and (x, y - 1) not in self.intersection_memory[self.pos]: - next_position = (x, y - 1) - # append the cell behind which just passed through before entering this center - self.intersection_memory[self.pos].append( - (x + 1, y)) - # choose the first route that the runner used to enter this intersection to get out of this loop - else: - num_routes = len( - self.intersection_memory[self.pos]) - for i in range(num_routes - 1): - self.intersection_memory[self.pos].pop() - # set position by the remained position (first route) - next_position = self.intersection_memory[self.pos][0] - - # In the up (north) direction - elif self.direction == 'up': - # continue forward if having road and that road haven't been gone through - if (((x, y + 1) in possible_steps) and (self.pos not in self.intersection_memory)) or (((x, y + 1) in possible_steps) and (self.pos in self.intersection_memory) and ((x, y + 1) not in self.intersection_memory[self.pos])): - next_position = (x, y + 1) - # At the intersection, or over the center 1 cell, store a center cell, and the cells around that have been gone through - if len(possible_steps) > 2: - # create key-value inside - if self.pos not in self.intersection_memory: - # key: center cell's position, value: list of around road cells position that have been gone through - self.intersection_memory[self.pos] = [] - - self.intersection_memory[self.pos].append((x, y - 1)) - - # Append the current pos once passed the intersection - elif (self.pos[0], self.pos[1] - 1) in self.intersection_memory: - self.intersection_memory[( - self.pos[0], self.pos[1] - 1)].append(self.pos) - - # either one-way road or at the intersection that runner must turn - else: - # facing trail or dead end --> make a U-turn - if len(possible_steps) == 1: - next_position = (x, y - 1) - # at the corner and have to turn either left or right - elif len(possible_steps) == 2: - # remove the behind step and assign the turning road - possible_steps.remove((x, y - 1)) - next_position = possible_steps[0] - # at intersection and have to turn and also avoid repeated route - else: - # create key memory for that intersection if not yet created - if self.pos not in self.intersection_memory: - self.intersection_memory[self.pos] = [] - # Prefer turn right first - if ((x + 1, y) in possible_steps) and ((x + 1, y) not in self.intersection_memory[self.pos]): - next_position = (x + 1, y) - # append the cell behind which just passed through before entering this center - self.intersection_memory[self.pos].append( - (x, y - 1)) - # Turn left instead if already turned right - elif ((x - 1, y) in possible_steps) and (x - 1, y) not in self.intersection_memory[self.pos]: - next_position = (x - 1, y) - # append the cell behind which just passed through before entering this center - self.intersection_memory[self.pos].append( - (x, y - 1)) - else: # choose the first route that the runner used to enter this intersection to get out of this loop - num_routes = len( - self.intersection_memory[self.pos]) - for i in range(num_routes - 1): - self.intersection_memory[self.pos].pop() - # set position by the remained position (first route) - next_position = self.intersection_memory[self.pos][0] - - # In the down (south) direction - elif self.direction == 'down': - # continue forward if having road and that road haven't been gone through - if (((x, y - 1) in possible_steps) and (self.pos not in self.intersection_memory)) or (((x, y - 1) in possible_steps) and (self.pos in self.intersection_memory) and ((x, y - 1) not in self.intersection_memory[self.pos])): - next_position = (x, y - 1) - # At the intersection, or over the center 1 cell, store a center cell, and the cells around that have been gone through - if len(possible_steps) > 2: - # create key-value inside - if self.pos not in self.intersection_memory: - # key: center cell's position, value: list of around road cells position that have been gone through - self.intersection_memory[self.pos] = [] - - self.intersection_memory[self.pos].append((x, y + 1)) - - # Append the current pos once passed the intersection - elif (self.pos[0], self.pos[1] + 1) in self.intersection_memory: - self.intersection_memory[( - self.pos[0], self.pos[1] + 1)].append(self.pos) - - # either one-way road or at the intersection that runner must turn - else: - # facing trail or dead end --> make a U-turn - if len(possible_steps) == 1: - next_position = (x, y + 1) - # at the corner and have to turn either left or right - elif len(possible_steps) == 2: - # remove the behind step and assign the turning road - possible_steps.remove((x, y + 1)) - next_position = possible_steps[0] - # at intersection and have to turn and also avoid repeated route - else: - # create key memory for that intersection if not yet created - if self.pos not in self.intersection_memory: - self.intersection_memory[self.pos] = [] - # Prefer turn right first - if ((x - 1, y) in possible_steps) and ((x - 1, y) not in self.intersection_memory[self.pos]): - next_position = (x - 1, y) - # append the cell behind which just passed through before entering this center - self.intersection_memory[self.pos].append( - (x, y + 1)) - # Turn left instead if already turned right - elif ((x + 1, y) in possible_steps) and (x + 1, y) not in self.intersection_memory[self.pos]: - next_position = (x + 1, y) - # append the cell behind which just passed through before entering this center - self.intersection_memory[self.pos].append( - (x, y + 1)) - # choose the first route that the runner used to enter this intersection to get out of this loop - else: - num_routes = len( - self.intersection_memory[self.pos]) - for i in range(num_routes - 1): - self.intersection_memory[self.pos].pop() - # set position by the remained position (first route) - next_position = self.intersection_memory[self.pos][0] - - # Update direction for every step - self.direction = self.set_direction(self.pos, next_position) - self.model.grid.move_agent(self, next_position) - self.count += 1 - if self.pos == self.init_position: - print('NUMBER OF STEP TO COMPLETE THIS LOOP RUN: ', self.count) - - # print(self.intersection_memory) - - def set_direction(self, current_pos, next_pos): - # Unpack tuple position - x, y = current_pos - a, b = next_pos - if a > x: - return 'right' - elif a < x: - return 'left' - elif b > y: - return 'up' - else: - return 'down' +from runner import RunnerAgent +import numpy as np +from matplotlib import pyplot as plt +import seaborn as sns class CellAgent(Agent): @@ -299,22 +22,13 @@ class VirtualWorldModel(Model): def __init__(self, N, width, height): self.width = width self.height = height + self.num_agents = N self.schedule = RandomActivation(self) + self.heatmap_data = np.zeros((self.height, self.width)) self.grid = MultiGrid(self.width, self.height, True) - # Create a list of lists to store attribute of each cell (house, trail, road,...) - # Further, this will be also used for agents/people's initial position and to direct in this map - # self.cell_attribute = [] self.background_cells = [] - # for x in range(self.width): - # # a number of list corresponding with a number of x cells (column) - # self.cell_attribute.append(list()) - # for inside_list in self.cell_attribute: - # for y in range(self.height): - # # a number of list corresponding with a number of y cells (row) for each column - # inside_list.append(list()) - # Create agent for cell and set its attribute count = 0 # for unique_id for x in range(self.width): @@ -328,8 +42,7 @@ def __init__(self, N, width, height): # Set attribute for each cell self.set_attribute_cell(cell_object, x, y) - # Set corresponding position in the attribute list to this type - # self.cell_attribute[x][y] = cell_object.type + # Append to the list containing all background cells self.background_cells.append(cell_object) count += 1 @@ -338,55 +51,54 @@ def __init__(self, N, width, height): self.roads = [ cell.pos for cell in self.background_cells if cell.type == 'road'] # Create runner agents - for i in range(N): + self.agent_objects = [] + for i in range(self.num_agents): runner = RunnerAgent(i, self) # store the inital position as attribte runner.init_position = self.random.choice(self.roads) - -<< << << < Updated upstream print('Initial position: ', runner.init_position) -== == == = - # runner.init_position = (46, 21) - # print('Initial position: ', runner.init_position) ->>>>>> > Stashed changes + self.grid.place_agent(runner, runner.init_position) self.schedule.add(runner) + self.agent_objects.append(runner) + + # update heatmap data + x, y = runner.init_position + self.heatmap_data[self.height - 1 - y][x] += 1 # Attribute running for visualization self.running = True + # Trail entrance point + self.trail_entrance_point = [(3, 32), (30, 40)] + + self.num_agents_complete_running = 0 + def step(self): ''' Activate the step for all runner agents at once ''' self.schedule.step() -<<<<<<< Updated upstream -======= # stop once all agents finish running for agent in self.agent_objects: if agent.state == 'rest': self.num_agents_complete_running += 1 if self.num_agents_complete_running == self.num_agents: self.running = False - print('ALL AGENTS COMPLETED THEIR RUNNING') + print('ALL AGENTS COMPLETED THEIR RUNS') # HEAT MAP - fig, ax = plt.subplots() sns.set_theme() - xlabels = [i for i in range(self.width)] - ax = sns.heatmap(self.heatmap_data, xticklabels=10, yticklabels=10) plt.tight_layout() plt.show() - else: self.num_agents_complete_running = 0 ->>>>>>> Stashed changes def set_attribute_cell(self, cell_object, x, y): # Attribute 'HOUSE' for cells if y >= 5 and y <= 7 and x >= 35 and x <= 37: @@ -485,17 +197,3 @@ def set_attribute_cell(self, cell_object, x, y): # GRASS else: cell_object.type = 'grass' - - # Find all road cells and return a list of multiple tuple positions of roads - def find_road_cells(self, list_cells, width, height): - position_roads = [] - for x in range(width): - for y in range(height): - if list_cells[x][y] == 'road': - position_roads.append((x, y)) - return position_roads - - -# world = VirtualWorldModel(51, 51) -# # # # # print(len(world.cell_attribute[49])) -# print(world.cell_attribute)