2014-01-26 16 views
0

Я пытаюсь заполнить цвет в многоугольнике, используя рекурсивный алгоритм наводнения. Я кодирую в python 2.7. Я иду на полпути к заполнению, затем падает. Это происходит все время, когда я запускаю код. Есть ли что-то неправильно с кодом, или это просто проблема в моем ноутбуке. Пожалуйста помоги? Спасибо. Вот код.алгоритм заполнения наводнений в python

import pygame 
    import numpy as np 
    from pygame.locals import * 
    import sys 
    def flood_fill(name, x, y, color): 
     get = name.get_at((x, y)) 
     if get == (0, 0, 0, 255): 
      screen.set_at((x, y), red) 
      pygame.display.flip() 
      flood_fill(name, x + 1, y, color) 
      flood_fill(name, x - 1, y, color) 
      flood_fill(name, x, y + 1, color) 
      flood_fill(name, x, y - 1, color) 

    if __name__ == '__main__': 
     pygame.init() 
     sys.setrecursionlimit(1500000000) 
     width = 640 
     height = 480 
     resolution = (width, height) 
     screen = pygame.display.set_mode(resolution) 
     black = (0, 0, 0) 
     white = (255, 255, 255) 
     red = (255, 0, 0) 
     pygame.draw.rect(screen, white, [20, 20, 250, 100], 2) 
     flood_fill(screen, 100, 50, red) 
     while True: 
      for event in pygame.event.get(): 
       if event.type == QUIT: 
        pygame.quit() 
        sys.exit() 
      pygame.display.flip() 
+2

Какое сообщение об ошибке при сбое? – Miquel

+0

Я не знаком с 'pygame', но я предполагаю, что у вас есть незаконные индексы в' name.get_at ((x, y)) '. Проверьте координаты или поймайте рассматриваемое исключение с помощью 'pass' (что, вероятно, не является хорошим стилем). –

+0

@MOehm Я думал то же самое, но я думаю, что его функция не должна когда-либо попадать в незаконные параметры, потому что его переданные параметры гарантируют, что наводнение завершится до краев экрана (если правильно написано с курса). Думайте, проблема в другом месте. –

ответ

0

Вы должны предоставить ошибку, что вы получаете, но на основе кода, я думаю, что ошибка является IndexError, и вы должны проверить, если пиксельные координаты являются действительными координатами т.е. они всегда находятся внутри области из поверхность, которая находится в вашем случае screen.

Согласно documentation: If the pixel position is outside the area of the Surface an IndexError exception will be raised.

Просто убедитесь, что get_at метод получает действительные параметры или окружать его с try\except блока.

+0

думал то же самое, но пересмотрел его, так как параметры, он перешел к заливка, кажется, чтобы избежать случай, когда значения достигают краев экрана. –

+0

@VikramBhat Я уверен, что недействительные вызовы генерируются рекурсивными вызовами. Например, он называет 'flood_fill (name, x - 1, y, color)', не проверяя, действительно ли 'x-1'. – pkacprzak

+0

Я уверен, что это произойдет в общем случае, но параметры, которые он передал функции, пытаются нарисовать прямоугольник, наложив заливку на точку внутри прямоугольника, чтобы в любом случае она была прервана на границах, не достигнув недопустимых координат. Поэтому я не думаю, что это единственная проблема –

1

Довольно уверен, что ваш предел рекурсии является проблемой. Все setrecursionlimit действительно устраняет предупреждения, которые помешали бы вам делать глупые вещи; он не волшебным образом создает транзисторы в вашем CPU для хранения стека вызовов 1500000000.

Реализация заливки в стеке, как правило, является плохим. Вместо этого используйте стекную структуру данных стека.

+0

Но для следующего случая его максимальное пространство в стеке необходимо 250 * 100, которое будет меньше 1 МБ пространства, не должно быть проблемой для stackoverflow? –

+0

Не знаете, как вы попадаете на этот номер; имеет ли его процессор только 40 байтов регистров? Я сомневаюсь в этом, но если так, hed будет работать над каким-то встроенным процессором, имеющим всего лишь несколько килобайт памяти. Это даже не подсчет локальных переменных. Документы python отмечают, что setrecursionlimit может привести к сбоям; и это единственная небезопасная вещь, которую он делает. Независимо от того, нет никакой причины использовать всю эту память для простой заливки, и особенно это не ваша ограниченная память стека. –

+0

@EelcoHoogendoorm Я только говорю, что встроенная заливка на основе стека не так уж плоха по сравнению с структурой данных стека, основанной на сложности пространства, хотя может быть и медленнее. да, возможно, нет необходимости в setrecursionlimit –

Смежные вопросы