您的位置:首页 > 其它

使用PySide实现生命游戏

2017-07-19 18:48 330 查看
生命游戏的规则可以直接百度生命游戏

使用PySide主要思路是创建一个主要的窗体QWidget,

通过QPainter来重绘窗体来显示元胞位置,可以先抽象成每个位置是一个点,用一个二维数组来记录gridworld上的地图, 每次扫描地图,确定每个位置周围活细胞数目,也用一个二维数组记录下来,然后在下一个时间时重绘

使用QBasicTimer来做定时器,具体做法是,在窗体类 里面创建一个QBasicTimer实例,然后修改timerEvent方法,也就是在timerEvent里面实现每一步的动作

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

# -*-coding:utf-8 -*-

__author__ = "Boyce"

'''
life game
'''

import sys
from PySide.QtCore import *
from PySide.QtGui import *
import numpy as np
import random

class 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_()


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: