Reputation: 33
I'm trying to make a program with python to draw some columns and then to sort them from small to large. Drawing will be done with the pygame module.
The program works so far: With the c-key a new set of random length columns are placed in a list. This is immediately visible on the pygame window. When you press the c-key more than one time the window will show the new columns, just as expected.
With the s-key a sorting routine must be called and after sorting the columns must be redrawn on the pygame window. This redrawing from this function does not happen. I tried to put some print statements (commented out in the code now) to try to follow what"s going on. It shows that there is some kind of sorting as the order of the columns in the list are really changing. It only won't print the new order on the window.
The code is as follows:
import pygame
import math
import random
from queue import PriorityQueue
WIDTH = 800
WIN = pygame.display.set_mode((WIDTH, WIDTH))
pygame.display.set_caption("Sorting Columns")
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 255, 0)
WHITE = (255, 255, 255)
GREY = (128, 128, 128)
TURQUOISE = (64, 224, 208)
class Column:
def __init__(self, col, HIGHT, WIDTH, total_cols):
self.col = col
self.hight = HIGHT
self.x = col * WIDTH
self.y = WIDTH
self.color = TURQUOISE
self.neighbors = []
self.WIDTH = WIDTH
self.total_cols = total_cols
def get_pos(self):
return self.col
def get_hight(self):
return self.HIGHT
def is_open(self):
return self.color == GREEN
def make_newcolumn(self):
self.color = TURQUOISE
def make_sorted(self):
self.color = BLUE
def update_neighbors(self, grid):
pass
def draw(self, win):
pygame.draw.rect(win, self.color, (self.x, 800-self.hight, self.WIDTH, 800))
def __lt__(self, other):
return False
def sort_columns(draw, COLS, grid):
for i in range(COLS):
#print(grid[i].hight)
count = i + 1
#print(count)
#print(len(grid))
#print(i)
#print(COLS)
#print(grid[(count)].hight)
if count < len(grid):
#print("\n\n\n")
#print(grid[i].hight)
#print(grid[count].hight)
if grid[i].hight > grid[count].hight:
#print(grid[i].hight)
#print(grid[count].hight)
temp1 = grid[i]
grid[i] = grid[count]
grid[count] = temp1
#print(grid[i].hight)
#print(grid[count].hight)
#print("hello")
count += 1
for k in range(COLS):
print(grid[k].hight)
draw()
return False
def make_cols(cols, WIDTH):
columns = []
gap = WIDTH // cols
for i in range(cols):
h = random.randrange(10, 790, 10)
print(h)
kolom = Column(i, h, gap, cols)
columns.append(kolom)
return columns
def draw_cols(win, cols, WIDTH):
gap = WIDTH // cols
for j in range(cols):
pygame.draw.line(win, GREY, (j * gap, 0), (j * gap, WIDTH))
def draw(win, grid, cols, WIDTH):
win.fill(WHITE)
for Column in grid:
Column.draw(win)
draw_cols(win, cols, WIDTH)
pygame.display.update()
def main(win, WIDTH):
COLS = 5
grid = make_cols(COLS, WIDTH)
run = True
while run:
draw(win, grid, COLS, WIDTH)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
pass
if event.key == pygame.K_c:
grid = make_cols(COLS, WIDTH)
draw(win, grid, COLS, WIDTH)
if event.key == pygame.K_s:
print("\n")
sort_columns(lambda: draw(win, grid, COLS, WIDTH),COLS, grid)
draw(win, grid, COLS, WIDTH)
pygame.quit()
main(WIN, WIDTH)
Through the lambda function in the mainloop the draw function is called. Anyone any hint why this isn't working?
P.S. I'm very aware that the sorting function is far from ready, I'm working om it. It will be helpful if the graphics will show the order of the list of columns so I can continue on this.
Upvotes: 1
Views: 87
Reputation: 367
pygame.draw.rect(win, self.color, (self.x, 800 - self.hight, self.WIDTH, 800))
You haven't updated x. Even though the Column
s are sorted in the grid, each Column
is redrawn in the same place.
Upvotes: 0
Reputation:
You need to copy the grid instead of modifying the original one. Also list has a built-in sort function that can sort the elements based on the key. You are also attempting to call draw in sorting function. This wont work because sort only happens as long as s-key is being held down.
One last thing, because the window is 800 pixels, it goes off the screen so you cannot see the whole columns which makes things look weird.
import pygame
import math
import random
from queue import PriorityQueue
WIDTH = 800
WIN = pygame.display.set_mode((WIDTH, WIDTH))
pygame.display.set_caption("Sorting Columns")
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 255, 0)
WHITE = (255, 255, 255)
GREY = (128, 128, 128)
TURQUOISE = (64, 224, 208)
class Column:
def __init__(self, col, HIGHT, WIDTH, total_cols):
self.col = col
self.hight = HIGHT
self.x = col * WIDTH
self.y = WIDTH
self.color = TURQUOISE
self.neighbors = []
self.WIDTH = WIDTH
self.total_cols = total_cols
def get_pos(self):
return self.col
def get_hight(self):
return self.HIGHT
def is_open(self):
return self.color == GREEN
def make_newcolumn(self):
self.color = TURQUOISE
def make_sorted(self):
self.color = BLUE
def update_neighbors(self, grid):
pass
def draw(self, win):
pygame.draw.rect(win, self.color, (self.x, 800 - self.hight, self.WIDTH, 800))
def __lt__(self, other):
return False
def sort_columns(grid):
grid.sort(key=lambda h: h.hight)
return grid
def make_cols(cols, WIDTH):
columns = []
gap = WIDTH // cols
for i in range(cols):
h = random.randrange(10, 790, 10)
kolom = Column(i, h, gap, cols)
columns.append(kolom)
return columns
def draw_cols(win, cols, WIDTH):
gap = WIDTH // cols
for j in range(cols):
pygame.draw.line(win, GREY, (j * gap, 0), (j * gap, WIDTH))
def draw(win, grid, cols, WIDTH):
for Column in grid:
Column.draw(win)
draw_cols(win, cols, WIDTH)
pygame.display.update()
def main(win, WIDTH):
COLS = 3
grid = make_cols(COLS, WIDTH)
grid_ = make_cols(COLS, WIDTH)
run = True
while run:
win.fill(WHITE)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
pass
if event.key == pygame.K_c:
grid_ = make_cols(COLS, WIDTH)
if event.key == pygame.K_s:
gird = sort_columns(grid)
grid_ = grid
draw(win, grid_, COLS, WIDTH)
pygame.quit()
main(WIN, WIDTH)
Upvotes: 1