python3 实现在控制台面板玩扫雷

2020-04-13  本文已影响0人  格雷s

代码介绍

本项目主要体现的是通过递归的思想实现点击坐标雷块判断及周围区域的雷区判断

代码实现

import random
import re
#扫雷网格大小
GRID_SIZE=5

class Minesweeper:
    
    def __init__(self):
        #生成雷区的数据
        self.matrix_minesweeper = self.placeMines()
        #游戏面板
        self.matrix_out = self.makeBoard()
        #地雷数量
        self.minesCount = self.countAllMines()
        #游戏是否结束
        self.gameOver = False

    #初始化生成随机放置地雷的网格,空字符串"",地雷x
    def placeMines(self):
        matrix = [[0 for i in range(GRID_SIZE)] for i in range(GRID_SIZE)]
        for i in range(GRID_SIZE):
            for j in range(GRID_SIZE):
                #随机生成雷
                if random.randint(0,GRID_SIZE) == GRID_SIZE // 2:
                    matrix[i][j] = 'X'
                else:
                    matrix[i][j] = ' '
        return matrix

    #返回游戏板 #
    def makeBoard(self):
        return [['#' for c in range(GRID_SIZE)] for r in range(GRID_SIZE)]

    #输出打印当前游戏网格
    def showBoard(self,matrix):
        #打印 |1234
        output = " |"
        for i in range(GRID_SIZE):
            output = f'{output}{i}'
        print(output)
        #打印-------
        output ="--"
        for i in range(GRID_SIZE):
            output = f'{output}-'
        print(output)

        #打印矩阵
        for i in range(GRID_SIZE):
            output = [f'{i}|']
            for j in range(GRID_SIZE):
                #如果当前踩雷了,并且当前位置是雷,则展示雷
                if self.gameOver and self.matrix_minesweeper[i][j] == 'X':
                    output.append('X')
                else:
                    output.append(f'{matrix[i][j]}')
            print(''.join(output))

    #返回当前游戏网格中,未显示的#
    def countHiddenCells(self,matrix):
        tmp = 0;
        for i in range(GRID_SIZE):
            for j in range(GRID_SIZE):
                if matrix[i][j] == '#':
                    tmp = tmp + 1
        return tmp

    #返回初始化之后包含的雷个数
    def countAllMines(self):
        tmp = 0
        for i in range(GRID_SIZE):
            for j in range(GRID_SIZE):
                if self.matrix_minesweeper[i][j] == 'X':
                    tmp = tmp + 1
        return tmp

    #返回当前行,当前列是否是雷
    def isMineAt(self,matrix,r,c):
        if matrix[r][c] == 'X':
            self.gameOver = True
            return True
        else:
            self.gameOver = False
            return False

    #根据当前坐标,判断当前坐标相邻cell中的地雷数量
    def countAdjacentMines(self,matrix,r,c):
        if r<0 or r >= GRID_SIZE or c <0 or c >= GRID_SIZE:
            return 0
        count=0
        #左上角
        if r-1 >= 0 and c-1>=0:
            if self.matrix_minesweeper[r-1][c-1] == 'X':
                count = count + 1
       #左边         
        if r-1>=0:
            if self.matrix_minesweeper[r-1][c] == 'X':
                count = count + 1
        #左下
        if r-1>=0 and c+1 < GRID_SIZE:
            if self.matrix_minesweeper[r-1][c+1] == 'X':
                count = count + 1
        #下
        if c+1 < GRID_SIZE:
            if self.matrix_minesweeper[r][c+1] == 'X':
                count = count + 1
        #右下
        if r+1 < GRID_SIZE and c+1 < GRID_SIZE:
            if self.matrix_minesweeper[r+1][c+1] == 'X':
                count = count + 1
        #右
        if r+1 < GRID_SIZE:
            if self.matrix_minesweeper[r+1][c] == 'X':
                count = count + 1
        #右上
        if r+1 < GRID_SIZE and c-1>=0:
            if self.matrix_minesweeper[r+1][c-1] == 'X':
                count = count + 1
        #上
        if c-1>=0:
            if self.matrix_minesweeper[r][c-1] == 'X':
                count = count + 1
        return count
    
    #查询当前坐标的相邻雷
    def recureMines(self,r,c):
        if r<0 or r >= GRID_SIZE or c <0 or c >= GRID_SIZE:
            return 
        #相邻8个cell是否有雷的
        count = self.countAdjacentMines(self.matrix_minesweeper,r,c)
        if count == 0 and self.matrix_out[r][c] == '#':
            #如果当前周围没有雷,且没有处理过,则把游戏网格当前位置清空,并且递归执行周围8个cell
            self.matrix_out[r][c]=' '
            self.recureMines(r-1,c)
            self.recureMines(r-1,c-1)
            self.recureMines(r-1,c+1)
            self.recureMines(r,c+1)
            self.recureMines(r+1,c+1)
            self.recureMines(r+1,c)
            self.recureMines(r+1,c-1)
            self.recureMines(r,c-1)
        else:
            #当前坐标显示相邻几个雷,如果没有则为空
            if count == 0:
                self.matrix_out[r][c] = ' '
            else:
                self.matrix_out[r][c] = f'{count}'

def main():
    minesweeper = Minesweeper()
    print('---------------------游戏开始后地雷埋的位置,供踩雷参考---------------------------')    
    for i in range(GRID_SIZE):
        print(minesweeper.matrix_minesweeper[i])

    print('--------------------游戏开始----------------------------')    
    #初始化打印游戏面板
    minesweeper.showBoard(minesweeper.matrix_out)

    while True:
        key_num = input('Select a cell (row,col) >')
        #分割row,col
        rc=re.split(r',',key_num)

        #判断是否为数字
        if not(rc[0].isdigit() and rc[1].isdigit()):
            print('请输入数字坐标')
            continue    

        #获取行
        row = int(rc[0])
        #获取列数
        column = int(rc[1])
        
        #判断坐标是否在网格内
        if row >= GRID_SIZE or column >= GRID_SIZE:
            print('不在游戏面板范围内,请输入合适的网格坐标')
            continue

        #判断当前位置是否有雷
        if minesweeper.isMineAt(minesweeper.matrix_minesweeper,row,column):
            #踩雷,结束
            minesweeper.showBoard(minesweeper.matrix_out)
            print('Game Over!')
            break
        else:
            minesweeper.recureMines(row,column)
        #打印
        minesweeper.showBoard(minesweeper.matrix_out)
        #如果'#'和雷的数量相同,胜利,结束
        if  minesweeper.countHiddenCells(minesweeper.matrix_out) == minesweeper.minesCount:
            print('YOU WIN!!')
            break



if __name__ == '__main__':
    main()

游戏效果

image.png image.png
上一篇 下一篇

猜你喜欢

热点阅读