2015-06-26 58 views
0

我完全難住。我用主題標籤包圍了問題的癥結所在。任何幫助深表感謝!我編輯我的列表的一個值,但所有其他值似乎也編輯(完整的代碼)

import pygame 
import time 
import random 

pygame.init() 

display_width = 600 
display_height = 600 
display = pygame.display.set_mode((display_width, display_height)) 
pygame.display.set_caption('Snake') 
clock = pygame.time.Clock() 
fps = 10 

white = (255, 255, 255) 
red = (200, 0, 0) 
green = (0, 200, 0) 
blue = (0, 0, 200) 
black = (0, 0, 0) 

def extend_snake(snake): 
    x = snake[len(snake) - 1][0] 
    y = snake[len(snake) - 1][1] 
## for i in snake: 
##  print(i) 
    return ([x, y]) 

def spawn_fruit(): 
    x = random.randrange(fruit_rad, display_width - fruit_rad, 2 * fruit_rad) 
    y = random.randrange(fruit_rad, display_height - fruit_rad, 2 * fruit_rad)  
    return ((x, y)) 

def pause(): 
    while True: 
     for event in pygame.event.get(): 
      if event.type == pygame.QUIT: 
       pygame.quit() 
       quit() 
      if event.type == pygame.KEYDOWN: 
       if event.key == pygame.K_p: 
        return 

score = 0 

snake = [] 
snake_size = 10 
snake.append([display_width/2, display_height/2]) 
snake_dx = 0 
snake_dy = 0 

fruit = [] 
fruit_count = 5 
fruit_rad = 5 
for a in range(fruit_count): 
    fruit.append(spawn_fruit()) 

while True: 
    for event in pygame.event.get(): 
     if event.type == pygame.QUIT: 
      pygame.quit() 
      quit() 
     if event.type == pygame.KEYDOWN: 
      if event.key == pygame.K_p: 
       pause()   
      elif event.key == pygame.K_a or event.key == pygame.K_LEFT: 
       snake_dx = -snake_size 
       snake_dy = 0 
      elif event.key == pygame.K_d or event.key == pygame.K_RIGHT: 
       snake_dx = snake_size 
       snake_dy = 0 
      elif event.key == pygame.K_w or event.key == pygame.K_UP: 
       snake_dy = -snake_size 
       snake_dx = 0 
      elif event.key == pygame.K_s or event.key == pygame.K_DOWN: 
       snake_dy = snake_size 
       snake_dx = 0 

    print(snake) 
    for coord in fruit: 
     if snake[0][0] + fruit_rad == coord[0] and snake[0][1] + fruit_rad == coord[1]: 
      fruit.remove(coord) 
      fruit.append(spawn_fruit()) 
      snake.append(extend_snake(snake)) 
      score += 1 
      fps += 1 

    for i in range(len(snake) - 1, 0, -1): 
     snake[i] = snake[i - 1] 
############################################ ####
try: 
     print('1', snake[1]) 
    except: 
     pass 
    snake[0][0] += snake_dx 
    snake[0][1] += snake_dy 
    try: 
     print('2', snake[1]) 
    except: 
     pass 
######################################### ################
display.fill(white) 
    for coord in fruit: 
     pygame.draw.circle(display, red, coord, fruit_rad) 
    for coord in snake: 
     pygame.draw.rect(display, black, [coord[0], coord[1], snake_size, snake_size]) 

    pygame.display.update() 
    clock.tick(fps) 

這將返回例如:
1(100,100)
2(110,100)

不管我在哪裏打印(蛇),其中每個列表都是相同的。 請問有人可以解釋爲什麼會發生這種情況,我能做些什麼來阻止它?

+1

總之,我相信還會有更完整的答案波紋管,名單是在Python mutables。請參閱[this](http://stackoverflow.com/questions/8056130/immutable-vs-mutable-types-python)以獲取更多詳細信息,特別是第二個答案有一些不錯的展示代碼。如果你有一個列表'a'並且說'b = a'改變'b'也會改變'a'。 – ljetibo

+0

謝謝,我會研究mutables。我還沒有遇到任何與C#或VB呢。 – Mike

回答

1

設置snake [i] = snake [i-1]使它們成爲同一個對象,因此解釋了爲什麼它們都被編輯,即使代碼只編輯其中一個。

1

當你正在做 - snake[i] = snake[i - 1],你只是通過snake[i - 1]的參考snake[i]。這似乎當你做出的任何位置內snake[i]你實際上是進行更改到引用對象的任何變化發生的所有i

然後,因此改變在所有其他snake[i]反映也是如此。

爲了您的邏輯來工作,你需要使用copy.deepcopy來創建對象的深層副本,以便更改未在其他snake[i]小號

在你的情況反映,你需要做的 -

import copy 
for i in range(len(snake) - 1, 0, -1): 
    snake[i] = copy.deepcopy(snake[i - 1]) 

例子 -

>>> l = [1,2,3] 
>>> l1 = l 
>>> l 
[1, 2, 3] 
>>> l1 
[1, 2, 3] 
>>> l1.pop(1) 
2 
>>> l1 
[1, 3] 
>>> l 
[1, 3] 
>>> import copy 
>>> l2 = copy.deepcopy(l) 
>>> l2 
[1, 3] 
>>> l2.append(4) 
>>> l2 
[1, 3, 4] 
>>> l 
[1, 3] 
>>> l1 
[1, 3] 
相關問題