美文网首页
Python小练习:命令行扫雷

Python小练习:命令行扫雷

作者: FosterThePeople | 来源:发表于2017-05-30 21:47 被阅读0次
    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    import random
    from copy import deepcopy
    from platform import system
    import os
    
    if "windows" in system().lower():
        input ("This python game doesn't work well on Windows, recomend run on macOS or Linux. You can press enter to run it.")
    
    logo = '''
    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  拥抱地雷 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃     ___         _              _____ _                   _              ┃
    ┃    / __\__  ___| |_ ___ _ __  /__   \ |__   ___    /\/\ (_)_ __   ___   ┃
    ┃   / _\/ _ \/ __| __/ _ \ '__|   / /\/ '_ \ / _ \  /    \| | '_ \ / _ \  ┃
    ┃  / / | (_) \__ \ ||  __/ |     / /  | | | |  __/ / /\/\ \ | | | |  __/  ┃
    ┃  \/   \___/|___/\__\___|_|     \/   |_| |_|\___| \/    \/_|_| |_|\___|  ┃
    ┃                                                                         ┃
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  Coded by FTP ━┛
    '''
    
    game_over = '''
    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃       _____   ___  ___  ___ _____    _____  _   _ ___________   _       ┃
    ┃      |  __ \ / _ \ |  \/  ||  ___|  |  _  || | | |  ___| ___ \ | |      ┃
    ┃      | |  \// /_\ \| .  . || |__    | | | || | | | |__ | |_/ / | |      ┃
    ┃      | | __ |  _  || |\/| ||  __|   | | | || | | |  __||    /  | |      ┃
    ┃      | |_\ \| | | || |  | || |___   \ \_/ /\ \_/ / |___| |\ \  |_|      ┃
    ┃       \____/\_| |_/\_|  |_/\____/    \___/  \___/\____/\_| \_\ (_)      ┃
    ┃                                                                         ┃
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
    '''
    
    you_win = '''
    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃              __   _______ _   _    _    _ _____ _   _   _               ┃
    ┃              \ \ / /  _  | | | |  | |  | |_   _| \ | | | |              ┃
    ┃               \ V /| | | | | | |  | |  | | | | |  \| | | |              ┃
    ┃                \ / | | | | | | |  | |/\| | | | | . ` | | |              ┃
    ┃                | | \ \_/ / |_| |  \  /\  /_| |_| |\  | |_|              ┃
    ┃                \_/  \___/ \___/    \/  \/ \___/\_| \_/ (_)              ┃
    ┃                                                                         ┃
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
    '''
    
    def create_map():
        mine = [[0 for col in range(map_size)] for row in range(map_size)] # 生成9x9的二维数组,填充0
        i = 0
        while i!=mine_no: # 将指定数量的地雷随机放入二维数组
            r = random.randint(0,map_size-1)
            c = random.randint(0,map_size-1)
            if mine[r][c] == 1:
                pass
            else:
                mine[r][c] = 1
                i += 1
        return mine
    
    def count_mine(r, c): # 计算周围地雷数量并返回数字的函数
        def is_mine(r, c):
            if r <0 or c <0 or r >map_size-1 or c >map_size-1: # 防止取list负索引或超出list范围
                pass
            elif mine[r][c] == 1:
                return 1
        nunber_of_mines_around = 0
        if is_mine(r-1,c-1): # 按九宫格顺序
            nunber_of_mines_around += 1
        if is_mine(r,c-1):
            nunber_of_mines_around += 1
        if is_mine(r+1,c-1):
            nunber_of_mines_around += 1
        if is_mine(r-1,c):
            nunber_of_mines_around += 1
        if is_mine(r+1,c):
            nunber_of_mines_around += 1
        if is_mine(r-1,c+1):
            nunber_of_mines_around += 1
        if is_mine(r,c+1):
            nunber_of_mines_around += 1
        if is_mine(r+1,c+1):
            nunber_of_mines_around += 1
        return nunber_of_mines_around
    
    def enter_number(t): # 判断键盘传入的数值
        data_range = [str(i) for i in (range(1,map_size+1))]
        data = input("Enter " + t + " number:")
        while not data.isdigit():
            data = input("Not a number, please enter " + t +  " number again:")
        while data not in data_range:
            data = input("Out of map range, please enter again:")
        return int(data)-1
    
    def open_cell(r, c):
        global game_status
        if mine[r][c] == 1:
            game_status = 0
        else:
            global visible_cell
            if mine_ui[r][c] == "◼︎":
                visible_cell += 1
            if mine_counted[r][c] == 0:
                mine_ui[r][c] = " "
            else:
                mine_ui[r][c] = mine_counted[r][c]
            game_status = 1
            if visible_cell == map_size * map_size - mine_no:
                game_status = 2
    
    def open_surrounding_zero_cell(r, c):
        def is_edge(r,c):
            if r <0 or c <0 or r >map_size-1 or c >map_size-1:
                pass
            else:
                return 0
        if mine_counted[r][c] == 0:
            open_cell(r,c)
            if is_edge(r-1,c-1) == 0:
                if mine_ui[r-1][c-1] == "◼︎":
                    open_cell(r-1,c-1)
                    open_surrounding_zero_cell(r-1,c-1)
            if is_edge(r,c-1) == 0:
                if mine_ui[r][c-1] == "◼︎":
                    open_cell(r,c-1)
                    open_surrounding_zero_cell(r,c-1)
            if is_edge(r+1,c-1) == 0:
                if mine_ui[r+1][c-1] == "◼︎":
                    open_cell(r+1,c-1)
                    open_surrounding_zero_cell(r+1,c-1)
            if is_edge(r-1,c) == 0:
                if mine_ui[r-1][c] == "◼︎":
                    open_cell(r-1,c)
                    open_surrounding_zero_cell(r-1,c)
            if is_edge(r+1,c) == 0:
                if mine_ui[r+1][c] == "◼︎":
                    open_cell(r+1,c)
                    open_surrounding_zero_cell(r+1,c)
            if is_edge(r-1,c+1) == 0:
                if mine_ui[r-1][c+1] == "◼︎":
                    open_cell(r-1,c+1)
                    open_surrounding_zero_cell(r-1,c+1)
            if is_edge(r,c+1) == 0:
                if mine_ui[r][c+1] == "◼︎":
                    open_cell(r,c+1)
                    open_surrounding_zero_cell(r,c+1)
            if is_edge(r+1,c+1) == 0:
                if mine_ui[r+1][c+1] == "◼︎":
                    open_cell(r+1,c+1)
                    open_surrounding_zero_cell(r+1,c+1)
    
    def start_game():
        global game_status
        game_status = 1
        global visible_cell
        visible_cell = 0
        global mine
        global mine_counted
        global mine_ui
        # 初始化list
        mine = create_map()
        mine_counted = deepcopy(mine)
        mine_ui = [["◼︎" for col in range(map_size)] for row in range(map_size)]
        # 计算周围地雷
        for r in range(0,map_size):
            for c in range(0,map_size):
                mine_counted[r][c] = count_mine(r,c)
    
    # 自定义地图大小和雷数
    map_size = 9
    mine_no = 10
    
    # 游戏封面
    os.system('clear')
    print (logo)
    print ("                               [Enter] to Start")
    print ("                                [C] to Custom \n")
    splash_choose = input ("                           Please choose and enter:")
    while splash_choose not in ["C","c",""]:
        splash_choose = input("                       Wrong choose, please enter again:")
    if str.upper(splash_choose) == "C":
        map_size = input ("                   Please enter custom map size(only number):")
        while not map_size.isdigit():
            map_size = input ("                   Please enter custom map size(only number):")
        map_size = int(map_size)
        mine_no = input ("                   Please enter custom mine number(only number):")
        while not mine_no.isdigit():
            mine_no = input ("                   Please enter custom mine number(only number):")
        mine_no = int(mine_no)
    
    start_game()
    # 游戏流程
    while game_status == 1:
        #### 输出地图 ####
        os.system('clear')
        line = "\n    "
        for n in range (1,map_size+1):
            if n<10:
                line = line + " " + str(n) + " "
            else:
                line = line + " " + str(n)
            if n==map_size:
                print (line)
        print ("   ┏" + "━━━"*map_size + "┓")
        row_no = 1
        for r in range(0,map_size):
            line = ""
            cell_no = 1
            for c in range(0,map_size):
                line = line + " " + str(mine_ui[r][c]) + " "
                cell_no += 1
                while cell_no > map_size:
                    if row_no <10:
                        print (" " + str(row_no) + " ┃" + line + "┃ " + str(row_no))
                    else:
                        print (" " + str(row_no) + "┃" + line + "┃ " + str(row_no))
                    row_no += 1
                    cell_no = 1
                    line = ""
        print ("   ┗" + "━━━"*map_size + "┛")
        line = "    "
        for n in range (1,map_size+1):
            if n<10:
                line = line + " " + str(n) + " "
            else:
                line = line + " " + str(n)
            if n==map_size:
                print (line+ "\n")
        ######## end
        move_r = enter_number("row")
        move_c = enter_number("column")
        open_cell(move_r,move_c)
        if game_status == 0 or game_status == 2:
            os.system('clear')
            if game_status == 0:
                print (game_over)
            if game_status == 2:
                print (you_win)
            print ("                              Enter [R] to restart")
            print ("                              Enter [E] to exit\n")
            last_choose = input("                           Please choose and enter:")
            while last_choose not in ["R","r","E","e"]:
                last_choose = input("                       Wrong choose, please enter again:")
            if str.upper(last_choose) == "R":
                start_game()
            if str.upper(last_choose) == "E":
                exit()
        open_surrounding_zero_cell(move_r,move_c)
    

    相关文章

      网友评论

          本文标题:Python小练习:命令行扫雷

          本文链接:https://www.haomeiwen.com/subject/eltdfxtx.html