def play_game(dims, mines): board = gen_board(dims, mines) counts = get_neighbor_counts(board) known = np.ones(dims) * -1 while True: os.system('clear') print_known(known) indices = input( 'Enter {} indices (space separated): '.format(len(dims))) try: indices = map(int, indices.split()) safe = select(indices, board, counts, known) if not safe: print_game_over(board, counts) input('You lose! Press ENTER to play again. ') break elif np.sum(known == -1) == mines: print_game_over(board, counts) input('You win! Press ENTER to play again. ') break except Exception: pass
def solve(board, serial=False): counts = get_neighbor_counts(board) known = np.ones(dims) * -1 marked = np.zeros(known.shape) turns = 0 while True: turns += 1 indices = get_safe_indices(known, marked) if len(indices) > 0: if serial: safe = select(indices[0], board, counts, known) assert safe else: for index in indices: safe = select(index, board, counts, known) assert safe else: index = get_random_unknown_index(known, marked) safe = select(index, board, counts, known) if not safe: print('You lose! (random selection)') return False mark_mines(known, marked) print_known(known, marked=marked) print(np.sum(marked)) print('-' * 80) assert np.sum((known > 0) * board) == 0 if np.sum(board) == np.sum(marked): assert np.sum(board * marked) == np.sum(board) print('Game won in {} turns!'.format(turns)) return True
def play_game(dims, mines, screen): board = gen_board(dims, mines) counts = get_neighbor_counts(board) known = np.ones(dims) * -1 flags = np.zeros(dims) screen.keypad(True) curses.start_color() curses.init_pair(1, curses.COLOR_BLUE, curses.COLOR_BLACK) curses.init_pair(2, curses.COLOR_GREEN, curses.COLOR_BLACK) curses.init_pair(3, curses.COLOR_RED, curses.COLOR_BLACK) curses.init_pair(4, curses.COLOR_BLUE, curses.COLOR_BLACK) curses.init_pair(5, curses.COLOR_MAGENTA, curses.COLOR_BLACK) curses.init_pair(6, curses.COLOR_CYAN, curses.COLOR_BLACK) curses.init_pair(7, curses.COLOR_YELLOW, curses.COLOR_BLACK) curses.init_pair(8, curses.COLOR_WHITE, curses.COLOR_BLACK) curses.init_pair(9, curses.COLOR_YELLOW, curses.COLOR_YELLOW) curses.init_pair(10, curses.COLOR_BLACK, curses.COLOR_RED) colors = { '1': curses.color_pair(1), '2': curses.color_pair(2), '3': curses.color_pair(3), '4': curses.color_pair(4), '5': curses.color_pair(5), '6': curses.color_pair(6), '7': curses.color_pair(7), '8': curses.color_pair(8), '*': curses.color_pair(9), 'X': curses.color_pair(10) } screen_dims = screen.getmaxyx() offset = [ int((screen_dims[1] - dims[1] * 2) / 2), int((screen_dims[0] - dims[0]) / 2) ] x, y = 0, 0 key = '' while key != 'q': screen.clear() display_screen(get_known_string(known, flags), screen, colors, offset[0], offset[1]) screen.addstr( 0, 0, 'Press q to quit, ENTER to select a ' + 'square, and f to flag a mine.', curses.A_BOLD) screen.move(y + offset[1], x + offset[0]) key = chr(screen.getch()) if (key == 'w' or ord(key) == curses.KEY_UP) and y > 0: y -= 1 elif (key == 's' or ord(key) == curses.KEY_DOWN) and y < dims[0] - 1: y += 1 elif (key == 'a' or ord(key) == curses.KEY_LEFT) and x > 0: x -= 2 elif (key == 'd' or ord(key) == curses.KEY_RIGHT) \ and x < (dims[1] - 1) * 2: x += 2 elif key == 'f' \ and (known[y, int(x / 2)] < 0 or flags[y, int(x / 2)] > 0): flags[y, int(x / 2)] = 1 - flags[y, int(x / 2)] elif key == '\n' and not flags[y, int(x / 2)]: safe = select([int(y), int(x / 2)], board, counts, known) if not safe: screen.clear() display_screen(get_game_over_string(board, counts), screen, colors, offset[0], offset[1]) screen.addstr(0, 0, 'You lose! Press ENTER to play again.', curses.A_BOLD) screen.getch() break elif np.sum(known == -1) == mines: screen.clear() display_screen(get_game_over_string(board, counts), screen, colors, offset[0], offset[1]) screen.addstr(0, 0, 'You win! Press ENTER to play again.', curses.A_BOLD) screen.getch() break screen.refresh() return key
def mark_mines(known, marked): unknown = get_neighbor_counts(known < 0) satisfied = (unknown == known) & (known > 0) new_marked = np.round(get_neighbor_counts(satisfied) * (known < 0)) marked[(marked + new_marked) > 0] = 1
def get_safe_indices(known, marked): marked_counts = get_neighbor_counts(marked) satisfied = (marked_counts == known) & (known > 0) safe_indices = get_neighbor_counts(satisfied) * (known < 0) * (marked < 1) return np.transpose(np.nonzero(safe_indices))