like the title says I wanted to create a visualized bubble sort with python and pygame. The sort works perfectly but when it comes to visualize it it never gets the correct output.
Here's the code:
import pygame
import sys
import time
pygame.init()
Vector_len = 0
x = 0
numbers_to_order = []
IsRunning = True
Vector_len = eval(input("How many numbers do you want to sort? "))
for i in range(Vector_len):
numbers_to_order.append(0)
for i in range(len(numbers_to_order)):
numbers_to_order[i] = eval(input("Insert number at index "+str(i+1)+": "))
print("Inserted array: "+str(numbers_to_order))
screen = pygame.display.set_mode((1000,500))
while IsRunning:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
IsRunning = False
for i in range(len(numbers_to_order)):
for j in range(len(numbers_to_order)):
try:
if numbers_to_order[j] > numbers_to_order[j+1]:
x = numbers_to_order[j]
numbers_to_order[j] = numbers_to_order[j+1]
numbers_to_order[j+1] = x
except(IndexError):
pass
pygame.draw.rect(screen,(255,255,255),(j*(1000/len(numbers_to_order)),500-(numbers_to_order[j])*50,(1000/len(numbers_to_order)),(numbers_to_order[j])*50))
print((j*(1000/len(numbers_to_order)), (numbers_to_order[j])*50))
pygame.display.flip()
time.sleep(0.05)
print("Sorted array: "+str(numbers_to_order))
pygame.quit()
sys.exit()
When running, instead of showing the bars sorting correctly, they are displayed in a wrong order but the sort is correct. Any help?
The major issue is that you've to clear the display in every frame and to draw the entire "list" in every frame. Note, if a bar for a large number was drawn at position, then a bar for a smaller number won't "clear" that.
screen.fill(0)
for k, n in enumerate(numbers_to_order):
pygame.draw.rect(screen,(255,255,255),(k*(1000/len(numbers_to_order)),500-(numbers_to_order[k])*50,(1000/len(numbers_to_order)),(n)*50))
I recommend not to use nested loops in the game loop, which draw the scene. Use the main application loop and increment the control variables i
and j
in the loop:
i = 0
j = 0
while IsRunning:
# [...]
if j < len(numbers_to_order)-1:
j += 1
elif i < len(numbers_to_order)-1:
i += 1
j = 0
Further i recommend to use pygame.time.Clock()
See the example:
# start control variables
i = 0
j = 0
IsRunning = True
# main loop
clock = pygame.time.Clock()
while IsRunning:
# handle events
for event in pygame.event.get():
if event.type == pygame.QUIT:
IsRunning = False
if event.type == pygame.MOUSEBUTTONDOWN:
IsRunning = False
# clear screen
screen.fill(0)
# draw the entire range
for k, n in enumerate(numbers_to_order):
pygame.draw.rect(screen,(255,255,255),(k*(1000/len(numbers_to_order)),500-(numbers_to_order[k])*50,(1000/len(numbers_to_order)),(n)*50))
# update the display
pygame.display.flip()
clock.tick(10)
# sort (1 step)
print((j*(1000/len(numbers_to_order)), (numbers_to_order[j])*50))
try:
if numbers_to_order[j] > numbers_to_order[j+1]:
x = numbers_to_order[j]
numbers_to_order[j] = numbers_to_order[j+1]
numbers_to_order[j+1] = x
except(IndexError):
pass
# increment control variables
if j < len(numbers_to_order)-1:
j += 1
elif i < len(numbers_to_order)-1:
i += 1
j = 0