Example #1
0
def draw(canvas: curses.window):
    canvas.border()
    canvas.nodelay(True)

    # https://docs.python.org/3/library/curses.html#curses.window.getmaxyx
    window_height, window_width = canvas.getmaxyx()
    # rows and columns greater by one then real window size
    max_y, max_x = window_height - 1, window_width - 1

    curses.curs_set(False)

    # Reducing max dimensions by 2 allows to avoid "curses.error"
    stars_max_y = window_height - 2
    stars_max_x = window_width - 2
    coroutines = [
        blink(
            canvas,
            random.randint(1, stars_max_y),  # stars mustn't appear on border
            random.randint(0, stars_max_x),
            delay=random.randint(1, 20),
        ) for _ in range(random.randint(100, 200))
    ]

    coroutines.append(animate_rocket_flight(canvas, max_y, max_x))

    while coroutines:
        for coro in coroutines.copy():
            try:
                coro.send(None)
            except StopIteration:
                coroutines.remove(coro)
        canvas.refresh()
        time.sleep(TIC_TIMEOUT)
Example #2
0
def show_msg(screen: curses.window, screen_height: int, screen_width: int,
             message: str):
    """Generic routine to generate an error message"""
    screen.addstr(screen_height // 2, screen_width // 2 - len(message) // 2,
                  message)
    screen.nodelay(0)
    screen.getch()
    sys.exit(0)
Example #3
0
def run_game(scr: curses.window):
    curses.curs_set(0)
    scr.nodelay(True)
    game_state = ""
    status_w: int = 25
    maxy = scr.getmaxyx()[0] - 1
    maxx = scr.getmaxyx()[1]

    midy = int(maxy / 2)
    midx = int(maxx / 2)
    snake: list = []
    for i in range(SNAKE_LEN):
        snake.append((midy, status_w + midx + i))
    direction = WEST
    apples: list = []
    score = 0
    while True:
        scr.erase()
        draw_statusbar(scr, (maxy - 1, maxx), status_w, score)
        draw_snek(scr, snake, direction)
        draw_apples(scr, apples)
        # ++ Tick ++
        key = scr.getch()
        direction, game_state = process_key(key, direction)
        snake = move_snake(snake, direction)
        snake = portals(snake, direction, status_w + 2, (maxy - 1, maxx))
        snake, apples, nscore = eat_apples(snake, apples)
        apples = create_apples(snake, apples, MAX_APPLES - len(apples),
                               status_w, (maxy, maxx))
        score += nscore
        if game_state != "":
            return game_state, 0
        # -- Tick --
        scr.refresh()
        if check_loss(snake):
            curses.napms(1000)
            return "end", score
        curses.napms(100)
Example #4
0
def main(scr: curses.window):
    # Remove blinking cursor
    curses.curs_set(0)

    # Get screen's height and width & check if the screen is big enough
    sh, sw = scr.getmaxyx()
    if sh < SCR_H + 2 or sw < SCR_W + 2: show_msg(scr, sh, sw, MSG_SCR_SMALL)

    # Get args
    mode, ip, port, plname = get_args(scr, sh, sw)

    # Start socket for host/join mode
    skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    skt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    if mode == 'host':
        try:
            skt.bind((ip, port))
            skt.listen(1)
        except:
            show_msg(scr, sh, sw, MSG_CANT_HOST)
    else:
        try:
            skt.connect((ip, port))
        except:
            show_msg(scr, sh, sw, MSG_CANT_JOIN)

    # Setup keys
    up_key = set((curses.KEY_UP, ord('k'), ord('K'), ord('w'), ord('W')))
    down_key = set((curses.KEY_DOWN, ord('j'), ord('J'), ord('s'), ord('S')))
    quit_key = set((ord('q'), ord('Q')))
    keys = {'up_key': up_key, 'down_key': down_key, 'quit_key': quit_key}

    # Activate nodelay (so getch won't interrupt the execution)
    scr.nodelay(1)
    scr.timeout(33)

    # Create arena
    arena = Arena(0, 1, SCR_W, SCR_H)

    # Create players
    player1 = Player('left', arena)
    player2 = Player('right', arena)

    # Create the ball
    ball = Ball(arena.bound_x // 2, arena.bound_y // 2, choice((-1, 1)),
                choice((-1, 0, 1)))

    # Connection accepted
    accepted = False

    # Waiting connection message
    scr.addstr(sh // 2, sw // 2 - len(MSG_WAITING) // 2, MSG_WAITING)
    scr.refresh()
    scr.addstr(sh // 2, 0, " " * sw)

    # Draw the arena
    arena.draw(scr)

    # Game loop
    while True:
        # Start networking
        if mode == 'host':
            if not accepted:
                # Accept client
                try:
                    clskt, claddr = skt.accept()
                except:
                    sys.exit()
                # Write host name on the screen and send it
                scr.addstr(0, 0, plname)
                clskt.send(plname.encode().ljust(16))
                # Receive client name and add to screen
                try:
                    clname = clskt.recv(16).strip().decode()[:16]
                except:
                    show_msg(scr, 0, SCR_W, MSG_DISCONN)
                scr.addstr(0, SCR_W + 1 - len(clname), clname)
                # Mark client as accpeted
                accepted = True
        else:
            if not accepted:
                # Receive host name and add to screen
                try:
                    scr.addstr(0, 0, skt.recv(16).strip().decode()[:16])
                except:
                    show_msg(scr, 0, SCR_W, MSG_DISCONN)
                # Write client name on the screen and send it
                scr.addstr(0, SCR_W + 1 - len(plname), plname)
                skt.send(plname.encode().ljust(16))
                accepted = True

        # Draw the game score
        scr.addstr(0, SCR_W // 2 - 6, str(player1.score))
        scr.addstr(0, SCR_W // 2 + 6, str(player2.score))

        # Draw players
        player1.draw(scr, arena)
        player2.draw(scr, arena)

        # Draw ball (host) and check goals
        if mode == 'host':
            ball.move(player1, player2, arena)
            ball.draw(scr)

        # Get button press, perform action and send over the network
        if mode == 'host':
            action = get_action(scr, arena, player1, keys, plname == 'AI', {
                'p1': player1.y,
                'p2': player2.y,
                'ball': ball.upload()
            })
            if action == 'up' and player1.y > arena.y + 3:
                player1.move('up')
            elif action == 'down' and player1.y < arena.bound_y - 3:
                player1.move('down')
            elif action == 'quit':
                clskt.close()
                sys.exit(0)
            else:
                action = None

            # Send ball and host's action
            try:
                clskt.send(pickle.dumps((str(action), ball.upload())))
                player2_action = clskt.recv(16).strip().decode()
                if player2_action == 'up' and player2.y > arena.y + 3:
                    player2.move('up')
                elif player2_action == 'down' and player2.y < arena.bound_y - 3:
                    player2.move('down')
            except:
                show_msg(scr, 0, SCR_W, MSG_DISCONN)

        else:
            action = get_action(scr, arena, player2, keys, plname == 'AI', {
                'p1': player1.y,
                'p2': player2.y,
                'ball': ball.upload()
            })
            if action == 'up' and player2.y > arena.y + 3:
                player2.move('up')
            elif action == 'down' and player2.y < arena.bound_y - 3:
                player2.move('down')
            elif action == 'quit':
                skt.close()
                sys.exit(0)
            else:
                action = None

            # Send client's action, then get ball and host's position
            try:
                skt.send(str(action).encode().ljust(16))
                player1_action, ball_info = pickle.loads(
                    skt.recv(sys.getsizeof(('down', ball.upload())) * 3))
                if player1_action == 'up' and player1.y > arena.y + 3:
                    player1.move('up')
                elif player1_action == 'down' and player1.y < arena.bound_y - 3:
                    player1.move('down')
                ball.download(ball_info)
            except:
                show_msg(scr, 0, SCR_W, MSG_DISCONN)

            # Draw ball (join) and check goals
            ball.move(player1, player2, arena)
            ball.draw(scr)

        scr.refresh()
Example #5
0
def main(screen: curses.window):
    curses.mousemask(1)
    screen.nodelay(1)
    curses.curs_set(0)
    start(screen)
    chat_page(screen)