示例#1
0
class PlayGround:
    
    def __init__(self, map_config, user_config, logdb, prefix):

        self.fm = FieldMap(int(map_config['width']),
                           int(map_config['height']),
                           int(map_config['unit_meter']),
                           logdb, prefix)

        self.fm.place_centers(int(map_config['center']['num']),
                              int(map_config['center']['extent']))

        self.fm.dump_map()

        self.user_dists = []
        self.users = []
        self.users_on_map = np.zeros((int(map_config['width']),
                                     int(map_config['height'])))
        for i in range(int(user_config['num'])):
            h = self.fm.get_loc_random()
            o = self.fm.get_loc_in_center()
            u = User(i, "user_%07d" % i, h[0], h[1], o[0], o[1])
            self.users.append(u)
            self.users_on_map[u.curx][u.cury] += 1
        
        self.logdb = logdb['%s_udist' % prefix]
            
        self.logging_buff_size = 10
        self.logging_buff = []

    def dump_user_dist(self):
        r = []
        for i in range(self.fm.width):
            for j in range(self.fm.height):
                r.append([i, j, self.users_on_map[i][j]])

        return r

    def process(self, step_count):
        for u in self.users:
            self.move_user(u)

        log = {"time": step_count,
               "dist": self.dump_user_dist()}
        self.logging(log, False)
    
    def flush_log(self):
        if len(self.logging_buff) > 0:
            self.logdb.insert(self.logging_buff)
            self.logging_buff = []

    def logging(self, data, flush):
        self.logging_buff.append(data)
        if len(self.logging_buff) >= self.logging_buff_size or flush:
           self.logdb.insert(self.logging_buff) 
           self.logging_buff = []

    def move_user(self, u):
        attractions = self.calc_attractions_proto(u)
        sel_arry = self.direction_select_array(attractions)
        direction = sel_arry[np.random.randint(len(sel_arry))]
        self.users_on_map[u.curx][u.cury] -= 1        
        if direction == 0: ## NORTH
            self.users_on_map[u.curx][u.cury+1] += 1
            u.move_to(u.curx, u.cury+1)

        elif direction == 1: ## EAST
            self.users_on_map[u.curx+1][u.cury] += 1
            u.move_to(u.curx+1, u.cury)

        elif direction == 2: ## SOUTH
            self.users_on_map[u.curx][u.cury-1] += 1
            u.move_to(u.curx, u.cury-1)

        elif direction == 3: ## WEST
            self.users_on_map[u.curx-1][u.cury] += 1
            u.move_to(u.curx-1, u.cury)
    
    def calc_attractions_proto(self, user):
        '''
        no user specific attraction
        [north, east, south, west]の配列を返す
        '''
        x = user.curx
        y = user.cury
        
        if y < self.fm.height - 1:
            yp = self.fm.field_matrix[x][y+1]
        else:
            yp = 0
        if x < self.fm.width - 1:
            xp = self.fm.field_matrix[x+1][y]
        else:
            xp = 0
        if y > 0:
            ym = self.fm.field_matrix[x][y-1]
        else:
            ym = 0
        if x > 0:
            xm = self.fm.field_matrix[x-1][y]
        else:
            xm = 0
        return [yp, xp, ym, xm]
        
    def direction_select_array(self, attr_arry):
        r = []
        for i in range(len(attr_arry)):
            for j in range(int(attr_arry[i])):
                r.append(i)
        return r