def display_field(screen: curses.window, coords, player: Player, my: bool, game: Game) -> None: """ function for printing fields on the console """ # obtaining field field = player.my_field if my else player.enemy_field # obtaining sliding window borders start_left = field.border_left start_top = field.border_top iter_row = start_top iter_col = start_left for y, x, symb in coords: # replacing current active element with the cursor if iter_row == field.y_cur and iter_col == field.x_cur: screen.addstr(y, x, Field.CURSOR) else: screen.addstr(y, x, symb) # printing numbers on the top of the sliding window if iter_row == start_top: num_zeros = len(str(game.map_width)) - len(str(iter_col)) power_of_ten = 10**len(str(game.map_width)) screen.addstr( y - 1, x, "0" * num_zeros + str(iter_col) + " " if iter_col < power_of_ten else str(iter_col) + ' ') # printing numbers on the left of the sliding window if iter_col == start_left: screen.addstr(y, x - len(str(iter_row)), str(iter_row)) iter_col += 1 if iter_col == start_left + Field.WINDOW_WIDTH: iter_col = start_left iter_row += 1 screen.refresh()
async def fire( canvas: curses.window, start_row: typing.Union[float, int], start_column: typing.Union[float, int], max_y: int, max_x: int, rows_speed: typing.Union[float, int] = -0.3, columns_speed: typing.Union[float, int] = 0, ): """Display animation of gun shot. Direction and speed can be specified.""" row, column = start_row, start_column canvas.addstr(round(row), round(column), "*") await asyncio.sleep(0) canvas.addstr(round(row), round(column), "O") await asyncio.sleep(0) canvas.addstr(round(row), round(column), " ") row += rows_speed column += columns_speed symbol = "-" if columns_speed else "|" curses.beep() while 0 < row < max_y and 0 < column < max_x: canvas.addstr(round(row), round(column), symbol) await asyncio.sleep(0) canvas.addstr(round(row), round(column), " ") row += rows_speed column += columns_speed
def input_thread(inputw: curses.window, roomid: str): while True: msg = inputw.getstr() inputw.clear() # send msg send_danmu(roomid=roomid, msg=msg)
def draw_frame(canvas: curses.window, start_row: int, start_column: int, text: str, negative: bool = False): """Draw multiline text fragment on canvas. Erase text instead of drawing if negative=True is specified.""" rows_number, columns_number = canvas.getmaxyx() for row, line in enumerate(text.splitlines(), round(start_row)): if row < 0: continue if row >= rows_number: break for column, symbol in enumerate(line, round(start_column)): if column < 0: continue if column >= columns_number: break if symbol == " ": continue # Check that current position it is not in a lower right corner of the window # Curses will raise exception in that case. Don`t ask why… # https://docs.python.org/3/library/curses.html#curses.window.addch if row == rows_number - 1 and column == columns_number - 1: continue symbol = symbol if not negative else " " canvas.addch(row, column, symbol)
def start_app(window: curses.window, messages): window.keypad(False) curses.init_pair(1, curses.COLOR_WHITE, 18) curses.init_pair(2, curses.COLOR_WHITE, 21) termulator = Termulator(window, messages) termulator.run()
def curses_program(screen: curses.window): y, x = screen.getmaxyx() o = Ocean(x - 1, y - 1) screen.clear() curses.resizeterm(y, x) for instruct in data: screen.clear() curr_north, curr_east = c.north, c.east c.execute_instruction(instruct) new_north, new_east = c.north, c.east if new_north < curr_north: for i in range(abs(curr_north - new_north)): o.move_ocean_south() o.draw(screen) else: for i in range(abs(curr_north - new_north)): o.move_ocean_north() o.draw(screen) if new_east < curr_east: for i in range(abs(curr_east - new_east)): o.move_ocean_west() o.draw(screen) else: for i in range(abs(curr_east - new_east)): o.move_ocean_east() o.draw(screen)
def draw(self, screen: curses.window): """(Re)draw the ball""" # Erase the ball from the old position screen.addstr(self.old_y, self.old_x, ' ') # Draw the ball on the new position screen.addstr(self.y, self.x, 'O')
def main(win: curses.window) -> None: win.keypad(True) net = Network(receiveCallback=receptionCallback, eventCallback=eventCallback) net.startReceptionThread() windowThread = threading.Thread(target=threadRefreshScreen, args=(win, )) windowThread.daemon = True windowThread.start() keyThread = threading.Thread(target=threadGetKeys, args=( win, net, )) keyThread.daemon = True keyThread.start() periodicThread = threading.Thread(target=threadPeriodic, args=(net, )) periodicThread.daemon = True periodicThread.start() keyThread.join() while True: time.sleep(2.0)
def main(stdscr: curses.window): stdscr.clear() curses_utils = CursesUtils(stdscr) curses_utils.draw_start_screen() board = Board(height=20, width=10) GameLoop(board, curses_utils, tick_frequency=0.5).run()
def sprite_init(scr: c.window, text: c.window, sprite: dict, erase=True): show_sprite(scr, sprite['image'], erase) for group in sprite['lines']: for i, line in enumerate(group): text.addstr(i, 0, line) text.getch() text.erase() scr.erase() scr.refresh()
def colorize(stdscr: Window, color: Color) -> Generator[Window, None, None]: """ Context manager to make colorizing operations easier. """ pair = color_pair(color) if has_colors() else None if pair is not None: stdscr.attron(pair) yield stdscr if pair is not None: stdscr.attroff(pair)
def start_game(screen: curses.window, mheight: int, mwidth: int) -> None: """ function for starting a new game mheight: map height mwidth: map width """ # reading player's name screen.clear() print_to_center(screen, ['Enter your name: ']) screen.refresh() curses.curs_set(1) curses.echo() name = screen.getstr().decode("utf-8") curses.curs_set(0) curses.noecho() screen.clear() print_to_center(screen, ['Preparing the game...']) screen.refresh() # initializing a new game game = Game(mheight, mwidth) # making necessary preparations game.prepare_game(player_name=name) # playing the game play_game(screen=screen, game=game)
def draw_snek(scr: curses.window, snake: list, direction: tuple): for y, x in snake[1:]: scr.addstr(y, x, 's') if direction == NORTH: scr.addstr(snake[0][0], snake[0][1], '^') elif direction == SOUTH: scr.addstr(snake[0][0], snake[0][1], 'v') elif direction == EAST: scr.addstr(snake[0][0], snake[0][1], '>') elif direction == WEST: scr.addstr(snake[0][0], snake[0][1], '<')
def threadGetKeys(win: curses.window, net: Network) -> None: while 1: try: key = win.getkey() win.addstr(" KEY = " + key) GlobVar.currentMovement = "Stop" if GlobVar.connectedToPi: if key == "KEY_UP": GlobVar.currentMovement = "Go Forward" GlobVar.last_answer = net.robotGoForward() elif key == "KEY_DOWN": GlobVar.currentMovement = "Go Backward" GlobVar.last_answer = net.robotGoBackward() elif key == "KEY_RIGHT": GlobVar.currentMovement = "Go Right" GlobVar.last_answer = net.robotGoRight() elif key == "KEY_LEFT": GlobVar.currentMovement = "Go Left" GlobVar.last_answer = net.robotGoLeft() elif key == " ": GlobVar.currentMovement = "Stop" GlobVar.last_answer = net.robotStop() elif key == "R" or key == 'r': GlobVar.last_answer = net.robotReset() GlobVar.dumberStarted = False elif key == "U" or key == 'u': GlobVar.last_answer = net.robotStartWithoutWatchdog() if GlobVar.last_answer == net.ACK: GlobVar.dumberStarted = True else: GlobVar.dumberStarted = False elif key == "W" or key == 'w': GlobVar.last_answer = net.robotStartWithWatchdog() if GlobVar.last_answer == net.ACK: GlobVar.dumberStarted = True else: GlobVar.dumberStarted = False elif key == "C" or key == 'c': GlobVar.last_answer = net.robotCloseCom() GlobVar.connectedToDumber = False GlobVar.dumberStarted = False elif key == "O" or key == 'o': GlobVar.last_answer = net.robotOpenCom() if GlobVar.last_answer == net.ACK: GlobVar.connectedToDumber = True else: GlobVar.connectedToDumber = False #if key == os.linesep or key =='q' or key == 'Q': # break except Exception as e: GlobVar.exceptionmsg = "Exception received: " + str(e)
def print_to_center(screen: curses.window, messages) -> None: """ function for printing messages to the center of the screen :param screen: :param messages: list-like iterable element """ sheight, swidth = screen.getmaxyx() for index, message in enumerate(messages): screen.addstr(sheight // 2 + index, swidth // 2 - len(message) // 2, message)
async def blink( canvas: curses.window, row: int, column: int, delay: int, symbols: typing.Sequence[str] = "+*.:", ): while True: symbol = random.choice(symbols) canvas.addstr(row, column, symbol, curses.A_DIM) for _ in range(delay): await asyncio.sleep(0) canvas.addstr(row, column, symbol) for _ in range(delay): await asyncio.sleep(0) canvas.addstr(row, column, symbol, curses.A_BOLD) for _ in range(delay): await asyncio.sleep(0) canvas.addstr(row, column, symbol) for _ in range(delay): await asyncio.sleep(0)
def process_shooting(screen: curses.window, cur_player: Player, game: Game, is_human: bool): """ function for processing current player's shot """ # shoot succ, hit = game.player_shoot() # if player chose an inappropriate cell, do nothing if not succ: game.turn -= 1 else: screen.clear() message = "You missed" if is_human else "AI missed" if hit: message = "You hit enemy ship" if is_human else "AI hit enemy ship" game.check_victory() game.turn -= 1 # printing the result of the shot to the screen if is_human: print_to_center(screen, [message]) else: y_shot = cur_player.enemy_field.y_cur x_shot = cur_player.enemy_field.x_cur print_to_center(screen, [f"AI has shot to {y_shot} {x_shot}", message]) screen.refresh() screen.getch() screen.refresh()
def render_welcome_screen(window: curses.window) -> None: window.clear() window.addstr(0, 10, "jocus 0.0.1") window.addstr(1, 10, "collect coins and you win") window.addstr(3, 10, "press any key to start...") window.refresh()
def start(self, stdscr: curses.window): self.stdscr = stdscr self.mainwin = stdscr.subwin(20, 100, 0, 0) self.chatwin = stdscr.subwin(1, 80, 20, 1) curses.halfdelay(1) curses.curs_set(False) while True: try: self.stdscr.erase() self.draw() self.stdscr.refresh() self.controller.chat() except KeyboardInterrupt: break
def __init__(self, _x, _y, _window: curses.window, _orientation: int = 0, _arr: Union[None, list] = None, _score=4): """ класс фигуры ## ## :param _x: :param _y: :param _window: window_magic_creater :param _orientation: :param _arr: :param _score: """ self.x = _x self.y = _y self.window = _window self.max_x = _window.getmaxyx()[1] - 2 self.max_y = _window.getmaxyx()[0] - 2 self.exist = True self.arr = _arr self.score = _score self.orientation = _orientation
def read_controls(canvas: curses.window) -> typing.Tuple[int, int, bool]: """Read keys pressed and returns tuple witl controls state.""" rows_direction = columns_direction = 0 space_pressed = False while True: pressed_key_code = canvas.getch() if pressed_key_code == -1: # https://docs.python.org/3/library/curses.html#curses.window.getch break if pressed_key_code == UP_KEY_CODE: rows_direction = -1 if pressed_key_code == DOWN_KEY_CODE: rows_direction = 1 if pressed_key_code == RIGHT_KEY_CODE: columns_direction = 1 if pressed_key_code == LEFT_KEY_CODE: columns_direction = -1 if pressed_key_code == SPACE_KEY_CODE: space_pressed = True return rows_direction, columns_direction, space_pressed
def display_game(screen: curses.window, cur_player: Player, game: Game): """ function for printing game on the console """ # obtain coordinates for displaying fields sheight, swidth = screen.getmaxyx() my_coords, enemy_coords = game.display_field(sheight=sheight, swidth=swidth) # print fields and stats on the console screen.clear() display_field(screen, my_coords, cur_player, True, game=game) display_field(screen, enemy_coords, cur_player, False, game=game) stats = game.num_alive_ships() display_stats(screen=screen, statistics=stats[0], my=True, game=game) display_stats(screen=screen, statistics=stats[1], my=False, game=game)
def update(self, window: curses.window) -> None: self.player.move(window.getkey()) self.player.maybe_grab_coin(self.coins) if not self.coins and not self.is_finished: self.is_finished = True voice.say("оа") voice.say("молодец")
def main(screen: curses.window, mheight: int, mwidth: int): # removing cursor curses.curs_set(0) # setting color for menu curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_WHITE) # things to be printed prev_game = load_game() str_start_game = "Start New Game" str_load_game = "Load Game" str_exit = "Exit" menu_items = [str_load_game, str_start_game, str_exit ] if prev_game else [str_start_game, str_exit] cur_index = 0 # selected menu item display_menu(screen, menu_items, cur_index) while True: # listen to input key = screen.getch() # handling navigation if key == curses.KEY_UP and cur_index > 0: cur_index -= 1 elif key == curses.KEY_DOWN and cur_index < len(menu_items) - 1: cur_index += 1 # handling Enter button elif key == curses.KEY_ENTER or key in [10, 13]: cur_item = menu_items[cur_index] if cur_item == str_start_game: # adjust length of the symbols Field.recal_sybms(len(str(mwidth))) # start new game start_game(screen, mheight, mwidth) elif cur_item == str_load_game: # adjust length of the symbols Field.recal_sybms(len(str(prev_game.map_width))) # continue last saved game play_game(screen, game=prev_game) elif cur_item == str_exit: return screen.clear() display_menu(screen, menu_items, cur_index)
def draw(self, screen: curses.window, arena: Arena): """Draw player on the screen's defined y position""" # clear player's row for i in range(arena.y + 1, arena.bound_y - 1): screen.addstr(i, self.x, ' ') # draw the player screen.addstr(self.y - 1, self.x, '|') screen.addstr(self.y, self.x, '|') screen.addstr(self.y + 1, self.x, '|')
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)
def render(self, stdscr: Window) -> None: """ Render the unit to screen. """ # Cache the encoded lines, no sense redoing the work if not self._lines: lines = self.icon.splitlines() self._lines = [l.encode(CODEC) for l in lines] with colorize(stdscr, self.color): for offset_y, line in enumerate(self._lines): try: stdscr.addstr(self.y + offset_y, self.x, line) except curses.error as err: raise ValueError(f"y={self.y}, x={self.x}: {line}") from err # Unit is no longer dirty self._dirty = False
def process_human_move(screen: curses.window, cur_player: Player, game: Game): """ function for listening to player's input and taking appropriate actions """ buttons_move_cursor = [ curses.KEY_UP, curses.KEY_DOWN, curses.KEY_LEFT, curses.KEY_RIGHT, ord('w'), ord('s'), ord('a'), ord('d') ] buttons_shoot = [curses.KEY_ENTER, 10, 12, 13, 14] while True: # get fields my_field = cur_player.my_field enemy_field = cur_player.enemy_field display_game(screen, cur_player, game) # listen to the input key = screen.getch() # move corresponding cursors if key in buttons_move_cursor: move_cursor(key, my_field=my_field, enemy_field=enemy_field, game=game) # shoot at the current location of the cursor elif key in buttons_shoot: process_shooting(screen, cur_player, game, is_human=True) break # save the game elif key == ord('o'): screen.clear() save_game(game) print_to_center(screen, ['The game was saved']) screen.getch() game.turn -= 1 break
def show_sprite(scr: c.window, sprite: list, erase=True): if erase: scr.erase() scr_y, scr_x = scr.getmaxyx() begin_y = scr_y // 2 - len(sprite) // 2 begin_x = scr_x // 2 - len(sprite[0]) // 2 for i, s in enumerate(sprite): scr.addstr(begin_y + i, begin_x, s) scr.refresh()
def play_game(screen: curses.window, game: Game) -> None: """ function for simulating the game """ while not game.is_finished: # obtaining the current player cur_player = game.players[game.turn % 2] # if human if cur_player.is_human: process_human_move(screen, cur_player, game) screen.refresh() # if current player is AI else: process_ai_move(screen, cur_player, game) screen.refresh() game.turn += 1 declare_winner(screen, game)