使用PySide实现生命游戏

来源:互联网 发布:怎么才能在淘宝上卖东西 编辑:程序博客网 时间:2024/05/17 08:16

生命游戏的规则可以直接百度生命游戏

使用PySide主要思路是创建一个主要的窗体QWidget,
通过QPainter来重绘窗体来显示元胞位置,可以先抽象成每个位置是一个点,用一个二维数组来记录gridworld上的地图, 每次扫描地图,确定每个位置周围活细胞数目,也用一个二维数组记录下来,然后在下一个时间时重绘
使用QBasicTimer来做定时器,具体做法是,在窗体类 里面创建一个QBasicTimer实例,然后修改timerEvent方法,也就是在timerEvent里面实现每一步的动作

具体代码如下,比较简单,既不用解释了

# -*-coding:utf-8 -*-__author__ = "Boyce"'''life game'''import sysfrom PySide.QtCore import *from PySide.QtGui import *import numpy as npimport randomclass LifeGame(QWidget):    def __init__(self, row, col):        super(LifeGame, self).__init__()        self.row = row        self.col = col        self.life_state = np.random.randint(0, 2, size = [self.row, self.col])        self.neighbor = np.zeros(self.col*self.row, dtype=int).reshape(self.row, self.col)        self.end_state = np.zeros(self.col*self.row, dtype=int).reshape(self.row, self.col)        self._initUi()    def _initUi(self):        self.setStyleSheet("background-color:grey")        self.setWindowTitle("life game")        self.setWindowIcon(QIcon("icon/life_game_icon.jpg"))        button = QPushButton("reset", self)        button.clicked.connect(self.reset)        button.move(300, 300)    def reset(self):        self.life_state = np.random.randint(0, 2, size = [self.row, self.col])    def _neighbor_num(self, i, j, arr):        num = 0        d_row = [-1, -1, -1, 0, 0, 1, 1, 1]        d_col = [-1, 0, 1, -1, 1, -1, 0, 1]        for k in range(8):            ii = i + d_row[k]            jj = j + d_col[k]            if ii in range(arr.shape[0]) and jj in range(arr.shape[1]) and arr[ii][jj] != 0:                num += 1        return num    def update_neighbor_num(self):        size = self.life_state.shape        for i in range(size[0]):            for j in range(size[1]):                self.neighbor[i][j] = self._neighbor_num(i, j, self.life_state)    def update_life_state(self):        size = self.life_state.shape        for i in range(size[0]):            for j in range(size[1]):                if self.neighbor[i][j] == 2:                    pass                elif self.neighbor[i][j] == 3:                    self.life_state[i][j] = 1                else:                    self.life_state[i][j] = 0    def paintEvent(self, event):        qp = QPainter()        qp.begin(self)        self.drawPoints(qp)        qp.end()    def drawPoints(self, qp):        qp.setPen(Qt.black)        size = self.life_state.shape        for i in range(size[0]):            for j in range(size[1]):                if self.life_state[i][j] != 0:                    qp.drawPoint(i, j)    def run(self):        self.show()        self.timer = QBasicTimer()        self.timer.start(1, self)        self.step = 0    def timerEvent(self, event):        if (self.life_state == self.end_state).all():            return        else:            self.step += 1            self.repaint()            self.update_neighbor_num()            self.update_life_state()class LifeGamePlus(LifeGame):    def __init__(self, row, col, cell_width, cell_height):        self.CellWidth = cell_width        self.CellHeight = cell_height        # self.cellImage = QImage("icon/cell.jpg")        super(LifeGamePlus, self).__init__(row, col)    def _initUi(self):        self.setStyleSheet("background-color:grey")        self.setWindowTitle("life game")        self.setWindowIcon(QIcon("icon/life_game_icon.jpg"))        self.setMinimumSize(QSize(self.col*self.CellWidth, self.row*self.CellHeight))    def paintEvent(self, event):        qp = QPainter()        qp.begin(self)        self.drawCells(qp)        qp.end()    def drawCells(self, qp):        qp.setPen(Qt.black)        size = self.life_state.shape        colorTable = [0x000000, 0xCC6666, 0x66CC66, 0x6666CC,                      0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00]        for i in range(size[0]):            for j in range(size[1]):                # color = QColor(colorTable[random.randint(0,7)])                if self.life_state[i][j] != 0:                    rect = QRect(i*self.CellWidth, j*self.CellHeight, self.CellWidth, self.CellHeight)                    qp.fillRect(i*self.CellWidth, j*self.CellHeight, self.CellWidth, self.CellHeight, Qt.black)                    # qp.drawImage(rect, self.cellImage)class LifeGamePlusWindow(QMainWindow):    def __init__(self, row, col, cell_width, cell_height):        super(LifeGamePlusWindow, self).__init__()        self.row = row        self.col = col        self.CellWidth = cell_width        self.CellHeight = cell_height        self._initUi()    def _initUi(self):        self.setStyleSheet("background-color:grey")        self.setWindowTitle("life game")        self.setWindowIcon(QIcon("icon/life_game_icon.jpg"))        self.lifeGameBoard = LifeGamePlus(self.row, self.col, self.CellWidth, self.CellHeight)        self.setCentralWidget(self.lifeGameBoard)        self.statusBar().showMessage("game on")        exitAction = QAction(QIcon("icon/startGame.jpg"), "&start", self)        exitAction.setShortcut("Ctrl+Q")        exitAction.setStatusTip("reset the game")        exitAction.triggered.connect(self.lifeGameBoard.reset)        menuBar = self.menuBar()        startMenu = menuBar.addMenu("&start")        startMenu.addAction(exitAction)    def run(self):        self.lifeGameBoard.run()        self.show()if __name__ == "__main__":    app = QApplication(sys.argv)    current = LifeGamePlusWindow(40, 40, 10, 10)    current.run()    app.exec_()

这里写图片描述