JustPaste
HomeCategoriesAboutDonateContactTerms of UsePrivacy Policy
JustPaste

Free online notepad — write and share instantly

Navigate

  • Home
  • Timeline
  • Categories

Info

  • About
  • Donate
  • Contact

Legal

  • Terms of Use
  • Privacy Policy

© 2026 JustPaste.app. All rights reserved.

Made with ♥ by JustPaste

Project thingy | JustPaste.app
about 1 month ago9 views
👨‍💻Programming

Project thingy

# Final Project: The Skill Test

# INITIALISE
import pygame
import os
import random
os.environ["SDL_AUDIODRIVER"] = "dsp"
pygame.init()

# Generate window
WINDOW_WIDTH = 600
WINDOW_HEIGHT = 400
window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("The Skill Test")

# Initialise screen
screen = 0

# Colours
BLACK = (0, 0, 0)
PINK = (255, 0, 255)
PURPLE = (150, 0, 150)
BLUE = (0, 0, 255)
CYAN = (0, 255, 255)
GREEN = (0, 200, 0)
YELLOW = (255, 255, 0)
ORANGE = (255, 128, 0)
RED = (200, 0, 0)
WHITE = (255, 255, 255)
GREY = (128, 128, 128)
# Fonts
font = pygame.font.SysFont(None, 36)
gamefont = pygame.font.SysFont(None, 20)
bigfont = pygame.font.SysFont(None, 72)

# Initialise grade system
grades = [0, 0, 0, 0, 0]
grade_names = ["Rubbish", "F", "E", "D", "C", "B", "A", "S", "!"]
grade_colours = [WHITE, RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, PURPLE, PINK]
currentgrade = 9

# Initialise games and variables (prevents 'not defined' errors)
# Typing system
letters = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
typedtext = ""
text = ""
# Grade thresholds
thresholds2 = [-1.0, 30.0, 60.0, 80.0, 100.0, 120.0, 135.0, 150.0, 160.0]
thresholds3 = [0, 150, 300, 450, 600, 750, 900, 950, 990]
thresholds4 = [0, 12, 18, 24, 30, 35, 40, 50, 64]
thresholds5 = [3.00, 0.50, 0.40, 0.32, 0.28, 0.24, 0.20, 0.16, 0.12]
# Game 1
score1 = 0
# Game 2
time2 = 180.0
# Game 3
score3 = 0
skips3 = 2
playerX = 1
playerY = 1
redsquares = []
greensquares = []
# Game 4
score4 = 0
time4 = 0.0
num1 = 1
num2 = 1
answer = 2
# Game 5
framesToGreen = 40
framesWaited = 0
clickable = 0
time5 = 0.00
exitDelay = 0
clicked = 0
# Average grade
averageGrade = 1

# Initialise clock
clock = pygame.time.Clock()
FPS = 60
gametick = 0
obstick = 0

# DEFINITIONS
def createRedSquares(): # Generate red squares (game 3)
    for index in range(300):
        xPos = random.randint(20, 1600) // 2
        yPos = random.randint(1, 4)
        redsquares.append([xPos, yPos])
def createGreenSquares(): # Generate green squares (game 3)
    for index in range(40):
        xPos = random.randint(20, 1600) // 2
        yPos = random.randint(1, 4)
        if [xPos, yPos] in redsquares: # Prevents overlap between green and red squares
            while [xPos, yPos] in redsquares:
                xPos = random.randint(20, 1600) // 2
                yPos = random.randint(1, 4)
        greensquares.append([xPos, yPos])
def generateNewQuestion(): # Generates a new question (game 4)
    global num1, num2, answer, typedtext, operator
    typedtext = ""
    operator = random.randint(1, 4)
    # Generate addition question
    if operator == 1:
        num1 = int(round(random.uniform(1, 1.2**(score4+4)), 0))
        num2 = int(round(random.uniform(1, 1.2**(score4+4)), 0))
        answer = num1 + num2
    # Generate subtraction question
    if operator == 2:
        num1 = int(round(random.uniform(1, 1.2**(score4+4)), 0))
        num2 = int(round(random.uniform(1, 1.2**(score4+4)), 0))
        answer = num1 - num2
    # Generate multiplication question
    if operator == 3:
        num1 = int(round(random.uniform(1, 1.1**(score4+4)), 0))
        num2 = int(round(random.uniform(1, 1.1**(score4+4)), 0))
        answer = num1 * num2
    # Generate division question
    if operator == 4:
        num1 = int(round(random.uniform(1, 1.1**(score4+4)), 0))
        num2 = int(round(random.uniform(1, 1.1**(score4+4)), 0))
        answer = num1 * num2

# GAME LOOP
running = True
while running:
    # Events
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        # CONTROLS
        # Typing (game 2)
        if screen == 2:
            if event.type == pygame.KEYDOWN and time2 <= 179.9 and (not event.key == pygame.K_BACKSPACE) and (not (len(typedtext)==50 and event.key == pygame.K_SPACE)):
                typedtext += event.unicode
                typedtext = typedtext.upper()
                # Check for mistake
                if len(typedtext) > 0 and screen == 2:
                    if not typedtext[len(typedtext)-1] == text[len(typedtext)-1]:
                        time2 += -3.0
                        time2 = round(time2, 1)
                        typedtext = typedtext[:len(typedtext)-1]

        # Player Controls (screen 3)
        if screen == 3:
            if event.type == pygame.KEYDOWN:
                # Movement up and down
                if event.key == pygame.K_UP:
                    if playerY < 4:
                            playerY += 1
                if event.key == pygame.K_DOWN:
                    if playerY > 1:
                            playerY += -1
                # Green square click
                if event.key == pygame.K_SPACE:
                    if spacebarPressedThisTick == 0:
                        spacebarPressedThisTick = 1
                        greenSquareFound = 0
                        for index in range(40):
                            if greensquares[index][0]-1 == playerX and greensquares[index][1] == playerY:
                                score3 += 10 # Reward for clicking space on a green square
                                greenSquareFound = 1 # Prevents penalty
                        if greenSquareFound == 0:
                            score3 += -15 # Penalty for clicking space when not on a green square
                # Use skip
                if event.key == pygame.K_RIGHT:
                    if skips3 > 0:
                        skips3 += -1
                        playerX += 5
                        
        # Typing (game 4)
        if screen == 4:
            if event.type == pygame.KEYDOWN and event.key == pygame.K_BACKSPACE: # Allows backspaces
                if len(typedtext) > 0:
                    typedtext = typedtext[:len(typedtext)-1]
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_MINUS:
                if len(typedtext) == 0:
                    typedtext += "-"
            elif event.type == pygame.KEYDOWN and event.unicode.isdigit(): # Prevents operators being entered for cheating
                typedtext += event.unicode
                typedtext = typedtext.upper()
            # Answer submission (game 4)
            if event.type == pygame.KEYDOWN and event.key == pygame.K_RETURN:
                # Addition
                if operator == 1:
                    if typedtext == str(answer):
                        score4 += 1
                        time4 += 10.0
                        time4 = round(time4, 1)
                        generateNewQuestion()
                    else:
                        time4 += -10.0
                        time4 = round(time4, 1)
                        generateNewQuestion()
                # Subtraction
                elif operator == 2:
                    if typedtext == str(answer):
                        score4 += 1
                        time4 += 10.0
                        time4 = round(time4, 1)
                        generateNewQuestion()
                    else:
                        time4 += -10.0
                        time4 = round(time4, 1)
                        generateNewQuestion()
                # Multiplication
                elif operator == 3:
                    if typedtext == str(answer):
                        score4 += 1
                        time4 += 10.0
                        time4 = round(time4, 1)
                        generateNewQuestion()
                    else:
                        time4 += -10.0
                        time4 = round(time4, 1)
                        generateNewQuestion()
                # Division
                elif operator == 4:
                    if typedtext == str(num1):
                        score4 += 1
                        time4 += 10.0
                        time4 = round(time4, 1)
                        generateNewQuestion()
                    else:
                        time4 += -10.0
                        time4 = round(time4, 1)
                        generateNewQuestion()

        # Clicking (game 5)
        if screen == 5:
            if event.type == pygame.KEYDOWN:
                if clickable == 1:
                    # Calculate grade after clicked
                    for index in range(9):
                        if time5 > 0.12:
                            if time5 > thresholds5[index]:
                                currentgrade = index
                                break
                        else:
                            currentgrade = 9
                    clicked = 1
                else:
                    screen = 0

        # Exit (end of test)
        if screen == 0:
            if event.type == pygame.KEYDOWN and event.key == pygame.K_0:
                if 0 not in grades and averageGrade >= 5: # Exit only allowed with a C grade or above
                    exit()

        # OPEN GAMES
        # Game Selection (screen 0)
        if event.type == pygame.KEYDOWN and screen == 0:
            # Open game 1
            if event.key == pygame.K_1:
                screen = 1
                time = 600
                score1 = 50000
                cubeY = 190
            # Open game 2
            elif event.key == pygame.K_2:
                screen = 2
                time2 = 180.0
                chars = []
                text = ""
                typedtext = ""
                # Create text string
                for index in range(100):
                    # Add letters
                    if index == 0 or index == 99 or index == 49 or index == 50 or chars[index-1] == " ": # Prevent space for first char, last char, between lines and after a space
                        letterselect = random.randint(1, 26)
                        chars.append(letters[letterselect-1])
                        text = " ".join([text + chars[index]])
                    else:
                        spacerand = random.randint(1, 7) # 1 in 7 chance for space
                        lastTen = text[len(text)-10:] # Guarantee space at least once every 10 letters
                        if spacerand == 6 or not " " in lastTen :
                            letterselect = " "
                            chars.append(" ")
                            text = " ".join([text + chars[index]])
                        else:
                            letterselect = random.randint(1, 26)
                            chars.append(letters[letterselect-1])
                            text = " ".join([text + chars[index]])
            # Open game 3
            if event.key == pygame.K_3:
                screen = 3
                score3 = 0
                playerX = 1
                playerY = 1
                redsquares = []
                greensquares = []
                skips3 = 2
                createRedSquares()
                createGreenSquares()
            # Open game 4
            elif event.key == pygame.K_4:
                screen = 4
                score4 = 0
                time4 = 10.0
                operator = 1
                num1 = 1
                num2 = 1
                answer = 1+1
                typedtext = ""
            # Open game 5
            elif event.key == pygame.K_5:
                screen = 5
                time5 = 0.00
                framesToGreen = random.randint(60, 360)
                framesWaited = 0
                clickable = 0
                exitDelay = 0
                clicked = 0
            else:
                pass
            
    # Key Detection
    keys = pygame.key.get_pressed()
    
    # TEXT RENDERING
    # Initialise corner grade render (screens 1-5)
    if screen > 0:
        if screen == 5: # Render grade only after button clicked on game 5
            if exitDelay > 0:
                gradeln = font.render(grade_names[currentgrade-1], True, grade_colours[currentgrade-1])
            else:
                gradeln = font.render("", True, WHITE)
        else:
            gradeln = font.render(grade_names[currentgrade-1], True, grade_colours[currentgrade-1]) # Show grades throughout game on games 1-4
    else:
        gradeln = font.render("", True, WHITE) # Not shown on main menu
        
    # Average grade render (screen 0)
    if screen == 0: # Only shows on main menu
        if 0 not in grades: # Only shows after all games completed
            averageln1 = gamefont.render("AVERAGE:", True, WHITE)
            averageln2 = bigfont.render(grade_names[averageGrade-1], True, grade_colours[averageGrade-1])
            # Player passes if their average grade is C or above
            if averageGrade >= 5:
                averageln3 = gamefont.render("YOU PASS: Replay the games using keys 1-5 or press 0 to exit The Skill Test", True, WHITE)
            else:
                averageln3 = gamefont.render("YOU FAIL: You need a C or above to complete the game. Replay the games using keys 1-5", True, WHITE)
        else:
            averageln1 = gamefont.render("", True, WHITE)
            averageln2 = bigfont.render("", True, WHITE)
            averageln3 = gamefont.render("", True, WHITE)
    else:
        averageln1 = gamefont.render("", True, WHITE)
        averageln2 = bigfont.render("", True, WHITE)
        averageln3 = gamefont.render("", True, WHITE)
    
    # TEXT
    # Screen 0 (Main Menu) Text
    if screen == 0:
        # Games List
        gameln = font.render("The Skill Test | Press a number key to play", True, WHITE)
        line1 = font.render("1 - Float", True, WHITE)
        line2 = font.render("2 - Typewriter", True, WHITE)
        line3 = font.render("3 - Obstacle Course", True, WHITE)
        line4 = font.render("4 - Examination", True, WHITE)
        line5 = font.render("5 - Reaction", True, WHITE)
        creditln = font.render("BOYLE, Kainos Entry | Aug 2026", True, WHITE)
        
    # Screen 1 (Float) Text
    elif screen == 1:
        gameln = font.render("Float | Press SPACE to float up", True, WHITE)
        line1 = font.render("Stay as close to the green line as you can", True, WHITE)
        line2 = font.render("You lose points faster the further you are from the", True, WHITE)
        line3 = font.render("line", True, WHITE)
        line4 = font.render("", True, WHITE)
        line5 = font.render("", True, WHITE)
        creditln = font.render(f"Score: {score1}", True, WHITE)
        
    # Screen 2 (Typewriter) Text
    elif screen == 2:
        gameln = font.render("Typewriter | Type the gibberish below in 3 minutes", True, WHITE)
        line1 = font.render("Each typo costs 3 seconds", True, WHITE)
        line2 = font.render("", True, WHITE)
        line3 = font.render("", True, WHITE)
        line4 = font.render("", True, WHITE)
        line5 = font.render("", True, WHITE)
        creditln = font.render(f"Time: {time2}", True, WHITE)
        lettersln1 = gamefont.render(text[:50], True, WHITE)
        lettersln2 = gamefont.render(text[50:], True, WHITE)
        typedln1 = gamefont.render(typedtext[:50], True, GREEN)
        if len(typedtext) > 50:
            typedln2 = gamefont.render(typedtext[50:], True, GREEN)
        else:
            typedln2 = gamefont.render("", True, GREEN)
            
    # Screen 3 (Obstacle Course) Text
    elif screen == 3:
        gameln = font.render("Obstacle Course | Use UP and DOWN to move", True, WHITE)
        line1 = font.render("Press SPACE when on green squares, avoid red", True, WHITE)
        line2 = font.render("Clicking space at the wrong time costs points", True, WHITE)
        line3 = font.render("Press RIGHT to skip forward", True, WHITE)
        line4 = font.render("", True, WHITE)
        line5 = font.render("", True, WHITE)
        creditln = font.render(f"Score: {score3} | Skips: {skips3}", True, WHITE)
    
    # Screen 4 (Examination) Text
    elif screen == 4:
        gameln = font.render("Examination | Get the questions right", True, WHITE)
        line1 = font.render("Correct answers give 10 seconds", True, WHITE)
        line2 = font.render("Wrong answers take away 10 seconds", True, WHITE)
        line3 = font.render("Press RETURN to submit your answer", True, WHITE)
        line4 = font.render("", True, WHITE)
        line5 = font.render("", True, WHITE)
        creditln = font.render(f"Score: {score4} | Time: {time4}", True, WHITE)
        lettersln1 = gamefont.render(text[:50], True, WHITE)
        lettersln2 = gamefont.render(text[50:], True, WHITE)
        typedln1 = gamefont.render(typedtext[:50], True, GREEN)
        if len(typedtext) > 50:
            typedln2 = gamefont.render(typedtext[50:], True, GREEN)
        else:
            typedln2 = gamefont.render("", True, GREEN)

    elif screen == 5:
        gameln = font.render("Reaction | Press ANY KEY when green", True, WHITE)
        line1 = font.render("Don't press too early", True, WHITE)
        line2 = font.render("", True, WHITE)
        line3 = font.render("", True, WHITE)
        line4 = font.render("", True, WHITE)
        line5 = font.render("", True, WHITE)
        creditln = font.render(f"Time: {round(time5, 2)}", True, WHITE)


    # GAME RENDERING
    # Black Window
    window.fill(BLACK)
    
    # Render text lines
    window.blit(gameln, (10, 10))
    window.blit(line1, (10, 40))
    window.blit(line2, (10, 70))
    window.blit(line3, (10, 100))
    window.blit(line4, (10, 130))
    window.blit(line5, (10, 160))
    window.blit(creditln, (10, 360))
    
    # Render average grade
    window.blit(averageln1, (10, 230))
    window.blit(averageln2, (10, 250))
    window.blit(averageln3, (10, 300))
    
    # Render grades (screen 0)
    if screen == 0:
        for index in range(5):
            if grades[index] > 0:
                grade_text = grade_names[grades[index]-1]
                window.blit(font.render(grade_text, True, grade_colours[grades[index]-1]), (300, 40+(30*(index))))
            else:
                window.blit(font.render("x", True, GREY), (300, 40+(30*(index))))

    # Render current grade (screens 1-5)
    else:
        window.blit(gradeln, (480, 360))

    # GAME RUNNING
    # Screen 1 (Float)
    if screen == 1:
        # Green line
        pygame.draw.rect(window, GREEN, (0, 190, 600, 20))
        # Moving block
        pygame.draw.rect(window, WHITE, (600-time, cubeY, 20, 20))
        if gametick == 6:
            time += -1
        if time < 594 and time > 0:
            if keys[pygame.K_SPACE]:
                if cubeY >= 140:
                    cubeY += -1
            else:
                if cubeY <= 240:
                    cubeY += 1
        if cubeY > 190:
            score1 += -(cubeY - 190)
        if cubeY < 190:
            score1 += (cubeY - 190)
        if time < 0:
            cubeY = 190
        if time < -20 or score1 < 1:
            if time < 0 and currentgrade > grades[0]:
                grades[0] = currentgrade
            screen = 0
        # Grade
        if score1 >= 20000:
            currentgrade = (score1 // 4000) - 3
        else:
            currentgrade = 1
    # Screen 2 (Typewriter)
    if screen == 2:
        window.blit(lettersln1, (10, 130))
        window.blit(lettersln2, (10, 160))
        window.blit(typedln1, (10, 230))
        window.blit(typedln2, (10, 260))
        # Timer
        if gametick == 6:
            time2 += -0.1
            time2 = round(time2, 1)
        # Grade
        for index in range(9):
            if time2 < 155.0:
                if time2 < thresholds2[index]:
                    currentgrade = index
                    break
            else:
                currentgrade = 9
        if time2 < 0.0 or len(typedtext) == 100:
            if len(typedtext) == 100 and currentgrade > grades[1]:
                grades[1] = currentgrade
            screen = 0
    # Screen 3 (Obstacle Course)
    # Course Area
    if screen == 3:
        pygame.draw.rect(window, BLUE, (0, 160, 600, 80))
        # Player
        pygame.draw.rect(window, WHITE, (20, 240-(20*playerY), 20, 20))
        # Screen Scroll
        if obstick == 0:
            playerX += 1
        # Red Squares
        for index in range(150):
            pygame.draw.rect(window, RED, (((redsquares[index][0]-playerX)*(20)), (240-(redsquares[index][1]*20)), 20, 20))
        # Green Squares
        for index in range(40):
            pygame.draw.rect(window, GREEN, (((greensquares[index][0]-playerX)*(20)), (240-(greensquares[index][1]*20)), 20, 20))
        # Check if red squares hit
        for index in range(150):
            if redsquares[index][0]-1 == playerX and redsquares[index][1] == playerY:
                if currentgrade > grades[2]:
                    grades[2] = currentgrade
                screen = 0
        # Check if red squares passed
        if obstick == 0:
            for index in range(150):
                if redsquares[index][0] == playerX:
                    score3 += 4
        # Check if course completed
        if playerX > 810:
            if currentgrade > grades[2]:
                grades[2] = currentgrade
            screen = 0
        # Grade
        for index in range(9):
            if score3 < 990:
                if score3 < thresholds3[index]:
                    currentgrade = index
                    break
            else:
                currentgrade = 9
        # Prevent negative score
        if score3 < 0:
            score3 = 0
    # Screen 4 (Examination)
    if screen == 4:
        # Question Render
        window.blit(lettersln1, (10, 130))
        window.blit(lettersln2, (10, 160))
        window.blit(typedln1, (10, 230))
        window.blit(typedln2, (10, 260))
        if operator == 1:
            text = f"{num1} + {num2}"
        if operator == 2:
            text = f"{num1} - {num2}"
        if operator == 3:
            text = f"{num1} x {num2}"
        if operator == 4:
            text = f"{answer} / {num2}"
        # Timer
        if gametick == 6:
            time4 += -0.1
            time4 = round(time4, 1)
        # Grade
        for index in range(9):
            if score4 < 100:
                if score4 < thresholds4[index]:
                    currentgrade = index
                    break
            else:
                currentgrade = 9
        # End game
        if time4 < 0:
            if score4 > 0:
                if currentgrade > grades[3]:
                    grades[3] = currentgrade
                screen = 0
            else:
                screen = 0
    # Screen 5 (Reaction)
    # Check if button should be green
    if screen == 5:
        if clickable == 1:
            if exitDelay == 0:
                time5 += 1/60
        else:
            framesWaited += 1
            if framesWaited > framesToGreen:
                clickable = 1
        # Render button
        if clickable == 0:
            pygame.draw.rect(window, RED, (250, 150, 100, 100))
        else:
            pygame.draw.rect(window, GREEN, (250, 150, 100, 100))
        # Count down to exit after clicked
        if clicked == 1:
            exitDelay += 1
        # Exit game if you take too long
        if time5 > 3.0:
            if 0 == grades[4]:
                grades[4] = 0
            screen = 0
        # Exit game after clicked
        if exitDelay > 60:
            if currentgrade > grades[4]:
                grades[4] = currentgrade
            screen = 0
    
    # Average grade calculation (screen 0)
    averageGrade = int(round(sum(grades) / 5, 0))

    # TICKS
    # Clock tick
    clock.tick(FPS)
    
    # Game tick (0.1 seconds)
    if gametick == 6:
        gametick = 0
    else:
        gametick += 1
        
    # Obstacle Course tick (screen 3)
    if obstick > 20-19*((playerX-1)/1149): # Ticks are faster as game continues
        obstick = 0
        spacebarPressedThisTick = 0 # Allows spacebar to be pressed again
    else:
        obstick += 1
    
    pygame.display.update()
pygame.quit()
← Back to timeline