
-----------------------------------
jdubs
Thu Oct 09, 2008 12:54 pm

need increasing levels of difficulty and upgraded graphiks
-----------------------------------
Mod edit: plagiarized from Euphoracle's code. For shame.
%edited by jon wortner
setscreen ("graphics:600:600") 
setscreen ("offscreenonly") 




var playerscore,compscore:int

playerscore:=0
compscore:=0
const PADDLE_H := 100 
const PADDLE_W := 12 
const PADDLE_LEFT_X := 25 
const PADDLE_RIGHT_X := maxx - (25 + PADDLE_W) 
const PADDLE_VCAP := 100 
const PADDLE_STARTY := (maxy div 2) - (PADDLE_H div 2) 
const PADDLE_FRIC := 1 %rate at which velocity of paddle decreases when idle 
const PADDLE_V_STEP := 1 %rate at which velicity increases per stroke (the ai is dumb because this puts it in the hole) 
const PADDLE_COLOR := green 
var BALL_R := 10 %this is actually the diameter; i'm too lazy to rename it 
const BALL_HR := BALL_R div 2 
const BALL_V := 6 
const BALL_COLOR := blue 
const K_UP := chr (200) 
const K_DOWN := chr (208) 
const DUMB_AMOUNT := 7 %10=god, 1=fence post 
const FPS := 1000 div 60 %millisec/sec 

type BALL : 
    record 
        x, y : int 
        vx, vy : int 
    end record 

type PADDLE : %if i was supercool and making this correctly, i wouldn't exempt the x and vx.  4 player pong anyone? 
    record 
        y : int 
        vy : int 
    end record 

var ball : BALL 
var p_paddle : PADDLE 
var ai_paddle : PADDLE 
var startpos := 0 %0=player 1=ai 
var done := false 
var chars : array char of boolean 

fcn get_paddle_x (left : boolean) : int 
    if (left) then 
        result PADDLE_LEFT_X 
    else 
        result PADDLE_RIGHT_X 
    end if 
end get_paddle_x 



proc approach (var value : int, target, step : int) 
    var nv : int 
    if (value > target) then 
        nv := value - step 
        if (nv < target) then 
            value := target 
        else 
            value := nv 
        end if 
    elsif (value < target) then 
        nv := value + step 
        if (nv > target) then 
            value := target 
        else 
            value := nv 
        end if 
    end if 
end approach 

proc reset_ball 
    if (startpos = 0) then 
        ball.x := PADDLE_LEFT_X + PADDLE_W + BALL_HR + 1 
        ball.y := p_paddle.y + (PADDLE_H div 2) - BALL_R 
    else 
        ball.x := PADDLE_RIGHT_X - PADDLE_W - BALL_HR - 1 
        ball.y := ai_paddle.y + (PADDLE_H div 2) - BALL_R 
    end if 
    ball.vx := 0 
    ball.vy := 0 
end reset_ball 

proc reset_paddles 
    p_paddle.y := PADDLE_STARTY 
    p_paddle.vy := 0 
    ai_paddle.y := PADDLE_STARTY 
    ai_paddle.vy := 0 
end reset_paddles 

proc launch_ball 
    var q := Rand.Int (0, 1) 
    if (startpos = 0) then %so it doesn't instantly bounce back 
        ball.vx := BALL_V 
    else 
        ball.vx := -BALL_V 
    end if 
    if (q = 0) then 
        ball.vy := -BALL_V 
    else 
        ball.vy := BALL_V 
    end if 
end launch_ball 

proc newgame 
    reset_paddles 
    reset_ball 
    launch_ball 
end newgame 

proc win (left : boolean) 
    if (left) then %player 
        put "player wins" 
        startpos := 0 
    put "Player ones score"
        playerscore:=playerscore+1
    put playerscore    
     compscore:=compscore+0
    put "computers score ", compscore
    else %ai 
        put "ai wins" 
        startpos := 1 
    put "Computer ones score"
        compscore:=compscore+1
    put compscore
        playerscore:=playerscore+0
    put "players score ", playerscore  
    end if 
    
    put "play again? (y/n) " .. 
    View.Update 
    loop 
        var c : string (1) 
        getch (c) 
        if (c = "y") then 
            newgame 
            exit 
        elsif (c = "n") then 
            done := true 
            exit 
        end if 
    end loop 
end win 
fcn collide_with_paddle (var p : PADDLE, x, y : int, left : boolean) : boolean 
    %vertexes 
    var px := get_paddle_x (left)  
    var x1 := px 
    var x2 := px + PADDLE_W 
    var y1 := p.y 
    var y2 := p.y + PADDLE_H 

    if (x < x2 and x > x1 and y > y1 and y < y2 and left) then 
        result true 
    elsif (x > x1 and x < x2 and y > y1 and y < y2 and (not left)) then 
        result true 
    end if 
    result false 
end collide_with_paddle 
fcn collide_ball : boolean %true if game is done 
    var new_x := ball.vx + ball.x 
    var new_y := ball.vy + ball.y 
    var changed := 0 

    %top & bottom walls 
    if (new_y < 0 or new_y > maxy) then 
        ball.vy := -ball.vy 
        changed := 1 
    end if 

    %game loser 
    if (new_x < 0) then 
        win (false) 
        result true 
    elsif (new_x > maxx) then 
        win (true) 
        result true 
    end if 

    %paddles 
    if (collide_with_paddle (p_paddle, new_x, new_y, true)) then 
        ball.vx := -ball.vx 
    elsif (collide_with_paddle (ai_paddle, new_x, new_y, false)) then 
        ball.vx := -ball.vx 
    end if 

    result false 
end collide_ball 
proc move_ball 
    ball.x := ball.vx + ball.x 
    ball.y := ball.vy + ball.y 
end move_ball 
proc do_player 
    Input.KeyDown (chars) 

    if (chars (K_UP)) then 
        p_paddle.vy := min (p_paddle.vy + PADDLE_V_STEP, PADDLE_VCAP) 
    elsif (chars (K_DOWN)) then 
        p_paddle.vy := max (p_paddle.vy - PADDLE_V_STEP, -PADDLE_VCAP) 
    else 
        approach (p_paddle.vy, 0, PADDLE_FRIC) 
    end if 
    if (p_paddle.vy > 1) then 
        p_paddle.y := min (p_paddle.y + p_paddle.vy, maxy - PADDLE_H) 
        if (p_paddle.y = maxy - PADDLE_H) then 
            p_paddle.vy := 0 
        end if 
    else 
        p_paddle.y := max (p_paddle.y + p_paddle.vy, 0) 
        if (p_paddle.y = 0) then 
            p_paddle.vy := 0 
        end if 
    end if 
end do_player 
proc do_ai_think 
    if (ball.vx < 0) then %looks more realistic if it idles when player is moving 
        return 
    end if 
    var projected_y := ball.y + ball.vy 
    var current_path := ai_paddle.y + ai_paddle.vy + (PADDLE_H div 2) 

    if (projected_y > current_path) then 
        ai_paddle.vy := min (ai_paddle.vy + PADDLE_V_STEP, round ((PADDLE_VCAP / 2) / (DUMB_AMOUNT / 10))) %makes it look dumb 
    elsif (projected_y < current_path) then 
        ai_paddle.vy := max (ai_paddle.vy - PADDLE_V_STEP, round ((-PADDLE_VCAP / 2) / (DUMB_AMOUNT / 10))) %and lose occasionally 
    else 
        approach (ai_paddle.vy, 0, PADDLE_FRIC) 
    end if 

    if (ai_paddle.vy > 1) then 
        ai_paddle.y := min (ai_paddle.y + ai_paddle.vy, maxy - PADDLE_H) 
    else 
        ai_paddle.y := max (ai_paddle.y + ai_paddle.vy, 0) 
    end if 
end do_ai_think 



proc drawball 
    drawfilloval (ball.x, ball.y, BALL_HR, BALL_HR, BALL_COLOR) 
end drawball 
proc drawplayer 
    drawfillbox (PADDLE_LEFT_X, p_paddle.y, PADDLE_LEFT_X + PADDLE_W, p_paddle.y + PADDLE_H, PADDLE_COLOR+100) 
end drawplayer 
proc drawai 
    drawfillbox (PADDLE_RIGHT_X, ai_paddle.y, PADDLE_RIGHT_X+ PADDLE_W, ai_paddle.y+ PADDLE_H, PADDLE_COLOR) 
end drawai 
proc drawgui 
    %hahahahaha 
end drawgui 

%divide by zero lol 
if (DUMB_AMOUNT < 1 or DUMB_AMOUNT > 10) then 
    put "DUMB_AMOUNT = ", DUMB_AMOUNT, "\nWHY WOULD YOU DO THIS D: