from microbit import *
from random import *

# Moves the paddle up when button A is pressed
def on_button_pressed_a():
    global paddlePosition
    led.unplot(4, paddlePosition)  # Clear the current paddle position
    paddlePosition += 1
    if paddlePosition == 5:  # Wrap around to the top
        paddlePosition = 0
input.on_button_pressed(Button.A, on_button_pressed_a)

# Moves the paddle down when button B is pressed
def on_button_pressed_b():
    global paddlePosition
    led.unplot(4, paddlePosition)  # Clear the current paddle position
    paddlePosition += -1
    if paddlePosition == -1:  # Wrap around to the bottom
        paddlePosition = 4
input.on_button_pressed(Button.B, on_button_pressed_b)

# Temporarily decreases the ball speed when the microbit is shaken
def on_gesture_shake():
    global saveSpeed, ballSpeed
    saveSpeed = ballSpeed  # Save the current speed
    ballSpeed = ballSpeed * 3  # Make the ball 3x slower
    basic.pause(3000)  # Keep the decreased speed for 3 seconds
    ballSpeed = saveSpeed  # Restore the original speed
    basic.pause(5000)  # Wait for 5 seconds before allowing another slow
input.on_gesture(Gesture.SHAKE, on_gesture_shake)

# Handles received radio values and updates game variables accordingly
def on_received_value(name, value):
    global velocityX, velocityY, ballY, ballX, ballSpeed, switchDirection, gameState
    if name.compare("vx") == 0:
        velocityX = value
    if name.compare("vy") == 0:
        velocityY = value
    if name.compare("y") == 0:
        ballY = value
        ballX = -1  # Reset ball position
        ballSpeed += -60  # Speeds up the game
    if name.compare("sD") == 0:
        switchDirection = value
    if name.compare("speed") == 0:
        ballSpeed = 530  # Reset to default speed
    if name.compare("loss") == 0:
        gameState = value  # Update game state
radio.on_received_value(on_received_value)

# Changes the ball direction when the logo is touched
def on_logo_touched():
    global velocityX, switchDirection
    if switchDirection == 1 and (ballX > 0 and ballX < 4):
        velocityX = velocityX * -1  # Reverse the X direction
        switchDirection = 0  # Power up is one use only
input.on_logo_event(TouchButtonEvent.TOUCHED, on_logo_touched)

# Initialize game variables
saveSpeed = 0
ballSpeed = 530  # Default ball speed
paddlePosition = 2  # Initial paddle position
ballX = -999
ballY = 999  # Ball off screen initially
velocityX = 0
velocityY = 0  # Ball does not move initially on right microbit
switchDirection = 1  # Indicates one use of switch power up
gameState = 0  # Initial game state

# Set up the radio group
radio.set_group(1)

# Game loop: manage paddle and game state
def on_forever():
    global paddlePosition
    radio.send_value("pause", pins.digital_read_pin(DigitalPin.P0))
    if ballX > 5:  # Ball is out of bounds, loss
        paddlePosition = 999  # Hide the paddle
        basic.show_leds("""
            . # . . .
            . # . . .
            . # . . .
            . # . . .
            . # # # .
        """)
        radio.send_value("loss", 1)  # Indicate a loss
    elif gameState == 1:  # Win state
        paddlePosition = 999
        basic.show_leds("""
            # . . . #
            # . . . #
            # . # . #
            # # . # #
            # . . . #
        """)
    led.plot(4, paddlePosition)  # Display the paddle
    radio.set_group(1)  # Ensure the correct radio group is active
basic.forever(on_forever)

# Game loop: manage ball movement and collisions
def on_forever2():
    global velocityX, ballX, velocityY, ballY
    basic.pause(ballSpeed)
    if not (ballX > 0 and ballX < 4 and pins.digital_read_pin(DigitalPin.P0) == 1):
        led.unplot(ballX, ballY)  # Clear the current ball position
        if ballX == 4 and paddlePosition == ballY:  # Ball hits the paddle
            velocityX = velocityX * -1  # Reverse X direction
        ballX += velocityX  # Update ball X position
        if ballX != -1:
            if ballY == 4 or ballY == 0:  # Ball hits top or bottom wall
                velocityY = velocityY * -1  # Reverse Y velocity
            ballY += velocityY  # Update ball Y position
            led.plot(ballX, ballY)  # Display the ball
        else:  # Ball is going to other microbit
            radio.send_value("vx", velocityX)  # Send X velocity
            radio.send_value("vy", velocityY)  # Send Y velocity
            radio.send_value("y", ballY)  # Send Y position
basic.forever(on_forever2)