Posts: 57
Threads: 13
Joined: Sep 2017
Jan-12-2020, 05:53 PM
(This post was last modified: Jan-12-2020, 06:50 PM by xBlackHeartx.)
I'm developing a program that will simply generate all the possible colors if I restrict the rgb values to multiples of 51. Its working out so far, but right now some of my functions generate an infinite loop and I have no clue why. I initially ignored this, but then I opened up taskmanager to find out how much RAM the thing was taking, and I found it was perpetually increasing. Now I want to fix it, but I have no clue why its doing what its doing.
import pygame
pygame.init()
block=50
screenW=25*block
screenH=20*block
x=0
y=0
screen=pygame.display.set_mode((screenW,screenH))
red=False
green=False
blue=False
rg=False
rb=False
gb=False
def drawR():
r=255
g=0
b=0
global x
global y
global red
x=0
y=0
while r>=0 and red==False:
pygame.draw.rect(screen,(r,g,b),(x,y,block,block))
print("red",r,g,b)
r-=51
y+=block
if r<=0:
red=True
def drawG():
r=0
g=255
b=0
global x
global y
global green
x=block
y=0
while g>=0 and green==False:
pygame.draw.rect(screen,(r,g,b),(x,y,block,block))
print("green",r,g,b)
g-=51
y+=block
if g<=0:
green=True
def drawB():
r=0
g=0
b=255
global x
global y
global blue
x=block*2
y=0
while b>=0 and blue==False:
pygame.draw.rect(screen,(r,g,b),(x,y,block,block))
print("blue",r,g,b)
b-=51
y+=block
if b<=0:
blue=True
def drawRG():
r=255
g=255
b=0
global x
global y
global rg
x=block*3
y=0
while r>=51 and g>=51 and rg==False:
pygame.draw.rect(screen,(r,g,b),(x,y,block,block))
print("redgreen",r,g,b)
r-=51
if r<51:
r=255
g-=51
if r==0 and g==51:
rg=True
y+=block
if y>block*4:
y=0
x+=block
def drawRB():
r=255
g=0
b=255
global x
global y
global rb
x=block*8
y=0
while r>=51 and b>=51 and rb==False:
pygame.draw.rect(screen,(r,g,b),(x,y,block,block))
print("redblue",r,g,b)
r-=51
if r<51:
r=255
b-=51
if r==0 and b==51:
rb=True
y+=block
if y>block*4:
y=0
x+=block
def drawGB():
r=0
g=255
b=255
global x
global y
global gb
x=block*13
y=0
while b>=51 and g>=51 and rg==False:
pygame.draw.rect(screen,(r,g,b),(x,y,block,block))
print("bluegreen",r,g,b)
b-=51
if b<51:
b=255
g-=51
if b==0 and g==51:
gb=True
y+=block
if y>block*4:
y=0
x+=block
def main():
while True:
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
exit()
drawR()
drawG()
drawB()
drawRG()
drawRB()
drawGB()
pygame.display.update()
main() What makes no sense is the first three functions (drawR, drawG, and drawB) do NOT make an infinite loop, but the latter three do (at least, they do when they print out the rgb value of each square they draw). They're based on the first three, so I can't fathom why they would do this. Their loops DO have an end point, just like the ones that draw the primary colors. Yeah, they're a bit more elaborate, but that's just because they have to change two values rather than one. I would guess this is a logic error somewhere, except I already made sure that the loops DON'T repeat. I have no clue what could be wrong.
I take it I'm just going to get an answer here? Go figure.
And then someone comes in and sabotages my thread. Aren't you all considerate? The owners of python should sue you for defamation at this rate.
Posts: 419
Threads: 34
Joined: May 2019
The first three run and then set the global variable to False. The last three don't do that so they are never told to stop.
Posts: 57
Threads: 13
Joined: Sep 2017
Uh, what are you talking about? The drawRG function sets its variable to true on line 104, and that variable is set to global on line 91. In my program, I have those variables set to false if the functions aren't done, and true when they are. Note how they're all declared false at the start of the program, and they're all outside the main loop.
Posts: 419
Threads: 34
Joined: May 2019
Ohhh.... I remember you.
If they were getting set to True then they would stop, that is the entire, specific purpose a while loop.
Add "rg", "rb", and "bg" to you print statements. They all stay False.
Posts: 57
Threads: 13
Joined: Sep 2017
Jan-12-2020, 09:51 PM
(This post was last modified: Jan-12-2020, 10:05 PM by xBlackHeartx.)
Strangely enough, I already tried to do that after I posted my last comment, but for some reason they won't print, even though the thing is printing the rgb values fine (I did that earlier to make sure it was rendering things right, it wasn't showing the right number of squares earlier). Also, changing the order of the commands doesn't fix the problem either. At this point, I'm starting to think my program is ignoring some of the lines.
Another thing I find really strange is it doesn't just do one loop over and over; it loops through all three. If they're caught in an infinite loop, then how can the program be cycling between all three of them? Shouldn't it remain locked in one loop?
I decided to put lines in the main loop to set the variables to True. That fixed the problem. I'm still mystified that it was ignoring the identical lines I typed in the original program.
Okay then, now I have another problem. Its suddenly not rendering one of the blocks of color! Specifically, the green-blue box. There is literally no difference between the function and the others; I copy-pasted them! And it WAS working before!
import pygame
pygame.init()
block=50
screenW=25*block
screenH=20*block
x=0
y=0
screen=pygame.display.set_mode((screenW,screenH))
list=[255,204,153,102,51]
red=False
green=False
blue=False
rg=False
rg_b=False
rb=False
rb_g=False
gb=False
gb_r=False
def drawR():
r=255
g=0
b=0
global x
global y
global red
x=0
y=0
while r>=0 and red==False:
pygame.draw.rect(screen,(r,g,b),(x,y,block,block))
print("red",r,g,b)
r-=51
y+=block
if r<=0:
red=True
def drawG():
r=0
g=255
b=0
global x
global y
global green
x=block
y=0
while g>=0 and green==False:
pygame.draw.rect(screen,(r,g,b),(x,y,block,block))
print("green",r,g,b)
g-=51
y+=block
if g<=0:
green=True
def drawB():
r=0
g=0
b=255
global x
global y
global blue
x=block*2
y=0
while b>=0 and blue==False:
pygame.draw.rect(screen,(r,g,b),(x,y,block,block))
print("blue",r,g,b)
b-=51
y+=block
if b<=0:
blue=True
def drawRG():
r=255
g=255
b=0
global x
global y
global rg
x=block*3
y=0
while r>=51 and g>=51 and rg==False:
pygame.draw.rect(screen,(r,g,b),(x,y,block,block))
print("redgreen",r,g,b)
r-=51
if r<51:
r=255
g-=51
if r==0 and g==51:
rg=True
y+=block
if y>block*4:
y=0
x+=block
def drawRB():
r=255
g=0
b=255
global x
global y
global rb
x=block*8
y=0
while r>=51 and b>=51 and rb==False:
pygame.draw.rect(screen,(r,g,b),(x,y,block,block))
print("redblue",r,g,b)
r-=51
if r<51:
r=255
b-=51
if r==0 and b==51:
rb=True
y+=block
if y>block*4:
y=0
x+=block
def drawGB():
r=0
g=255
b=255
global x
global y
global gb
x=block*13
y=0
while b>=51 and g>=51 and rg==False:
pygame.draw.rect(screen,(r,g,b),(x,y,block,block))
print("bluegreen",r,g,b)
b-=51
if b<51:
b=255
g-=51
if b==0 and g==51:
gb=True
y+=block
if y>block*4:
y=0
x+=block
##def drawRG_B():
## z=0
## for i in list:
## r=255
## g=255
## b=i
##
##
## global x
## global y
## global rg_b
##
## rg_b=False
##
## x=block*z
## y=block*5
##
## print(z)
##
## while r>=51 and g>=51 and b>=51 and rg_b==False:
## pygame.draw.rect(screen,(r,g,b),(x,y,block,block))
## print("redgreen-blue",r,g,b)
## r-=51
## if r<51:
## r=255
## g-=51
## if r==0 and g<=51 and b<=51:
## rg_b=True
## z+=5
##
## y+=block
## if y>block*9:
## y=block*5
## x+=block
def main():
while True:
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
exit()
global rg
global rb
global gb
drawR()
drawG()
drawB()
drawRG()
rg=True
drawRB()
rb=True
drawGB()
gb=True
## drawRG_B()
pygame.display.update()
main() This is getting stupid. Oh, and ignore the commented-out stuff. I gave up hope I was going to get help and started working on the functions for that would draw the boxes that had all three colors mixed in. Sadly though, it wasn't drawing all of them (its supposed to draw a series of five boxes with progressively higher blue values, it only draws the first), and it really ramped up the issue with the RAM (no pun intended). Honestly, I'll probably just delete that and start over once I fix the issue with the 2-color functions.
Posts: 419
Threads: 34
Joined: May 2019
The bottom 3 function use:
if b==0 and g==51:
gb=True The top 3 use "<="
Posts: 57
Threads: 13
Joined: Sep 2017
Doing that change doesn't fix the issue. Nor does removing the gb=True line in the main loop. What? Did making those global in the main loop mess up something?
Posts: 544
Threads: 15
Joined: Oct 2016
Jan-12-2020, 11:37 PM
(This post was last modified: Jan-12-2020, 11:37 PM by Windspar.)
Why are you not using range loops ?
You can do that. All with one function.
import os
import pygame
from itertools import product
def draw_color(surface, x, y, color, c_range, block):
y_top = y
red = range(color.r, -1, -c_range)
green = range(color.g, -1, -c_range)
blue = range(color.b, -1, -c_range)
for r, g, b in product(red, green, blue):
pygame.draw.rect(surface, (r, g, b), (x, y, block, block))
y += block
if y > block * 4 + y_top:
x += block
y = y_top
def main():
pygame.init()
# Center Screen before creating main surface.
os.environ['SDL_VIDEO_CENTERED'] = '1'
block = 50
size = block * 25, block * 25
# Basic pygame setup
pygame.display.set_caption("Colors")
surface = pygame.display.set_mode(size)
clock = pygame.time.Clock()
rect = surface.get_rect()
delta = 0
fps = 60
# Main Loop
running = True
while running:
# Event Loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Draw
surface.fill(pygame.Color('black'))
draw_color(surface, 0, 0, pygame.Color('red'), 50, block)
draw_color(surface, block, 0, pygame.Color('green'), 50, block)
draw_color(surface, block * 2, 0, pygame.Color('blue'), 50, block)
draw_color(surface, block * 4, 0, pygame.Color(255, 255, 0), 50, block)
draw_color(surface, block * 12, 0, pygame.Color(0, 255, 255), 50, block)
draw_color(surface, block * 4, block * 6, pygame.Color(255, 0, 255), 50, block)
# Render to screen
pygame.display.flip()
# Sleep/Idle and Delta
delta = clock.tick(fps)
main()
99 percent of computer problems exists between chair and keyboard.
Posts: 57
Threads: 13
Joined: Sep 2017
I can make no sense of that code. Also, it imports two modules I've never even heard of.
At this point, I'm thinking I need to just re-do the functions for the two-color blocks before moving on. Besides, I've tweaked the functions so much I can't even understand my own loops anymore.
And yes, I did think about making one function that could render everything, but I couldn't think of a way to get such to work, at least while using only python and pygame code. Honestly, at one point I was thinking it would actually take less lines of code if I just manually entered in every single possible combination rather than having an algorithm make them for me, and at this rate I'm still open to that being a possibility.
Posts: 57
Threads: 13
Joined: Sep 2017
I re-did the two-color functions, and now I no longer have an infinite loop. Also, the functions are far simpler this time since I based them off the single-color ones.
import pygame
pygame.init()
block=50
screenW=25*block
screenH=20*block
x=0
y=0
screen=pygame.display.set_mode((screenW,screenH))
list=[255,204,153,102,51]
red=False
green=False
blue=False
redgreen=False
redblue=False
greenblue=False
def drawR():
r=255
g=0
b=0
global x
global y
global red
x=0
y=0
while r>=0 and red==False:
pygame.draw.rect(screen,(r,g,b),(x,y,block,block))
print("red",r,g,b)
r-=51
y+=block
if r<=0:
red=True
def drawG():
r=0
g=255
b=0
global x
global y
global green
x=block
y=0
while g>=0 and green==False:
pygame.draw.rect(screen,(r,g,b),(x,y,block,block))
print("green",r,g,b)
g-=51
y+=block
if g<=0:
green=True
def drawB():
r=0
g=0
b=255
global x
global y
global blue
x=block*2
y=0
while b>=0 and blue==False:
pygame.draw.rect(screen,(r,g,b),(x,y,block,block))
print("blue",r,g,b)
b-=51
y+=block
if b<=0:
blue=True
def drawRedGreen():
r=255
g=255
b=0
global x
global y
global redgreen
x=block*3
y=0
while r>=0 and g>=0 and redgreen==False:
pygame.draw.rect(screen,(r,g,b),(x,y,block,block))
print("redgreen",r,g,b)
r-=51
y+=block
if y>=block*5:
y=0
x+=block
if r<=0:
r=255
g-=51
if g<=0:
redgreen=True
def drawRedBlue():
r=255
g=0
b=255
global x
global y
global redblue
x=block*8
y=0
while r>=0 and g>=0 and redblue==False:
pygame.draw.rect(screen,(r,g,b),(x,y,block,block))
print("redgreen",r,g,b)
r-=51
y+=block
if y>=block*5:
y=0
x+=block
if r<=0:
r=255
b-=51
if b<=0:
redblue=True
def drawGreenBlue():
r=0
g=255
b=255
global x
global y
global greenblue
x=block*13
y=0
while g>=0 and b>=0 and greenblue==False:
pygame.draw.rect(screen,(r,g,b),(x,y,block,block))
print("redgreen",r,g,b)
g-=51
y+=block
if y>=block*5:
y=0
x+=block
if g<=0:
g=255
b-=51
if b<=0:
greenblue=True
def main():
while True:
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
exit()
global rg
global rb
global gb
drawR()
drawG()
drawB()
drawRedGreen()
drawRedBlue()
drawGreenBlue()
pygame.display.update()
main() Next up is all the three-color values. I wasn't able to get that part work before, and also my program takes a second to display stuff. Hopefully it'll be easier this time now that I have 2-color functions that work better.
|