import time import random from turtle import * writer = None halfway_triggered = False player_choice = None # ========================= # ODDS # ========================= def generateOdds(): base = [random.uniform(15, 17) for _ in range(6)] total = sum(base) scale = 100 / total final_odds = [round(x * scale, 2) for x in base] diff = 100 - sum(final_odds) final_odds[-1] += diff return final_odds # ========================= # TRACK # ========================= def drawTrack(): track = Turtle() track.hideturtle() track.speed(0) track.penup() num_racers = 6 lane_height = 40 start_x = -300 finish_x = 300 bottom_y = -20 top_y = bottom_y + num_racers * lane_height lane_colors = ["lightgray", "white"] for i in range(num_racers): track.goto(start_x, bottom_y + i * lane_height) track.color("black", lane_colors[i % 2]) track.begin_fill() track.pendown() for _ in range(2): track.forward(finish_x - start_x) track.left(90) track.forward(lane_height) track.left(90) track.end_fill() track.penup() track.goto(start_x, bottom_y) track.setheading(90) track.pensize(4) track.color("black") track.pendown() track.forward(top_y - bottom_y) track.penup() track.goto(start_x - 10, top_y + 10) track.write("START", align="right", font=("Arial", 12, "bold")) for i in range(num_racers + 1): y = bottom_y + i * lane_height track.goto(start_x, y) track.setheading(0) track.pendown() track.forward(finish_x - start_x) track.penup() flag = Turtle() flag.hideturtle() flag.speed(0) flag.penup() square = 10 rows = int((top_y - bottom_y) / square) screen = Screen() screen.tracer(0) for row in range(rows): for col in range(2): x = finish_x + col * square y = bottom_y + row * square flag.goto(x, y) flag.color("black", "black" if (row + col) % 2 == 0 else "white") flag.begin_fill() flag.pendown() for _ in range(4): flag.forward(square) flag.left(90) flag.end_fill() flag.penup() screen.update() screen.tracer(1) flag.goto(finish_x - 10, top_y + 10) flag.write("FINISH", align="right", font=("Arial", 12, "bold")) # ========================= # SETUP # ========================= def setup(): drawTrack() global racers racers = [] names = ["Tianli", "Jayden", "Fred", "Wujin", "Terry", "Brad"] colors = ["red", "blue", "green", "purple", "orange", "brown"] for i in range(6): t = Turtle() t.nickname = names[i] t.shape("turtle") t.color(colors[i]) t.penup() t.goto(-317, i * 40) t.write(t.nickname, align="right") t.goto(-300, i * 40) t.pendown() racers.append(t) def halfwayChallenge(): global player_choice # Generate question a = random.randint(10, 99) b = random.randint(2, 9) correct = a * b answer = textinput( "Math Challenge!", f"HALFWAY BONUS!\n\nWhat is {a} × {b}?" ) # Find player's racer chosen = None for r in racers: if r.nickname == player_choice: chosen = r break if chosen is None: return # Apply result if answer is not None and answer.isdigit() and int(answer) == correct: chosen.forward(50) else: chosen.backward(50) # ========================= # RACE # ========================= def race(): global winner, halfway_triggered winner = None while winner is None: for r in racers: r.forward(random.randint(10, 30)) # HALF WAY CHECK if r.xcor() >= 0 and not halfway_triggered: halfway_triggered = True halfwayChallenge() winner = checkWin() def checkWin(): for r in racers: if r.xcor() >= 300: return r return None # ========================= # DISPLAY # ========================= def displayResult(prediction): global writer writer = Turtle() writer.hideturtle() writer.penup() writer.goto(-175, 300) writer.color("blue") writer.write( f"Winner: {winner.nickname}", font=("Chalkboard", 26, "bold") ) writer.goto(-175, 250) if winner.nickname == prediction: writer.color("green") writer.write("You Win!", font=("Chalkboard", 26, "bold")) else: writer.color("red") writer.write("You Lose! Better luck next time!", font=("Chalkboard", 26, "bold")) # ====================== # PLAY AGAIN BUTTON # ====================== button = Turtle() button.hideturtle() button.penup() button.goto(-120, 180) button.color("black", "#1e90ff") button.pendown() button.begin_fill() for _ in range(2): button.forward(240) button.right(90) button.forward(60) button.right(90) button.end_fill() button.penup() button.goto(0, 140) button.color("white") button.write( "PLAY AGAIN", align="center", font=("Helvetica", 22, "bold") ) def clickPlayAgain(x, y): if -120 < x < 120 and 120 < y < 180: replayGame() Screen().onclick(clickPlayAgain) def displayRacers(prediction=None): global odds, writer if "odds" not in globals(): odds = generateOdds() if writer is None: writer = Turtle() writer.hideturtle() writer.penup() writer.clear() for i in range(6): label = f"{racers[i].nickname} | Odds: {odds[i]}%" if prediction == racers[i].nickname: label = "--> " + label writer.goto(-350, -200 + i * 30) writer.color("blue") writer.write(label, font=("Arial", 14, "normal")) def drawScoreboard(prediction=None): global odds if "odds" not in globals(): odds = generateOdds() board = Turtle() board.hideturtle() board.penup() board.speed(0) # ====================== # PANEL BACKGROUND (BOTTOM) # ====================== board.goto(-380, -30) board.color("white", "#111111") board.pendown() board.begin_fill() for _ in range(2): board.forward(760) board.right(90) board.forward(100) board.right(90) board.end_fill() board.penup() # ====================== # TITLE # ====================== board.goto(0, -60) board.color("#00ffff") board.write( "SCOREBOARD", align="center", font=("Helvetica", 18, "bold") ) # ====================== # RACERS + ODDS (HORIZONTAL) # ====================== start_x = -350 y = -90 for i in range(6): name = racers[i].nickname odd = odds[i] # Highlight prediction label = f"{name} {odd}%" if prediction == name: label = "▶ " + label board.color("#00ff7f") else: board.color("white") board.goto(start_x + i * 125, y) board.write(label, font=("Arial", 12, "bold")) # Odds bar board.goto(start_x + i * 125, y - 18) board.color("#444444") board.pendown() board.forward(90) board.penup() board.goto(start_x + i * 125, y - 18) board.color("#00bfff") board.pendown() board.forward(0.9 * odd) board.penup() def getPrediction(): return textinput("Prediction", "Which racer will win?") def countdown(): counter = Turtle() counter.hideturtle() counter.penup() for number in ["3", "2", "1", "GO!"]: counter.clear() counter.goto(0, 120) if number == "GO!": counter.color("lime") # green GO else: counter.color("red") # red numbers counter.write( number, align="center", font=("Helvetica", 48, "bold") ) time.sleep(1) counter.clear() # ========================= # MAIN GAME (UNCHANGED) # ========================= def main(): global player_choice setup() drawScoreboard() player_choice = getPrediction() prediction = player_choice drawScoreboard(prediction) countdown() race() displayResult(prediction) def replayGame(): global racers, writer, odds, winner, halfway_triggered, player_choice halfway_triggered = False player_choice = None Screen().clear() racers = [] writer = None odds = generateOdds() winner = None setup() drawScoreboard() player_choice = getPrediction() prediction = player_choice drawScoreboard(prediction) countdown() race() displayResult(prediction) # ========================= # INSTRUCTION SCREEN # ========================= def instructionScreen(): screen = Screen() screen.clear() screen.bgcolor("#1e1e1e") pen = Turtle() pen.hideturtle() pen.penup() pen.color("white") # ====================== # TITLE # ====================== pen.goto(0, 200) pen.write( "TURTLE RACE", align="center", font=("Helvetica", 36, "bold") ) pen.goto(0, 165) pen.color("lightgray") pen.write( "Bet • Predict • Race", align="center", font=("Helvetica", 16, "normal") ) # ====================== # INSTRUCTION BOX # ====================== box = Turtle() box.hideturtle() box.penup() box.goto(-260, 150) box.color("white", "#2a2a2a") box.pendown() box.begin_fill() for _ in range(2): box.forward(520) box.right(90) box.forward(250) box.right(90) box.end_fill() box.penup() pen.color("white") pen.goto(0, -70) pen.write( "HOW TO PLAY\n\n" "• Check each turtle's odds\n" "• Type the name of the turtle you think will win\n" "• Click START to begin the race\n" "• When a turtle reaches halfway, solve a math question!\n" " - Correct answer gives your turtle +50 spaces\n" " - Wrong answer sets your turtle back 50 spaces\n" "• First turtle to cross the line wins\n\n" "Good luck 🐢", align="center", font=("Arial", 16, "normal") ) # ====================== # START BUTTON # ====================== button = Turtle() button.hideturtle() button.penup() def draw_start_button(): button.goto(-120, -110) button.color("black", "#3cb371") # professional green button.pendown() button.begin_fill() for _ in range(2): button.forward(240) button.right(90) button.forward(80) button.right(90) button.end_fill() button.penup() button.goto(0, -165) button.color("white") button.write( "START", align="center", font=("Helvetica", 28, "bold") ) draw_start_button() # ====================== # CLICK DETECTION # ====================== def startGame(x, y): if -120 < x < 120 and -220 < y < -140: screen.clear() main() screen.onclick(startGame) def resetGame(): global racers, writer, odds, winner racers = [] writer = None odds = None winner = None screen = Screen() screen.clear() instructionScreen() # ========================= # START PROGRAM # ========================= instructionScreen() done()