aboutsummaryrefslogtreecommitdiff
path: root/sweepy.py
diff options
context:
space:
mode:
Diffstat (limited to 'sweepy.py')
-rwxr-xr-xsweepy.py243
1 files changed, 243 insertions, 0 deletions
diff --git a/sweepy.py b/sweepy.py
new file mode 100755
index 0000000..bc173f5
--- /dev/null
+++ b/sweepy.py
@@ -0,0 +1,243 @@
+#!/usr/bin/env python3
+
+import curses
+from logic import MinesweeperLogic
+from ouija import Ouija, Tile
+from pathlib import Path
+import os
+
+HOME = Path(os.environ["HOME"])
+SWEEPY_ROOT = ".sweepy"
+MY_SWEEPY_ROOT = HOME / SWEEPY_ROOT
+MY_SWEEPY_WON = MY_SWEEPY_ROOT / "won"
+MY_SWEEPY_LOST = MY_SWEEPY_ROOT / "lost"
+
+def generate_tiles():
+
+ tiles = []
+ tiles.append(Tile("0", ""))
+ tiles.append(Tile("1", "1", Ouija.COLORS["DEFAULT"], curses.A_BOLD))
+ tiles.append(Tile("2", "2", Ouija.COLORS["BLUE"], curses.A_BOLD))
+ tiles.append(Tile("3", "3", Ouija.COLORS["RED"], curses.A_BOLD))
+ tiles.append(Tile("4", "4", Ouija.COLORS["GREEN"], curses.A_BOLD))
+ tiles.append(Tile("5", "5", Ouija.COLORS["ORANGE"], curses.A_BOLD))
+ tiles.append(Tile("!", "#", Ouija.COLORS["YELLOW"]))
+ tiles.append(Tile("_", "."))
+ tiles.append(Tile("x", "x", Ouija.COLORS["BLACK_ON_YELLOW"]))
+ tiles.append(Tile("-", ".", Ouija.COLORS["BLACK_ON_YELLOW"]))
+ tiles.append(Tile("+", "#", Ouija.COLORS["BLACK_ON_YELLOW"]))
+ return tiles
+
+def env_setup():
+ if not MY_SWEEPY_ROOT.exists():
+ MY_SWEEPY_ROOT.mkdir()
+ if not MY_SWEEPY_WON.exists():
+ MY_SWEEPY_WON.mkdir()
+ if not MY_SWEEPY_LOST.exists():
+ MY_SWEEPY_LOST.mkdir()
+
+def game_loop(stdscr, ob, ml):
+
+ cur_y, cur_x = ml.get_first_cell()
+
+ while(True):
+
+ if ml.has_won() or ml.has_lost():
+ msg = "You won!" if ml.has_won() else "You lost :("
+ base_fn = MY_SWEEPY_WON if ml.has_won() else MY_SWEEPY_LOST
+
+ stdscr.addstr(4, 3, "{} [n]ew game, [r]eplay, or [q]uit?".format(msg))
+ ob.draw_board(ml.get_board())
+
+ fn = "{}.sweepy".format(ml.SEED)
+ root_fn = MY_SWEEPY_ROOT / fn
+ fn_fq = MY_SWEEPY_WON / fn
+ if root_fn.exists():
+ root_fn.unlink()
+
+ ml.save(str(fn_fq))
+
+ while(True):
+
+ ik = stdscr.getkey()
+ if ik == 'n':
+ # clear the line
+ stdscr.move(4, 3)
+ stdscr.clrtoeol()
+
+ ml = MinesweeperLogic()
+ ml.new_game()
+ cur_y, cur_x = ml.get_first_cell()
+ break
+
+ elif ik == 'r':
+ stdscr.move(4, 3)
+ stdscr.clrtoeol()
+ ml.new_game()
+ cur_y, cur_x = ml.get_first_cell()
+ break
+
+ elif ik == 'q':
+ exit()
+
+ game_head(stdscr, ml)
+ game_foot(stdscr)
+ ob.draw_board(ml.get_board(), cur_y, cur_x)
+ in_key = stdscr.getkey()
+
+ # uncover a cell using the enter key
+ if in_key == "\n":
+ ml.do_move(cur_y, cur_x, "u")
+ if ml.get_first_cell():
+ cur_y, cur_x = ml.get_closest_cell(cur_y, cur_x)
+ #cur_y, cur_x = ml.closest(cur_y, cur_x)
+
+ # flag a cell using the "f" key
+ elif in_key == "f":
+ ml.do_move(cur_y, cur_x, "x")
+ if ml.get_first_cell():
+ cur_y, cur_x = ml.get_closest_cell(cur_y, cur_x)
+ #cur_y, cur_x = ml.closest(cur_y, cur_x)
+
+ # save a game (and exit) using the "s" key
+ elif in_key == "s":
+ ob.draw_board(ml.get_board())
+ fn = "{}.sweepy".format(ml.SEED)
+ root_fn = MY_SWEEPY_ROOT / fn
+ ml.save(str(root_fn))
+ stdscr.addstr(4, 3, "Game saved!")
+ stdscr.getch()
+ exit()
+
+ # start a new game with the "n" key
+ elif in_key == "n":
+ ob.draw_board(ml.get_board())
+ stdscr.addstr(4, 3, "new game? (y/n) ")
+ choice = stdscr.getkey()
+ stdscr.move(4, 3)
+ stdscr.clrtoeol()
+
+ if choice == 'y':
+ ml = MinesweeperLogic()
+ ml.new_game()
+ cur_y, cur_x = ml.get_first_cell()
+
+ # reset the current game with the "r" key
+ elif in_key == "r":
+ ob.draw_board(ml.get_board())
+ stdscr.addstr(4, 3, "reset the current game? (y/n) ")
+ choice = stdscr.getkey()
+ stdscr.move(4, 3)
+ stdscr.clrtoeol()
+
+ if choice == 'y':
+ ml.new_game()
+ cur_y, cur_x = ml.get_first_cell()
+
+ # quit without saving using the "q" key
+ elif in_key == "q":
+ ob.draw_board(ml.get_board())
+ stdscr.addstr(4, 3, "Quit without saving? (y/n) ")
+ choice = stdscr.getkey()
+ if choice == 'y':
+ exit()
+ else:
+ stdscr.move(4, 3)
+ stdscr.clrtoeol()
+
+ # navigation
+ elif in_key == "KEY_LEFT":
+ cur_y, cur_x, cost = ml.get_left(cur_y, cur_x)
+ elif in_key == "KEY_RIGHT":
+ cur_y, cur_x, cost = ml.get_right(cur_y, cur_x)
+ elif in_key == "KEY_UP":
+ cur_y, cur_x, cost = ml.get_up(cur_y, cur_x)
+ elif in_key == "KEY_DOWN":
+ cur_y, cur_x, cost = ml.get_down(cur_y, cur_x)
+ elif in_key == "\t":
+ cur_y, cur_x = ml.closest(cur_y, cur_x)
+
+def game_head(stdscr, ml):
+ stdscr.addstr(1, 3, "~ sweepy ~")
+ stdscr.addstr(2, 3, "{} bombs, seed: {}".format(str(ml.BOMBS),str(ml.SEED)))
+ stdscr.addstr(3, 3, "flags: {:>2}".format(str(ml.get_flag_count())))
+ stdscr.refresh()
+
+def game_foot(stdscr):
+ stdscr.addstr(24, 3, "u/d/l/r/tab navigation")
+ stdscr.addstr(25, 3, "enter: uncover cell")
+ stdscr.addstr(26, 3, "'f': (un)flag cell")
+ stdscr.addstr(27, 3, "'n': new game")
+ stdscr.addstr(28, 3, "'r': reset game")
+ stdscr.addstr(29, 3, "'s': save and quit game")
+ stdscr.addstr(30, 3, "'q': quit game (without saving)")
+
+def main(stdscr):
+
+ stdscr.clear()
+ curses.curs_set(False)
+
+ env_setup()
+
+ # blocks are 2 tall and 4 wide
+ ml = MinesweeperLogic()
+ board = Ouija(stdscr, 6, 5)
+ board.style(corner=None, horiz_edge="=")
+
+ if not board.setup_tiles(generate_tiles()):
+ return False
+
+ # print some info
+ stdscr.addstr(1, 3, "~ sweepy ~")
+ stdscr.addstr(2, 3, "[n]ew game, or [r]esume a game")
+
+ # initial loop
+ while(True):
+ in_key = stdscr.getkey()
+
+ if in_key == "q":
+ exit()
+ elif in_key == "n":
+ stdscr.addstr(3, 3, "choose a size")
+ stdscr.addstr(4, 3, "[0] 8 x 8 (10 bombs)")
+ stdscr.addstr(5, 3, "[1] 16 x 8 (25 bombs)")
+ while True:
+ choice = stdscr.getkey()
+ if choice == '0':
+ ml.new_game(8, 8, 10)
+ break
+ elif choice == '1':
+ ml.new_game(8, 16, 25)
+ break
+ else:
+ stdscr.addstr(6, 3, "invalid choice, choose again")
+ break
+ elif in_key == "l":
+ stdscr.addstr(3, 3, "what game do you want to load? ")
+ fn = stdscr.getstr()
+ stdscr.addstr(4, 3, fn)
+ stdscr.getch()
+ ml.load(fn.decode('utf-8'))
+ break
+ elif in_key == "r":
+ current_games = sorted(MY_SWEEPY_ROOT.glob("*.sweepy"))
+ stdscr.addstr(3, 3, "there are " + str(len(current_games)) + " games in progress")
+ for idx, game in enumerate(current_games):
+ stdscr.addstr(4 + idx, 3, "[{}] {}".format(str(idx), str(game.name)))
+
+ if len(current_games) != 0:
+ stdscr.addstr(4 + len(current_games), 3, "choose a game")
+ while True:
+ r_key = stdscr.getkey()
+ if r_key.isdigit() and int(r_key) in range(len(current_games)):
+ r_game = current_games[int(r_key)]
+ ml.load(str(r_game))
+ break
+ else:
+ stdscr.addstr(4 + len(current_games), 3, "invalid choice, choose a game")
+ break
+
+ stdscr.clear()
+ game_loop(stdscr, board, ml)
+
+curses.wrapper(main)