生命游戏Pygame

时间:2015-10-16 05:47:23

标签: python multidimensional-array pygame cell conways-game-of-life

我在python中创造了生命游戏。我不确定我是否正确地做到了。

get_cell函数对我来说似乎不对。另外我想在count_neighbors函数中使用这个函数。

我做错了什么,或者可以做得更好?

import pygame
import time
import sys

HEIGHT = 50
WIDTH = 50

SCALE = 10
SCREEN = pygame.display.set_mode((WIDTH*SCALE, HEIGHT*SCALE))


def create_blank():
    """Creates a HEIGHT x WIDTH list containing all zero's. The inner lists 
    will all be WIDTH long and the outer list will HEIGHT long."""
    board = [[0]*WIDTH]*HEIGHT
    return board


def get_cell(board, x, y):
    """Returns the game board at position x,y , this is 1 if the cell at that 
    position is alive and 0 if the cell is dead. If the x or y parameters are
    out of bounds (not valid coordinates), the function returns 0."""
    for x in range(WIDTH):
        for y in range(HEIGHT):
            return board[y][x]
    else:
        return 0


def count_neighbours(board, x, y):
    """Counts the number of alive neighbours around the position x,y , including 
    diagonal neighbours. Does not include the cell itself."""
    count = 0
    for i in range(x-1,x+2):
      for j in range(y-1,y+2):
        if not(i == x and j == y):
                count += int(mat[i][j])


def update(board):
    """Creates a new board copy and applies the game rules to each cell using 
    the old board. Does not modify the old board. Returns the new board."""
    if(count < 2 or count > 3):
      return 0
    elif count == 3:
      return 1
    else:
      return mat[i][j] 

我没有收到任何错误,董事会正在出现,但这对我来说仍然不合适......

3 个答案:

答案 0 :(得分:1)

问题在于:

board = [[0]*WIDTH]*HEIGHT

术语实例表示每块电路板具有相同的对象(而不是HEIGHT个副本,如您所料。)

以下示例可能会使事情变得清晰:

>>> WIDTH=2
>>> HEIGHT=3
>>> board = [[0]*WIDTH]*HEIGHT
>>> board
[[0, 0], [0, 0], [0, 0]]
>>> board[1][1] = 3
>>> board
[[0, 3], [0, 3], [0, 3]]

但是,如果你使用

board = [[0 for x in range(WIDTH)] for y in range(HEIGHT)]
而不是(即每次创建一个新的实例),结果如下所示:

[[0, 0], [0, 3], [0, 0]]

编辑进一步改进

我建议使用numpy。

import numpy as np

...

board = np.zeros([HEIGHT,WIDTH], dtype=int)

...

def count_neighbours(board, x, y):
    return np.sum(board[x-1:x+2][y-1:y+2]) - board[x][y]

答案 1 :(得分:1)

你错误地在一个范围内进行迭代,而不是检查范围内的成员资格:

>>> x = 3
>>> for x in range(5):
...     print x
1
2
3
4
5

而不是for ... in,您需要使用if ... infor是一个循环,if是一个分支:

>>> x = 3
>>> if x in range(5):
...     print x
3

所以,get_cell将是:

def get_cell(board, x, y):
    if x in range(WIDTH) and y in range(HEIGHT):
        return board[y][x]
    else:
        return 0

答案 2 :(得分:0)

其他人已经告诉过您代码的问题,但请注意,您可以使用import java.awt.*; import java.awt.event.*; import javax.swing.*; public class TestMainFrame { private static JFrame frame; private static JTextArea textArea; public TestMainFrame() { createAndShowGUI(); } private void createAndShowGUI() { frame = new JFrame("Test"); frame.setLayout(new BorderLayout()); final JButton btn = new JButton("Test Me"); btn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (btn.getText().equals("Test Me")) { testMe(); } } }); textArea = new JTextArea("This is a test pane! \n"); textArea.setEditable(false); JScrollPane scroller = new JScrollPane(textArea); frame.add(scroller, BorderLayout.CENTER); frame.add(btn, BorderLayout.PAGE_END); frame.setSize(new Dimension(300, 400)); frame.setVisible(true); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } private static void testMe() { writeToTextArea("Button Pressed"); writeToTextArea("Starting tests"); SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() { @Override public Void doInBackground() { writeToTextArea("Inside the doInBackground method of SwingWorker"); return null; } @Override public void done() { writeToTextArea("The SwingWorker has finished"); } }; worker.execute(); } // *** note change *** private static void writeToTextArea(final String text) { if (SwingUtilities.isEventDispatchThread()) { textArea.append(text + "\n"); } else { SwingUtilities.invokeLater(new Runnable() { public void run() { textArea.append(text + "\n"); } }); } } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { TestMainFrame testMainFrame = new TestMainFrame(); testMainFrame.createAndShowGUI(); } }); } } 代替嵌套列表来简化代码。

这是一个完整的示例,使用set作为棋盘,使用pygame进行显示。使用鼠标按钮创建或终止单元格。

set

enter image description here