Miura
Miura

Reputation: 33

Python pygame won't redraw after sort function

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

Answers (2)

arunkumaraqm
arunkumaraqm

Reputation: 367

pygame.draw.rect(win, self.color, (self.x, 800 - self.hight, self.WIDTH, 800))

You haven't updated x. Even though the Columns are sorted in the grid, each Column is redrawn in the same place.

Upvotes: 0

user12291970
user12291970

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

Related Questions