Exemple #1
0
def main():
    log("Starting Pyrox...")

    init_gl()
    director.init(resizable=True, caption=GAME_NAME, width=WINDOW_WIDTH, height=WINDOW_HEIGHT)
    director.window.set_icon(window_icon)
    game_scene = Game()
    director.run(game_scene)
Exemple #2
0
def search_series_urls_by_name(name):
    log('searching "{}"'.format(name))
    page = fetch_url(base_url + "/search?keyword=" + name.replace(' ', '+'))
    soup = BeautifulSoup(page, SOUP_PARSER_HTML)
    posters = soup.find_all('a', {'class': 'poster'})
    names = [poster.find('img')['alt'] for poster in posters]
    urls = [poster['href'] for poster in posters]
    return names, urls
Exemple #3
0
    def __init__(self, position, obj=None):
        super(Camera, self).__init__()
        log("Initialize Camera object")
        self.position = position
        self.width = WINDOW_WIDTH
        self.height = WINDOW_HEIGHT
        self.follow_obj = obj

        self.schedule(self.update)
Exemple #4
0
 def _find_episode_watch_links(self, series_page_html):
     hosts = _find_all_servers_and_eps(series_page_html)
     bold('Found {} Servers:'.format(len(hosts.keys())))
     log('\n'.join([
         '{}:\t{}'.format(server_name,
                          [ep.ep_number for ep in hosts[server_name]])
         for server_name in hosts
     ]))
     return hosts[self.get_server_name()]
Exemple #5
0
    def __init__(self, position):
        super(Player, self).__init__(position, player_stay)

        log("Initialize Player object. Position: %i:%i" % position)

        self.speed = TILE_SIZE
        self.sight_radius = 6
        self.buttons = set()
        self.minimap_color = (0, 250, 0)
Exemple #6
0
 def _add_counterexample_with(self, fml, c0_exists, exp=None):
     res, c1 = self._prove(fml=fml, exp=exp)
     if res == sat:
         self._add_counterexample(c1)
     elif res == unsat and c0_exists:
         # couldn't get a counterexample with sum(x^exp == 1), but got a counterexample to the first formula
         log("res == unsat, ex is not None. Exponents: %s" %
             str(self._synth_counterexamples_exp))
         self._error = True
     return res
Exemple #7
0
    def on_transform_completed(self, result: TransformResult):
        log(result)

        if result is None:
            return

        try:
            result.apply(self.df, self.vp)
        except ValueError as e:
            print('transform error:', e)

        self._refresh()
Exemple #8
0
    def _solve(self, min_sum=None, max_sum=None):
        res = None

        self._solver.push()
        if min_sum is not None:
            sum_vars = reduce(lambda rem, item: item + rem, self.P_z3, 0)
            self._solver.add(sum_vars >= min_sum)

        if max_sum is not None:
            if min_sum is None:
                sum_vars = reduce(lambda rem, item: item + rem, self.P_z3, 0)
                self._solver.add(sum_vars <= max_sum)

        self._set_timeout()
        r, self._has_timedout = check_with_timeout(self._solver, self._timeout)
        if r == sat:
            m = self._solver.model()
            log("Learner's s: %s" % self._solver)
            log("Model %s" % m)
            res = Model2Matrix(m, self.P_sym, symmetric=True, target='z3')
            self._error = self._has_timedout
        elif r == unsat:
            log("unsat")
            self._error = True
        elif r == unknown and not self._has_timedout:
            log("unknown")
            self._error = True

        self._solver.pop()

        if self._error or self._has_timedout or res is None:
            log("Could not solve the system with min/max_sum %s %s" % (min_sum, max_sum))
            if max_sum is not None and min_sum is not None:
                return self._solve(min_sum=None, max_sum=None)
            self._error = True
            return unsat

        # try:
        #     min_val = min(*(_x for _x in res if _x > 0))
        # except:
        #     min_val = 1
        #
        # inv_min = 1 / min_val
        # if self._multiply_by_inv_min:
        #     res = res.applyfunc(lambda x: x * inv_min)

        res_matrices = res
        # for P in self.P_sym:
        #     res_matrices.append(
        #         P.subs({self.P_sym[p]: res[p] for p in res})
        #     )
        return res_matrices
Exemple #9
0
    def __init__(self):
        super(Game, self).__init__()

        log("Starting Game_Scene...")

        self.input = Input()
        self.add(self.input, z=0, name='input')

        self.game_layer = self.get_game_layer()
        self.add(self.game_layer, z=1, name='game_layer')

        self.hud_layer = self.get_hud_layer()
        self.add(self.hud_layer, z=3, name='hud_layer')
Exemple #10
0
    def __init__(self):
        super(GameLayer, self).__init__()

        log("Initialize Game_Layer")

        self.level = level_manager.generate_level(5)
        self.add(self.level)

        self.cam = Camera(self.level.player.position, self.level.player)
        self.add(self.cam)

        self.schedule(self.update)
        self.schedule_interval(self.update_second, 1)
Exemple #11
0
    def learn(self):
        """

        :return: True iff a solution has been computed. Use get_solution() to retrieve it
        """
        if self.iter > -1:
            self.solution = self._solve(min_sum=self._min_sum, max_sum=self._max_sum)
            log("learner %s" % self.solution)
        else:
            # correct solution of 6-dim [sp.diag(1, 0, 3, 3, 0, 2), sp.diag(0, 2, 0, 0, 1, 0)]
            self.solution = [ -sp.Identity(self.n), sp.zeros(self.n, self.n)  ]#[+sp.Identity(self.n) for _ in range(len(self.P_sym))]
        res = self._valid_sol(self.solution)
        self.iter += 1
        return res
def download_file_from_multiple_sources(urls, path, headers=None):
    log('downloading {} from multiple urls'.format(path))
    # if not os.path.exists(path):
    #     os.makedirs(path)

    headers = make_headers_with_user_agent(headers)
    with open(path, 'wb') as f:
        for i, url in enumerate(urls):
            # file_name = url[url.rfind('/') + 1:]
            # file_path = os.path.join(path, file_name)
            f.write(fetch_url(url, headers=headers, return_bytes=True))
            print('\r{}/{}...'.format(i, len(urls)), end='')
    print()
    log('finished downloading {}'.format(path))
    return
Exemple #13
0
    def learn(self):
        """

        :return: True iff a solution has been computed. Use get_solution() to retrieve it
        """
        if self.iter > -1:
            self.solution, self._has_timedout = self._solve(
                min_sum=self._min_sum, max_sum=self._max_sum)
            log("learner %s" % self.solution)
        else:
            self.solution = [
                -sp.Identity(self.n) for _ in range(len(self.P_sym))
            ]
        res = self._valid_sol(self.solution)
        self.iter += 1
        return res
Exemple #14
0
    def on_configure_drawing_area(self, drawing_area, event):
        log(event)

        window = drawing_area.get_window()
        width = drawing_area.get_allocated_width()
        height = drawing_area.get_allocated_height()

        self.vp = Viewport(size=Size(width, height), on_changed=self._refresh)

        self.surface = window.create_similar_surface(
            cairo.CONTENT_COLOR,
            width,
            height,
        )
        self._refresh()
        return True
Exemple #15
0
 def set_exponents_counterexample(self, es):
     """
     Counterexamples x=(x0, x1, ..) will be generated such that their sum x0^i + x1^i + .. = 1 for i in es
     :param es: list of exponents
     :return: self
     """
     if isinstance(es, list):
         self._synth_counterexamples_exp = set(es)
     elif isinstance(es, (int, long, float)):
         self._synth_counterexamples_exp = {i for i in range(es)}
     else:
         log("Cannot accept exponents: %s" % str(es))
         self._error = True
     assert all(i >= 0 for i in self._synth_counterexamples_exp)
     self._max_counterexamples = len(self._synth_counterexamples_exp) + 1
     return self
Exemple #16
0
    def set_quality(self, requested_quality):
        requested_quality = G3F4AndWhatever.QUALITIES[requested_quality]
        self._navigate('https://9anime.to/')
        current_quality = self.driver.execute(
            Command.GET_LOCAL_STORAGE_ITEM, {'key': 'player_quality'})['value']
        if current_quality is not None:
            current_quality = current_quality.lower()

        if current_quality != requested_quality.lower():
            log('current quality: {}; changing to {}...'.format(
                current_quality, requested_quality))
            self.driver.execute(Command.SET_LOCAL_STORAGE_ITEM, {
                'key': 'player_quality',
                'value': requested_quality
            })
        return
Exemple #17
0
def is_valid_matrix_A(A):
    """
    :param A: matrix
    :return: True iff the parameter is a valid (system) A matrix
    """
    A = sp.Matrix(A)
    is_squared = A.shape[0] == A.shape[1]
    is_real_and_neg = all(sp.re(sp.simplify(sp.re(l))) <= 0 for l in A.eigenvals().keys())
    valid = A is not None and \
           hasattr(A, "shape") and hasattr(A.shape, "__len__") and \
           len(A.shape) == 2 and \
           is_squared and \
           is_real_and_neg
    if not valid:
        log("Invalid A: (squared, %s), (real and negative eig, %s)" % (is_squared, is_real_and_neg))
        print('A eigenvalues are: {}'.format(A.eigenvals().keys()))
    return valid
Exemple #18
0
 def _find_download_url(self, ep_page_html):
     soup = BeautifulSoup(ep_page_html, SOUP_PARSER_HTML)
     link = soup.find(attrs={'id': 'player'}).find('iframe')['src']
     # link = link[:link.index('?')]   # no 'autostart=True' parameter
     self._navigate(link)
     sleep(3)
     actual_page = self.driver.page_source
     soup = BeautifulSoup(actual_page, SOUP_PARSER_HTML)
     home_video_div = soup.find('div', id='home_video')
     links = [a['href'] for a in home_video_div.find_all('a')]
     log('links found in RapidVideo: {}'.format(links))
     for q in RapidVideo.QUALITY_ORDER:
         for link in links:
             if '&q={}p'.format(q) in link:
                 log('highest resolution found: {}p'.format(q))
                 soup = BeautifulSoup(fetch_url(link), SOUP_PARSER_HTML)
                 return soup.find('source')['src']
     raise RuntimeError('can\'t find download link')
Exemple #19
0
def diagonalize(M, real=True):
    """
    M = U D U^T
    :param M: a matrix-like object (list, NumPy/SymPy matrix)
    :param real: True iff D, U need to have only real elements
    :return: None iff M is not diagonalizable; (D, U) otherwise
    """
    M = sp.Matrix(M)
    if is_diagonal(M):
        return M, sp.eye(M.shape[0])
    try:
        # O = U * D * U.T
        D, U = M.diagonalize()[::-1]  # D, U
        if real and (len(D.atoms(sp.I)) > 0 or len(U.atoms(sp.I)) > 0):  # imaginary unit
            log("Could not diagonalize: %s. M: %s" % ("D, U have complex numbers", M))
            return None
        return D, U
    except Exception as e:
        log("Could not diagonalize: %s. M: %s" % (e, M))
        return None
Exemple #20
0
    def download_episodes(self, series_page_url, requested_episodes, quality,
                          download_path):
        series_page_html = fetch_url(series_page_url)
        available_episodes = self._find_episode_watch_links(series_page_html)

        # region quality
        if quality is None:
            quality = self.highest_quality()
            warning('no specific quality was requested; '
                    'using highest quality ({}) available in this server ({})'.
                    format(quality, self.get_server_name()))

        self.set_quality(quality)
        # endregion

        episodes_to_download = self.intersect_availible_and_requested_episodes(
            available_episodes, requested_episodes)

        ep_fmt = 'ep{ep:03d}.{extension}'
        for download_url, ep in zip(
                self._travel_episodes(series_page_url, episodes_to_download),
                episodes_to_download):
            log('found download url for episode {}!'.format(ep.ep_number))
            if not os.path.exists(download_path):
                os.makedirs(download_path)
            if type(download_url) is str:
                download_file(
                    download_url,
                    os.path.join(
                        download_path,
                        ep_fmt.format(ep=ep.ep_number, extension='mp4')),
                    self.get_headers())
            else:
                download_file_from_multiple_sources(
                    download_url,
                    os.path.join(
                        download_path,
                        ep_fmt.format(ep=ep.ep_number, extension='ts')),
                    self.get_headers())

        return
Exemple #21
0
    def check(self, P):
        """

        :param P: matrix
        :return: unsat if there have been found no counterexamples, sat if there have been found and unknown otherwise
        """

        self._solver = Solver()
        self._set_timeout()

        log("Verifier got P %s" % P)

        V, Vd = self._V, self._Vd
        for i in range(len(self._P_sym)):
            V = V.subs({
                self._P_sym[i][r, c]: P[i][r, c]
                for r in range(self.n) for c in range(self.n)
            })
            Vd = Vd.subs({
                self._P_sym[i][r, c]: P[i][r, c]
                for r in range(self.n) for c in range(self.n)
            })

        _, _, V = sympy_converter(V.doit()[0])
        _, _, Vd = sympy_converter(Vd.doit()[0])

        if V == 0 or Vd == 0:
            log("error: P=0")
            return sat

        fml = Implies(OrNotZero(self._xs_z3), And(V >= 0, Vd <= 0))
        res, c0 = self._prove(fml, exp=0)

        if res == sat:
            self._add_counterexample(c0)

            self._solver.push()  # keep fml
            self._generate_counterexamples(c0 is not None)
            self._solver.pop()

        return res
def download_file(url, file_path, headers=None):
    log('downloading: {} -> {}'.format(url, file_path))
    url = make_safe_url(url)
    headers = make_headers_with_user_agent(headers)

    download_statistics = DownloadStatistics()
    response = requests.get(url, stream=True, headers=headers)
    chunk_size = 4096
    if CONTENT_LENGTH in response.headers.keys():
        total_size = int(response.headers[CONTENT_LENGTH])
    else:
        total_size = None
    with open(file_path, 'wb') as outfile:
        for i, data in enumerate(response.iter_content(chunk_size=chunk_size)):
            outfile.write(data)
            my_reporthook(i, chunk_size, total_size, download_statistics)

    # urlretrieve(url=url, filename=file_path, reporthook=my_reporthook, data=headers)
    print()
    log('finished downloading {}'.format(file_path))
    return
Exemple #23
0
    def _prove(self, fml=None, exp=0, orth=False):
        if fml is not None:
            self._solver.add(Not(fml))
            self._solver.add(self._x_precision)

        if orth:
            self._solver.add(self._orthogonal_counterexamples(self._xs_z3))

        if exp > 0:
            self._solver.add(self._sum_powers(self._xs_z3, exp) == 1)

        log("s %s" % self._solver)
        res, self._has_timedout = check_with_timeout(self._solver,
                                                     self._timeout)
        counterexample = None

        if res == unknown and not self._has_timedout:
            self._error = True
        elif res == sat:
            model = self._solver.model()
            counterexample = model_to_vector(model,
                                             self._xs_z3,
                                             N=self.n,
                                             target_z3=self._z3_learner)
            log("counterexample found #%s %s" % (str(self._iter + 1), model))
        else:
            log("proved")
        return res, counterexample
Exemple #24
0
    def _add_constraint(self, counterexample):
        for V_sym, Vd_sym in izip(self.V_list_sym, self.Vd_list_sym):
            V = V_sym.subs(
                {x: c
                 for x, c in izip(self._xs_sym, counterexample)})
            Vd = Vd_sym.subs(
                {x: c
                 for x, c in izip(self._xs_sym, counterexample)})

            _, __, V = convert.sympy_converter(V,
                                               var_map=self.P_map,
                                               target=convert.TARGET_SOLVER)
            _, __, Vd = convert.sympy_converter(Vd,
                                                var_map=self.P_map,
                                                target=convert.TARGET_SOLVER)
            try:
                self.model.addConstr(V >= consts.ZERO)
                self.model.addConstr(Vd <= -consts.ZERO)
                self.model.update()
            except Exception as e:
                log('Could not add counterexample: %s. (V:%s, Vd:%s). Exception: %s'
                    % (counterexample, V, Vd, e))
Exemple #25
0
def find_series_url_by_name(name):
    results = [
        url for _name, url in zip(*search_series_urls_by_name(name))
        if name == sanitize_name(_name)
    ]

    if len(results) == 0:
        log("watching page of {} couldn't be found. please check for typos or switch to names in opposite language (english/japanese)"
            .format(name))
        raise Exception()
    elif len(results) > 1:
        log("more than 1 result were found for {}, choosing the first one;".
            format(name))

    result = results[0]
    log('found watching page of {}: {}'.format(name, result))
    return result
Exemple #26
0
    def __init__(self, dungeon, start_tile, creatures, objects):
        print creatures

        super(Level, self).__init__()
        self.objects = objects
        self.creatures = creatures
        self.dungeon = dungeon
        self.width = len(dungeon[0])
        self.height = len(dungeon)

        for y in range(self.height):
            for x in range(self.width):
                if self.dungeon[y][x]:
                    self.add(self.dungeon[y][x])

        for obj in self.objects:
            self.add(obj)
            tile = self.get(obj.x, obj.y)
            if not tile.object_on:
                tile.object_on = obj

        for creature in self.creatures:
            self.add(creature)
            tile = self.get(creature.x, creature.y)
            if not tile.creature_on:
                tile.creature_on = creature

        # Player here
        self.start_pos = dungeon[start_tile[1]][start_tile[0]].center
        self.player = Player(self.start_pos)
        self.add(self.player)
        self.creatures.append(self.player)

        self.collman = cm.CollisionManagerGrid(0, WINDOW_WIDTH, 0, WINDOW_HEIGHT, TILE_SIZE, TILE_SIZE)

        self.schedule(self.update)


        log("Loading Level object, map sise: %i:%i" % (self.width, self.height))
        log("Count of creatures: %i. Count of Objects: %i" % (len(self.creatures), len(self.objects)) )
        for x in self.get_children():
            if x.type != OBJECT_TILE:
                log(str(x))
Exemple #27
0
 def __init__(self, position, img):
     super(Enemy, self).__init__(position, img)
     log("Initialize Enemy object. Position: %i:%i" % position)
     self.speed = TILE_SIZE
     self.minimap_color = (250, 0, 0)
Exemple #28
0
 def post_tweet(self, text: str) -> Status:
     log(f"Fake Tweet Sent: \"{text}\"")
     status = Status()
     status._json = {"text": f"{text}"}
     return status
Exemple #29
0
from src.cegis import Cegis
from src.common import createPoly, createFX
from src.linearize import linearize
from src.log import log
from src.z3_learner import IterativeZ3Learner

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="Synthesize Lyapunov functions")
    parser.add_argument('-e', '--exponent')
    parser.add_argument('-n', '--dimension')

    args = parser.parse_args(sys.argv[1:])
    e = args.exponent
    n = args.dimension

    log("Running with e=%s n=%s" % (e, n))
    if e is None or n is None:
        log("e and n must be set")
        sys.exit(1)
    e = int(e)
    n = int(n)

    roots = [- randint(0, 9) for _ in range(n)]
    p = sp.Poly(createPoly(roots))
    fx = createFX(p)

    A = linearize(fx)
    c = Cegis(A)
    c.set_learners([IterativeZ3Learner])
    assert c.solve(exponent=e)
    P = c.get_P()
Exemple #30
0
 def on_exit(self):
     super(GameLayer, self).on_exit()
     log("On exit call from game_layer")
Exemple #31
0
 def on_zoom_in_pressed(self, *args):
     self.vp.zoom_in()
     log(self.vp)
Exemple #32
0
    def _solve(self, min_sum=None, max_sum=None):
        m0 = self.model.copy()

        res = {}

        try:
            # if min_sum is not None:
            #     sum_vars = reduce(lambda rem, item: m0.getVarByName(str(item)) + rem, self.P_vars, 0)
            #     m0.addConstr(sum_vars >= min_sum)
            #
            # if max_sum is not None:
            #     if min_sum is None:  # sum_vars already computed
            #         sum_vars = reduce(lambda rem, item: m0.getVarByName(str(item)) + rem, self.P_vars, 0)
            #     m0.addConstr(sum_vars <= max_sum)
            #
            # if self._close_diagonal_by > 0:
            #     diag = diagonal_names(self.n, prefix='P')
            #     for p in diag:
            #         for q in diag:
            #             if p != q:
            #                 vp = m0.getVarByName(p)
            #                 vq = m0.getVarByName(q)
            #                 m0.addConstr(vp - vq <= self._close_diagonal_by)
            #                 m0.addConstr(vq - vp <= self._close_diagonal_by)

            # objective = reduce(lambda rem, item: m0.getVarByName(str(item)) + rem, self.P_sym, 0)
            # m0.setObjective(objective, gp.GRB.MINIMIZE)  # optional

            self._set_timeout(m0)
            m0.update()
            self._debug_model(m0)

            m0.optimize()
            if m0.status == gp.GRB.Status.TIME_LIMIT:
                log("timed out")
                self._has_timedout = True

            else:
                # min_val = float('inf')
                for v in m0.getVars():
                    log("%s %g" % (v.varName, v.x))
                    res[v.varName] = v.x
                    # if v.x > 0:
                    #     min_val = min(min_val, v.x)

                # if self._multiply_by_inv_min:
                #     inv_min = 1 / min_val
                #     res = {k: v * inv_min for k, v in res.items()}

                log('Obj: %g' % m0.objVal)
                self._error = False

        except gp.GurobiError as e:
            log("Error code %d : %s" % (e.errno, e))
            self._error = True

        except AttributeError as e:
            log("Attribute error: %s" % e)
            self._error = True

        if self._error:
            log("Could not solve the system with min/max_sum %s %s" %
                (min_sum, max_sum))
            # if max_sum is not None and min_sum is not None:
            #     return self._solve(min_sum=None, max_sum=None)
            self._error = True
            return unsat, self._has_timedout

        res_matrices = []
        for P in self.P_sym:
            res_matrices.append(
                P.subs({self.P_sym_map[p]: res[p]
                        for p in res}))
        return res_matrices, self._has_timedout
Exemple #33
0
    def make_random_room(self):
        assert len(self.rooms) > 0, "A main room must me created"

        prefer_direction = set()
        if (self.width > self.height):
            prefer_direction.add(UP)
            prefer_direction.add(DOWN)
        else:
            prefer_direction.add(RIGHT)
            prefer_direction.add(LEFT)

        rooms = filter(lambda x: len(x.free_direction) > 0 and len(set(x.free_direction) & prefer_direction) > 0,
                       self.rooms)
        # TODO: ставить комнату в непредпочтитетльную сторону при остутствии предпочтительных?

        room_from = choice(rooms)
        dirs = set(room_from.free_direction) & prefer_direction
        direction = choice(list(dirs))
        door_from = room_from.get_random_wall_pos(direction)

        room_new = None
        for i in range(GEN_MAX_TRY_PLACE_ROOM):
            hall_len = randint(HALL_MIN_LENGTH, HALL_MAX_LENGTH)
            door_new = get_new_pos_by_direction(door_from[0], door_from[1], hall_len, direction)

            room_width = randint(ROOM_MIN_WIDTH, ROOM_MAX_WIDTH)
            # if (room_width == 3):
            #     room_height = 3
            # else:
            room_height = randint(ROOM_MIN_HEIGHT, ROOM_MAX_HEIGHT)
            room_x = door_new[0]
            room_y = door_new[1]
            if (direction == UP):
                room_x -= room_width // 2
                room_y -= room_height - 1
            elif (direction == RIGHT):
                room_y -= room_height // 2
            elif (direction == DOWN):
                room_x -= room_width // 2
            elif (direction == LEFT):
                room_y -= room_height // 2
                room_x -= room_width - 1

            room_new = Room(room_x, room_y, room_width, room_height)
            hall_new = Hall(door_from, door_new)

            for room in self.rooms:
                if room_new.overlaps(room):
                    room_new = None
                    break

        # If new room was not created
        if (room_new == None):
            log("Cannot create new room, remove aviable direction")
            room_from.free_direction.remove(direction)
            return

        room_from.free_direction.remove(direction)
        room_new.free_direction.remove((direction + 2) % 4)

        self.halls.append(hall_new)
        self.rooms.append(room_new)
        self.compile()
Exemple #34
0
 def on_left_pressed(self, *args):
     self.vp.move(Direction.LEFT)
     log(self.vp)
Exemple #35
0
 def on_rotate_counterclockwise_pressed(self, *args):
     self.vp.rotate_counterclockwise()
     log(self.vp)
Exemple #36
0
 def on_zoom_out_pressed(self, *args):
     self.vp.zoom_out()
     log(self.vp)
Exemple #37
0
 def _debug_model(self, m0, filename="/tmp/gurobi.lp"):
     if self.debug_model:
         m0.write(filename)
         with open(filename) as content:
             log(content.read())
Exemple #38
0
 def on_down_pressed(self, *args):
     self.vp.move(Direction.DOWN)
     log(self.vp)
Exemple #39
0
 def on_right_pressed(self, *args):
     self.vp.move(Direction.RIGHT)
     log(self.vp)