Skip to content

Instantly share code, notes, and snippets.

@aq1
Created May 20, 2024 06:31
Show Gist options
  • Save aq1/527ade2019062c95e12755eafad4f26a to your computer and use it in GitHub Desktop.
Save aq1/527ade2019062c95e12755eafad4f26a to your computer and use it in GitHub Desktop.
import curses
import os
import random
import sys
def get_cell(row_index: int, column_index: int, player: tuple[int, int], target: tuple[int, int]):
if player == (row_index, column_index):
return '¤'
if target == (row_index, column_index):
return '*'
return '·'
def draw_field(
stdscr,
offset: tuple[int, int],
field: tuple[int, int],
player: tuple[int, int],
target: tuple[int, int],
):
for row_index in range(field[0] + 1):
stdscr.move(row_index + offset[0], offset[1])
stdscr.clrtoeol()
for column_index in range(field[1] + 1):
stdscr.addch(get_cell(row_index, column_index, player, target))
stdscr.addch('\n')
def draw_title(
stdsrc,
row: int,
terminal_width: int,
score: int,
):
title = f'hjkl to move q to quit. Score: {score}'
stdsrc.addstr(row, terminal_width // 2 - len(title) // 2, f'{title}\n')
def get_player_position(player: tuple[int, int], field: tuple[int, int], key: str):
row, column = player
field_rows, field_columns = field
if key == ord('k'):
return max(0, row - 1), column
if key == ord('j'):
return min(field_rows, row + 1), column
if key == ord('h'):
return row, max(0, column - 1)
if key == ord('l'):
return row, min(field_rows, column + 1)
return player
def get_target_position(field: tuple[int, int], player: tuple[int, int]):
while True:
target = random.randint(0, field[0]), random.randint(0, field[1])
if target != player:
return target
def main(stdscr):
size = 10
if len(sys.argv) > 1 and sys.argv[1].isdigit():
size = max(5, int(sys.argv[1]))
field = size, size
player = size // 2, size // 2
target = get_target_position(field, player)
score = 0
stdscr.clear()
stdscr.refresh()
while True:
terminal_size = tuple(os.get_terminal_size())
offset = (terminal_size[1] // 2) - (field[0] // 2), (terminal_size[0] // 2) - (field[1] // 2)
draw_title(
stdscr,
row=offset[0] - 1,
terminal_width=terminal_size[0],
score=score,
)
draw_field(stdscr, field=field, offset=offset, player=player, target=target)
stdscr.refresh()
key = stdscr.getch()
if key == ord('q'):
break
player = get_player_position(field=field, player=player, key=key)
if player == target:
score += 1
target = get_target_position(field=field, player=player)
if __name__ == "__main__":
try:
curses.wrapper(main)
except KeyboardInterrupt:
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment