How to choose a random color for each ball that will show up every time?

Question:

This is a simple python "flappy bird" game. I am struggling with choosing a random color for each ball that will show up every time — how can I do it?

from random import *
from turtle import *
from freegames import vector

bird = vector(0,0)
balls=[]

def tap (x, y):
    """Move bird up in response to screen tap"""
    up=vector(0,30)
    bird.move(up)
def inside(point):
     """Return true if point on screen """
     return -200 < point.x< 200 and -200 < point.y < 200

def draw(alive):
    """Draw screen objects."""
    clear()

    goto(bird.x, bird.y)
    if alive:
      dot(10,'green')
    else:
      dot(10,'red')

    for ball in balls:
      goto(ball.x, ball.y)
      dot(20,'black')

    update()

def move():
        """Update object positions."""
        bird.y -= 5

    for ball in balls:
      ball.x -= 3

    if randrange(10)==0:
      y=randrange(-199,199)
      ball=vector(199,y)
      balls.append(ball)

    while len(balls) >0 and not inside(balls[0]):
      balls.pop(0)

    draw (True)
    ontimer (move,50)

    if not inside(bird):
      draw(False)
      return

    for ball in balls:
      if abs(ball-bird)< 15:
      draw(False)
      return


setup(420,420,370,0)
hideturtle()
up()
tracer(False)
onscreenclick(tap)
move()
done()
Asked By: StarXfire

||

Answers:

According to the turtle docs dot will accept either a colorstring or an rgb value. To supply an rgb value to dot you must use the syntax dot(size, r, g, b) to specify the color. To generate a random color with random to fill these values we should create a function.

# Create a random color tuple
import random
import turtle
turtle.colormode(255)
def randomColor():
    return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))

# Now we can use this with dot like so
# Note we are using * to unpack the random color for dot()
turtle.dot(10, *randomColor())
Answered By: Alec Soronow

There are at least three ways you can generate random color values in Python turtle:

>>> import turtle
>>> from random import random
>>> turtle.colormode()  # confirm the default
>>> 1.0
>>> turtle.dot(20, (random(), random(), random()))

Another way, as @Alec Soronow points out is to change the default color mode and work with integer color values:

>>> from random import randint
>>> turtle.colormode(255)
>>> turtle.dot(20, (randint(0, 255), randint(0, 255), randint(0, 255)))

Since dot() can also accept hex color strings, e.g. '#a5b8af', we can also do:

>>> hex_color = '#' + hex(randint(0, 256**3 - 1)).replace('0x', '').zfill(6)
>>> turtle.dot(20, hex_color)

That gets your random color, but doesn’t solve your problem of having the ball remember its color. You could approach this by storing in balls tuples of the vector and color, and then when you acces it, you do something like:

for ball, color in balls:
    # whatever

but I’m going to suggest a different approach, which is to make your bird and balls all be turtles instead of vectors. Something like:

from random import random, randrange
from turtle import Screen, Turtle

def tap(x, y):
    """ Move bird up in response to screen tap """

    bird.forward(30)

def inside(entity):
    """ Return true if point on screen """

    x, y = entity.position()

    return -200 < x < 200 and -200 < y < 200

balls = []
spare_balls = []

def move():
    """ Update object positions """

    global balls

    if inside(bird):
        for ball in balls:
            if ball.distance(bird) < 15:
                bird.color('red')
                screen.update()
                return
    else:
        bird.color('red')
        screen.update()
        return

    bird.backward(5)

    for ball in balls:
        ball.forward(3)

    inside_balls = []

    for ball in balls:
        if inside(ball):
            inside_balls.append(ball)
        else:
            ball.hideturtle()
            spare_balls.append(ball)

    balls = inside_balls

    if randrange(10) == 0:
        if spare_balls:
            ball = spare_balls.pop()
        else:
            ball = Turtle(shape='circle', visible=False)
            ball.penup()
            ball.setheading(180)

        ball.setposition(199, randrange(-199, 199))
        ball.color(random(), random(), random())
        balls.append(ball)
        ball.showturtle()

    screen.update()
    screen.ontimer(move, 50)

screen = Screen()
screen.setup(420, 420, 370, 0)
screen.tracer(False)

bird = Turtle()
bird.shape('turtle')
bird.color('green')
bird.penup()
bird.setheading(90)

screen.onclick(tap)

move()

screen.mainloop()
Answered By: cdlane