1.5.17. fejezet, Útvonal keresés

Rekurzív útvonal keresés

Komponensek telepítése:

python3 -m pip install -U pygame --user

Rekurzív kép kitöltés:

import pygame
from pygame.locals import *
import sys
import time
 
pygame.init()
black = pygame.Color(0, 0, 0)
white = pygame.Color(255, 255, 255)
blue =  pygame.Color(0, 0, 255)
red =  pygame.Color(255, 0, 0)
green =  pygame.Color(0, 255, 0)
 
DISPLAY_WIDTH = 150
DISPLAY_HEIGHT = 120
 
display = pygame.display.set_mode((DISPLAY_WIDTH,DISPLAY_HEIGHT))
fillColor = blue
def applyColorRecursive(current_pos):
    if display.get_at(current_pos) == white:
        display.set_at(current_pos,fillColor)
        pygame.display.update()
        time.sleep(0.0001)
 
    # Left
    if current_pos[0] > 0 and display.get_at((current_pos[0]-1,current_pos[1])) == white:
        applyColorRecursive((current_pos[0]-1,current_pos[1]))
 
    # Right
    if current_pos[0]+1 < DISPLAY_WIDTH and display.get_at((current_pos[0]+1,current_pos[1])) == white:
        applyColorRecursive((current_pos[0]+1,current_pos[1]))
 
    # Up
    if current_pos[1] > 0 and display.get_at((current_pos[0],current_pos[1]-1)) == white:
        applyColorRecursive((current_pos[0],current_pos[1]-1))
 
    # Down
    if current_pos[1]+1 < DISPLAY_HEIGHT and display.get_at((current_pos[0],current_pos[1]+1)) == white:
        applyColorRecursive((current_pos[0],current_pos[1]+1))
 
def main():
    display.fill(white)
 
    pygame.draw.rect(display,black, Rect(10,10,40,40), 1)
    pygame.draw.circle(display, black, (50,50), 20, 1)
 
    sys.setrecursionlimit(999999999)
    applyColorRecursive((25,25))
 
    global fillColor
    fillColor = red
 
    applyColorRecursive((5,5))
 
    fillColor = green
    applyColorRecursive((55,55))
 
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
 
        pygame.display.update()
 
if __name__ == '__main__':
    main()

Deque használata nagyobb terepen

import pygame
from pygame.locals import *
import sys
import time
from collections import deque
 
pygame.init()
 
DISPLAY_WIDTH = 640
DISPLAY_HEIGHT = 480
 
display = pygame.display.set_mode((DISPLAY_WIDTH,DISPLAY_HEIGHT))
 
black = pygame.Color(0, 0, 0)
white = pygame.Color(255, 255, 255)
blue =  pygame.Color(0, 0, 255)
red =  pygame.Color(255, 0, 0)
green =  pygame.Color(0, 255, 0)
gray =  pygame.Color(200, 200, 200)
fillColor = blue
def applyColor(current_pos):
    stack = deque()
    stack.append(current_pos)
    while len(stack) > 0 :
        current_pos = stack[-1]
        if display.get_at((current_pos[0],current_pos[1])) == white:
            display.set_at((current_pos[0],current_pos[1]),fillColor)
            #time.sleep(0.00001)
            pygame.display.flip()
 
        match current_pos[2]:
            case 0:
                # Left
                if current_pos[0] > 0 and display.get_at((current_pos[0]-1,current_pos[1])) == white:
                    stack.append((current_pos[0]-1,current_pos[1],0))
                else:
                    stack[-1] = (current_pos[0],current_pos[1],current_pos[2]+1)
            case 1:
                # Right
                if current_pos[0]+1 < DISPLAY_WIDTH and display.get_at((current_pos[0]+1,current_pos[1])) == white:
                    stack.append((current_pos[0]+1,current_pos[1],0))
                else:
                    stack[-1] = (current_pos[0],current_pos[1],current_pos[2]+1)
            case 2:
                # Up
                if current_pos[1] > 0 and display.get_at((current_pos[0],current_pos[1]-1)) == white:
                    stack.append((current_pos[0],current_pos[1]-1,0))
                else:
                    stack[-1] = (current_pos[0],current_pos[1],current_pos[2]+1)
            case 3:
                # Down
                if current_pos[1]+1 < DISPLAY_HEIGHT and display.get_at((current_pos[0],current_pos[1]+1)) == white:
                    stack.append((current_pos[0],current_pos[1]+1,0))
                else:
                    stack[-1] = (current_pos[0],current_pos[1],current_pos[2]+1)
 
            case default:
                stack.pop()
 
def main():
    display.fill(white)
 
    imp = pygame.image.load("test.png").convert()
    display.blit(imp, (0, 0))
    pygame.display.flip()
 
    applyColor((25,25,0))
 
    global fillColor
 
    fillColor = red
    applyColor((345,275,0))
 
    fillColor = pygame.Color(250,140,50)
    applyColor((410,200,0))
 
    fillColor = green
    applyColor((155,155,0))
 
    fillColor = gray
    applyColor((215,215,0))
 
    fillColor = pygame.Color(255,0,150)
    applyColor((485,185,0))
 
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
 
        pygame.display.update()
 
if __name__ == '__main__':
    main()

Vonal húzása útvonal optimalizáláshoz

import pygame
from pygame.locals import *
import sys
import time
from collections import deque
 
pygame.init()
 
DISPLAY_WIDTH = 640
DISPLAY_HEIGHT = 480
 
display = pygame.display.set_mode((DISPLAY_WIDTH,DISPLAY_HEIGHT))
 
black = pygame.Color(0, 0, 0)
white = pygame.Color(255, 255, 255)
 
def plot(x, y):
    display.set_at((x,y),black)
 
def plotLine(x0, y0, x1, y1):
    dx = abs(x1 - x0)
    sx = 1 if x0 < x1 else -1
    dy = -abs(y1 - y0)
    sy = 1 if y0 < y1 else -1
    error = dx + dy
 
    while True:
        plot(x0, y0)
        if x0 == x1 and y0 == y1:
            break
        e2 = 2 * error
        if e2 >= dy:
            if x0 == x1:
                break
            error = error + dy
            x0 = x0 + sx
 
        if e2 <= dx:
            if y0 == y1:
                break
            error = error + dx
            y0 = y0 + sy
 
def main():
    display.fill(white)
    plotLine(100,480,150,20)
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
 
        pygame.display.update()
 
if __name__ == '__main__':
    main()