Python實現(xiàn)簡單掃雷游戲
更新時間:2022年06月08日 11:07:27 作者:側耳聽偑
這篇文章主要為大家詳細介紹了Python實現(xiàn)簡單掃雷游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實例為大家分享了Python實現(xiàn)簡單掃雷游戲的具體代碼,供大家參考,具體內(nèi)容如下
#coding: utf-8 __note__ = """ * 掃雷小游戲 * 需要python3.x以上 * 需要安裝PyQt5 * pip install PyQt5 """ ? import sys ? try: ? ? import PyQt5 except ImportError: ? ? import tkinter ? ? from tkinter import messagebox ? ? err_str = "請安裝PyQt5后再打開: pip install PyQt5" ? ? messagebox.showerror("模塊錯誤!", err_str) ? ? raise ImportError(err_str) ? ? sys.exit() ? ? from random import randint from PyQt5.QtWidgets import \ ? ? QApplication, ? ? ? ? ? \ ? ? QWidget, ? ? ? ? ? ? ? ?\ ? ? QPushButton, ? ? ? ? ? ?\ ? ? QLCDNumber, ? ? ? ? ? ? \ ? ? QDesktopWidget, ? ? ? ? \ ? ? QMessageBox from PyQt5.QtCore import Qt ? ? class Mine(object): ? ? mine = 9 ? ? no_mine = 0 ? ? n_mine = 10 ? ? width = 10 ? ? height = 10 ? ? ? def __init__(self, width=10, height=10, nMines=10): ? ? ? ? self.map = [] ? ? ? ? for _ in range(height): ? ? ? ? ? ? t_line = [] ? ? ? ? ? ? for _ in range(width): ? ? ? ? ? ? ? ? t_line.append(self.no_mine) ? ? ? ? ? ? self.map.append(t_line) ? ? ? ? ? ? ? ? ? self.width = width ? ? ? ? self.height = height ? ? ? ? self.n_mine = nMines ? ? ? ? ? self.remix() ? ? ? ? ? # 打亂布局重新隨機編排 ? ? def remix(self): ? ? ? ? ? for y in range(self.height): ? ? ? ? ? ? for x in range(self.width): ? ? ? ? ? ? ? ? self.map[y][x] = self.no_mine ? ? ? ? ? def add_mark(x, y): ? ? ? ? ? ? # 如果不是雷的標記就+1 ? ? ? ? ? ? if self.map[y][x]+1 < self.mine: ? ? ? ? ? ? ? ? self.map[y][x] += 1 ? ? ? ? ? ? ? ? ? mine_count = 0 ? ? ? ? ? while mine_count < self.n_mine: ? ? ? ? ? ? x = randint(0, self.width-1) ? ? ? ? ? ? y = randint(0, self.height-1) ? ? ? ? ? ? ? if self.map[y][x] != self.mine: ? ? ? ? ? ? ? ? self.map[y][x] = self.mine ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mine_count += 1 ? ? ? ? ? ? ? ? ? # 雷所在的位置的8個方位的數(shù)值+1 ? ? ? ? ? ? ? ? ## 上下左右 ? ? ? ? ? ? ? ? if y-1 >= 0: add_mark(x, y-1) ? ? ? ? ? ? ? ? if y+1 < self.height: add_mark(x, y+1) ? ? ? ? ? ? ? ? if x-1 >= 0: add_mark(x-1, y) ? ? ? ? ? ? ? ? if x+1 < self.width: add_mark(x+1, y) ? ? ? ? ? ? ? ? ## 四個角: 左上角、左下角、右上角、右下角 ? ? ? ? ? ? ? ? if x-1 >= 0 and y-1 >=1: add_mark(x-1, y-1) ? ? ? ? ? ? ? ? if x-1 >= 0 and y+1 < self.height: add_mark(x-1, y+1) ? ? ? ? ? ? ? ? if x+1 < self.width and y-1 >= 1: add_mark(x+1, y-1) ? ? ? ? ? ? ? ? if x+1 < self.width and y+1 < self.height: add_mark(x+1, y+1) ? ? ? ? ? def __getitem__(self, key): ? ? ? ? return self.map[key] ? ? ? def __str__(self): ? ? ? ? format_str = "" ? ? ? ? for y in range(self.height): ? ? ? ? ? ? format_str += str(self[y]) + "\n" ? ? ? ? return format_str ? ? __repr__ = __str__ ? class LCDCounter(QLCDNumber): ? ? __counter = 0 ? ? def __init__(self, start=0, parent=None): ? ? ? ? super().__init__(4, parent) ? ? ? ? self.setSegmentStyle(QLCDNumber.Flat) ? ? ? ? self.setStyleSheet("background: black; color: red") ? ? ? ? self.counter = start ? ? ? ? ? @property ? ? def counter(self): ? ? ? ? return self.__counter ? ? @counter.setter ? ? def counter(self, value): ? ? ? ? self.__counter = value ? ? ? ? self.display(str(self.__counter)) ? ? ? ? ? def inc(self): ? ? ? ? self.counter += 1 ? ? def dec(self): ? ? ? ? self.counter -= 1 ? class MineButton(QPushButton): ? ? # 按鈕類型 ? ? MINE = Mine.mine ? ? ? ?# 雷 ? ? NOTMINE = Mine.no_mine ?# 不是雷 ? ? m_type = None ? ? ? # 按鈕狀態(tài) ? ? mark = False ? ?# 是否是標記狀態(tài)(默認: 未被標記) ? ? ? s_flag = '⚑' ? # 標記 ? ? s_mine = '☠' ?# 雷 ? ? s_success = '👌' ? ? ? # 按鈕是否按下(默認False: 未按下) ? ? __pushed = False ? ? ? # 按鈕對應map的位置 ? ? m_x = 0 ? ? m_y = 0 ? ? ? def __init__(self, map_pos, m_type, parent): ? ? ? ? super().__init__(parent) ? ? ? ? self.m_type = m_type ? ? ? ? self.pushed = False ? ? ? ? self.m_x = map_pos[0] ? ? ? ? self.m_y = map_pos[1] ? ? ? ? ? @property ? ? def pushed(self): ? ? ? ? return not self.__pushed ? ? @pushed.setter ? ? def pushed(self, value): ? ? ? ? self.__pushed = not value ? ? ? ? self.setEnabled(self.__pushed) ? ? ? ## 按鈕上的鼠標按下事件 ? ? def mousePressEvent(self, e): ? ? ? ? #print("m_x:%d"%self.m_x, "m_y:%d"%self.m_y, "m_type:%d"%self.m_type) ? ? ? ? ? p = self.parent() ? ? ? ? # 記錄鼠標單擊次數(shù) ? ? ? ? p.nwap_lcd_clicked.counter += 1 ? ? ? ? ? # 左鍵掃雷 ? ? ? ? if e.buttons() == Qt.LeftButton: ? ? ? ? ? ? # 踩中雷, 全部雷都翻起來 ? ? ? ? ? ? if self.m_type == self.MINE: ? ? ? ? ? ? ? ? for t_line_btn in p.btn_map: ? ? ? ? ? ? ? ? ? ? for btn in t_line_btn: ? ? ? ? ? ? ? ? ? ? ? ? if btn.m_type == btn.MINE: ? ? ? ? ? ? ? ? ? ? ? ? ? ? btn.setText(btn.s_mine) ? ? ? ? ? ? ? ? ? ? ? ? else: ? ? ? ? ? ? ? ? ? ? ? ? ? ? if btn.mark != True: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if btn.m_type != btn.NOTMINE: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? btn.setText(str(btn.m_type)) ? ? ? ? ? ? ? ? ? ? ? ? btn.pushed = True ? ? ? ? ? ? ? ? # 苦逼臉 ? ? ? ? ? ? ? ? p.RestartBtn.setText('😣') ? ? ? ? ? ? ? ? QMessageBox.critical(self, "失敗!", "您不小心踩到了雷! " + self.s_mine) ? ? ? ? ? ? ? ? return None ? ? ? ? ? ? elif self.m_type == self.NOTMINE: ? ? ? ? ? ? ? ? self.AutoSwap(self.m_x, self.m_y) ? ? ? ? ? ? else: ? ? ? ? ? ? ? ? self.setText(str(self.m_type)) ? ? ? ? ? ? ? ? ? ? ? ? ? p.mine_counter -= 1 ? ? ? ? ? ? self.pushed = True ? ? ? ? # 右鍵添加標記 ? ? ? ? elif e.buttons() == Qt.RightButton: ? ? ? ? ? ? if self.mark == False: ? ? ? ? ? ? ? ? self.setText(self.s_flag) ? ? ? ? ? ? ? ? self.mark = True ? ? ? ? ? ? else: ? ? ? ? ? ? ? ? self.setText("") ? ? ? ? ? ? ? ? self.mark = False ? ? ? ? ? ? ? ? ? self.setFocus(False) ? ? ? ? ? ? ## 當按下的位置是NOTMINE時自動掃雷 ? ? def AutoSwap(self, x, y): ? ? ? ? p = self.parent() ? ? ? ? map_btn = p.btn_map ? ? ? ? ? ? ? ? ? def lookup(t_line, index): ? ? ? ? ? ? # 向左掃描 ? ? ? ? ? ? i = index ? ? ? ? ? ? while i >= 0 and not t_line[i].pushed and t_line[i].m_type != MineButton.MINE: ? ? ? ? ? ? ? ? if t_line[i].m_type != MineButton.NOTMINE: ? ? ? ? ? ? ? ? ? ? t_line[i].setText(str(t_line[i].m_type)) ? ? ? ? ? ? ? ? t_line[i].pushed = True ? ? ? ? ? ? ? ? p.mine_counter -= 1 ? ? ? ? ? ? ? ? p.nwap_lcd_counter.counter = p.mine_counter ? ? ? ? ? ? ? ? i -= 1 ? ? ? ? ? ? ? ? if t_line[i].m_type != MineButton.NOTMINE: ? ? ? ? ? ? ? ? ? ? break ? ? ? ? ? ? # 向右掃描 ? ? ? ? ? ? i = index + 1 ? ? ? ? ? ? while i < p.mine_map.width and not t_line[i].pushed and t_line[i].m_type != MineButton.MINE: ? ? ? ? ? ? ? ? if t_line[i].m_type != MineButton.NOTMINE: ? ? ? ? ? ? ? ? ? ? t_line[i].setText(str(t_line[i].m_type)) ? ? ? ? ? ? ? ? t_line[i].pushed = True ? ? ? ? ? ? ? ? p.mine_counter -= 1 ? ? ? ? ? ? ? ? p.nwap_lcd_counter.counter = p.mine_counter ? ? ? ? ? ? ? ? i += 1 ? ? ? ? ? ? ? ? if t_line[i].m_type != MineButton.NOTMINE: ? ? ? ? ? ? ? ? ? ? break ? ? ? ? ? ? ? ? ? # 向上掃描 ? ? ? ? j = y ? ? ? ? while j >= 0: ? ? ? ? ? ? lookup(map_btn[j], x) ? ? ? ? ? ? j -= 1 ? ? ? ? # 向下掃描 ? ? ? ? j = y + 1 ? ? ? ? while j < p.mine_map.height: ? ? ? ? ? ? lookup(map_btn[j], x) ? ? ? ? ? ? j += 1 ? ? ? class MineWindow(QWidget): ? ? ? def __init__(self): ? ? ? ? super().__init__() ? ? ? ? self.mine_map = Mine(nMines=16) ? ? ? ? self.InitGUI() ? ? ? ? #print(self.mine_map) ? ? ? ? ? ? ? def InitGUI(self): ? ? ? ? ? ? ? ? ? w_width = 304 ? ? ? ? w_height = 344 ? ? ? ? ? self.resize(w_width, w_height) ? ? ? ? self.setFixedSize(self.width(), self.height()) ? ? ? ? self.setWindowTitle("掃雷") ? ? ? ? ? ## 窗口居中于屏幕 ? ? ? ? qr = self.frameGeometry() ? ? ? ? cp = QDesktopWidget().availableGeometry().center() ? ? ? ? qr.moveCenter(cp) ? ? ? ? self.move(qr.x(), qr.y()) ? ? ? ? ? ? l_start_x = 2 ? ? ? ? l_start_y = 40 ? ? ? ? l_x = l_start_x ? ? ? ? l_y = l_start_y ? ? ? ? l_width = 30 ? ? ? ? l_height = 30 ? ? ? ? ? # 雷區(qū)按鈕 ? ? ? ? self.btn_map = [] ? ? ? ? for h in range(self.mine_map.height): ? ? ? ? ? ? l_x = l_start_x ? ? ? ? ? ? self.btn_map.append(list()) ? ? ? ? ? ? for w in range(self.mine_map.width): ? ? ? ? ? ? ? ? self.btn_map[h].append(MineButton([w, h], self.mine_map[h][w], self)) ? ? ? ? ? ? ? ? self.btn_map[h][w].resize(l_width, l_height) ? ? ? ? ? ? ? ? self.btn_map[h][w].move(l_x, l_y) ? ? ? ? ? ? ? ? self.btn_map[h][w].show() ? ? ? ? ? ? ? ? l_x += l_width ? ? ? ? ? ? l_y += l_height ? ? ? ? ? r_width = 30 ? ? ? ? r_height = 30 ? ? ? ? ? # 恢復按鈕 ? ? ? ? self.RestartBtn = QPushButton('😊', self) ? ? ? ? self.RestartBtn.clicked.connect(self.restart_btn_event) ? ? ? ? self.RestartBtn.resize(r_width, r_height) ? ? ? ? self.RestartBtn.move((w_width-r_width)//2, 6) ? ? ? ? ? ## 計數(shù)器 ? ? ? ? self.__mine_counter = self.mine_map.width * self.mine_map.height - self.mine_map.n_mine ? ? ? ? ? ## 兩個LCD顯示控件 ? ? ? ? # 操作次數(shù) ? ? ? ? self.nwap_lcd_clicked = LCDCounter(0, self) ? ? ? ? self.nwap_lcd_clicked.move(44, 8) ? ? ? ? ? # 無雷塊個數(shù) ? ? ? ? self.nwap_lcd_counter = LCDCounter(self.mine_counter, self) ? ? ? ? self.nwap_lcd_counter.move(204, 8) ? ? ? ? ? ? ? def restart_btn_event(self): ? ? ? ? self.mine_map.remix() ? ? ? ? #QMessageBox.information(self, "look up", str(self.mine_map)) ? ? ? ? for y in range(len(self.btn_map)): ? ? ? ? ? ? for x in range(len(self.btn_map[y])): ? ? ? ? ? ? ? ? self.btn_map[y][x].pushed = False ? ? ? ? ? ? ? ? self.btn_map[y][x].setText("") ? ? ? ? ? ? ? ? self.btn_map[y][x].m_type = self.mine_map[y][x] ? ? ? ? ? ? ? ? ? self.mine_counter = self.mine_map.width * self.mine_map.height - self.mine_map.n_mine ? ? ? ? self.RestartBtn.setText('😊') ? ? ? ? self.nwap_lcd_clicked.counter = 0 ? ? ? ? self.nwap_lcd_counter.counter = self.mine_counter ? ? ? ? ? ### 計數(shù)器 ? ? @property ? ? def mine_counter(self): ? ? ? ? return self.__mine_counter ? ? @mine_counter.setter ? ? def mine_counter(self, value): ? ? ? ? self.__mine_counter = value ? ? ? ? self.nwap_lcd_counter.dec() ? ? ? ? if self.mine_counter == 0: ? ? ? ? ? ? for t_line_btn in self.btn_map: ? ? ? ? ? ? ? ? for btn in t_line_btn: ? ? ? ? ? ? ? ? ? ? if btn.m_type == btn.MINE: ? ? ? ? ? ? ? ? ? ? ? ? btn.setText(btn.s_success) ? ? ? ? ? ? ? ? ? ? ? ? btn.pushed = True ? ? ? ? ? ? QMessageBox.information(self, "恭喜!", "您成功掃雷! " + MineButton.s_success) ? ? if __name__ == '__main__': ? ? app = QApplication(sys.argv) ? ? w = MineWindow() ? ? w.show() ? ? sys.exit(app.exec_())
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
python中的classmethod與staticmethod
這篇文章主要介紹了python中的classmethod與staticmethod,2022-01-01Python編程產(chǎn)生非均勻隨機數(shù)的幾種方法代碼分享
這篇文章主要介紹了Python編程產(chǎn)生非均勻隨機數(shù)的幾種方法代碼分享,具有一定借鑒價值,需要的朋友可以參考下。2017-12-12python實現(xiàn)DEM數(shù)據(jù)的陰影生成的方法
這篇文章主要介紹了python實現(xiàn)DEM數(shù)據(jù)的陰影生成的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-07-07python正則表達式函數(shù)match()和search()的區(qū)別
match()和search()都是python中的正則匹配函數(shù),那這兩個函數(shù)有何區(qū)別呢?本文詳細介紹了這2個函數(shù)的區(qū)別2021-10-10從DataFrame中提取出Series或DataFrame對象的方法
今天小編就為大家分享一篇從DataFrame中提取出Series或DataFrame對象的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-11-11