我在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]
我没有收到任何错误,董事会正在出现,但这对我来说仍然不合适......
答案 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 ... in
。 for
是一个循环,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