UnderwareDESIGN

General => Competitions => CleverCoders => Topic started by: kevin on November 12, 2008, 08:41:27 PM

Title: Challenge #15 - Table Tennis / Pong AI
Post by: kevin on November 12, 2008, 08:41:27 PM

(http://www.underwaredesign.com/PlayBasicSig.png) (http://www.playbasic.com)


Challenge #15 - Table Tennis / Pong  AI


    When learning to write Video Games,  it's commonly suggested that new programmers have a go a creating their version of classic retro games such as Pong / Tennis style game initially.  The theory being, that even though this is a retro challenge,  in order to build our own version of Pong, our program will need to cover many of the initial problems facing game programmers.    Such as, display principals (drawing the screen),  controls (getting input from the player), collisions  and computer controls characters,   Other wise known as  AI.   To be honest,  not too many retro games have 'smart' characters.  There are some exceptions to this of course, but generally speaking most old games have very simplistic AI algorithms. 

 
    In this challenge, your goal is to create your own Table Tennis/Pong styled game where the human controlled player hits the ball with the computer controlled player.  The player should control the bat (keys, joypad or mouse), with the aim of keeping the ball in play.  The ball is considered out of play, once it passed the players bat and leaves the screen/play area (behind the bat)    The visuals/physics are not important,  the challenge here is that you'll need to create the logic for the computer controlled player.



Reference Materials

  2 Player Pong (http://www.underwaredesign.com/forums/index.php?topic=2768.0)


Submission

* Submissions can be written in any version of PlayBasic (http://www.playbasic.com)

* Submission can only be accepted in Source Code form only.

* Authors can use external Media (images/music) provided you created the media/and or have permission to distribute the includes media or the Media is in the public domain.

* Zip up your Submissions and please try to keep it smaller than 500K !

* Authors automatically give consent for their submission(s) to distributed and used for promotional purposes via UnderwareDesign.com, PlayBasic code tank.

* Authors can submit as many times as they like.

* To make a submission, zip up your projects source code + media and either post it in this thread, or create your own thread in either the Source Codes or Show Case forums and post a link bellow.



Dead Line

Anytime before the next ice age




Return to Challenge Index (http://www.underwaredesign.com/forums/index.php?topic=3225.0)


Title: Re: Challenge #15 - Table Tennis / Pong AI
Post by: slayer93 on November 12, 2008, 11:40:23 PM
My quick try at this. Not the most advance ai or pong game.

Up/Down Arrowkeys to move.

[pbcode]
; PROJECT : Pong!
; AUTHOR  : Christian Ang
; CREATED : 11/12/2008
; ---------------------------------------------------------------------

;
; Setup
SetFPS 0
CreateCamera 1
RenderToScreen

;
; Create Bats
Box 0, 0, 10, 100, 1
GetImage 1, 0, 0, 10, 100
PrepareFXImage 1

Player=NewSprite(20, GetScreenHeight()/2, 1)
CenterSpriteHandle Player
SpriteCollision Player,True
SpriteCollisionMode Player,0

Computer=NewSprite(GetScreenWidth()-20, GetScreenHeight()/2, 1)
CenterSpriteHandle Computer
SpriteCollision Computer,True
SpriteCollisionMode Computer,0
Cls(0)

;
; Create Ball
Circle 10, 10, 10, 0
GetImage 2, 0, 0, 20, 20
PrepareFXImage 2
Ball=NewSprite(GetScreenWidth()/2, GetScreenHeight()/2, 2)
CenterSpriteHandle Ball
SpriteCollision Ball,True
SpriteCollisionMode Ball,2

;
; Set Ball Direction
Ballx=rnd(1)
Bally=rnd(1)
if Ballx=0 then Ballx=-1
if Bally=0 then Bally=-1

;
; Timer System Vars
msPerFrame#=1000/60
oldTime=Timer()

compTime=Timer()
compDecisionTime=rnd(100)+100
compDecision=rnd(3)

;
; Loop
Do

   ;
   ; Draw to Scene Buffer
   CaptureToScene
   ClsScene
   
   ;
   ; Show Score
   Text 0,0,"Player Score: "+str$(pScore)+" | Computer Score: "+str$(cScore)
   
   ;
   ; Update Timer System
   framesPast# = (Timer()-oldTime)/msPerFrame#
   oldTime=Timer()
   
   ;
   ; Controls
   If Upkey()=1 then MoveSprite Player,0.0,-5.0*framesPast#
   If Downkey()=1 then MoveSprite Player,0.0,5.0*framesPast#
   
   ;
   ; Computer Ai
   ; Make a decision every so often
   If Timer()-compTime => compDecisionTime
   ; Don't make it super smart by making 1 out of 10 moves go the wrong way
   ; and 1 out of 10 stay still
      compDecision=rnd(9)
      compDecisionTime=rnd(100)+200
      compTime=Timer()
   Endif

   ; Act on decision
   If compDecision=0
   ;
   ; Idle
   Else
      If compDecision=1
      ;
      ; Wrong Way
         If GetSpriteY(Ball) < GetSpriteY(Computer)
            MoveSprite Computer,0.0,5.0*framesPast#
         Else
            MoveSprite Computer,0.0,-5.0*framesPast#
         Endif
      Else
      ;
      ; Right Way   
         If GetSpriteY(Ball) < GetSpriteY(Computer)
            MoveSprite Computer,0.0,-5.0*framesPast#
         Else
            MoveSprite Computer,0.0,5.0*framesPast#
         Endif
      Endif
   Endif
   
   ;
   ; Move Ball
   If Ballx=1
      MoveSprite Ball,-6.0*framesPast#,0.0
   Else
      MoveSprite Ball,6.0*framesPast#,0.0
   Endif
   
   If Bally=1
      MoveSprite Ball,0.0,-2.0*framesPast#
   Else
      MoveSprite Ball,0.0,2.0*framesPast#
   Endif
   
   ;
   ; Collision
   If SpriteHit(Ball,2,1) > 0
      Ballx=-Ballx
   Endif
   If GetSpriteY(Ball) < 0 or GetSpriteY(Ball) > GetScreenHeight() then Bally=-Bally
   
   If GetSpriteY(Player)-50 < 0 then PositionSprite Player,20,50
   If GetSpriteY(Player)+50 > GetScreenHeight() then PositionSprite Player,20,GetScreenHeight()-50
   If GetSpriteY(Computer)-50 < 0 then PositionSprite Computer,GetScreenWidth()-20,50
   If GetSpriteY(Computer)+50 > GetScreenHeight() then PositionSprite Computer,GetScreenWidth()-20,GetScreenHeight()-50
      
   ;
   ; Score
   If GetSpriteX(Ball) < 0
      inc cScore
      reset=1
   Endif
   If GetSpriteX(Ball) > GetScreenWidth()
      inc pScore
      reset=1
   Endif

   ;
   ; Reset Ball
   If reset=1
      PositionSprite Ball,GetScreenWidth()/2, GetScreenHeight()/2
      Ballx=rnd(1)
      Bally=rnd(1)
      if Ballx=0 then Ballx=-1
      if Bally=0 then Bally=-1
      reset=0
   Endif   

   ;
   ; Draw the Scene
   DrawAllSprites
   DrawCamera 1
   
; Sync
   Sync
Loop

[/pbcode]

Title: Re: Challenge #15 - Table Tennis / Pong AI
Post by: markel422 on October 30, 2009, 11:07:07 AM
I've decided to take Kevin's advice and to not jump too far ahead of myself when it comes to making a big projected game.

I actually really did needed to start small because I had no idea how complicated this programming actually was and Kevin's predictions on how long it takes for a new programmer to create a Pong Game was right on. Compared to only a few hours for very Experienced people to create this...It actually took me a few weeks to get this right (As seen on my Code File on top, the start date and end date) and to understand the concepts of this. I was even able to successfully create the AI for the Computer which is an absolute first for me.:)

I really like how much I've improved on this Game Programming. When I first started, My mind was already blown away just by seeing one line of code :o, but now look at my Progress. :)

At the same time I wonder what my next level of Game Programming will be? After the Pong Game Now.

Here's the Code:

[pbcode]
; PROJECT : FirstGamePong
; AUTHOR  : Michael
; CREATED : 10/17/2009
; EDITED  : 10/30/2009
; ---------------------------------------------------------------------

openscreen 800,600,32,1

setfps 60

loadfont "Arial",1,24,0

gosub Ball_Restart

ballsize=8

player1x=40
player1y=300
player2x=750
player2y=300
playerspeed=4
Width=10
Height=80
p2width=10
p2height=50

sw=getscreenwidth()/2
sh=getscreenheight()/2

Dim PlayerScore(2)
PlayerScore(1)=0
PlayerScore(2)=0

do
   cls 0
   
   Compstate=false
   
   //Create Movement of Ball
   Ballx=ballx+ballspeedx
   
   //Add Collision Code for X Screen
   ;if ballx+ballsize > getscreenwidth()
      ;ballx = getscreenwidth() - ballsize
      ;ballspeedx=ballspeedx * -1
   ;endif
      
   ;if ballx-ballsize < 0
      ;ballx = 0 + ballsize
      ;ballspeedx=ballspeedx * -1
  ;endif
      
   //Add Collision Code for Y Screen
   if bally+ballsize > getscreenheight()
      bally = getscreenheight() - ballsize
      ballspeedy=ballspeedy * -1
   endif
   
   if Bally-ballsize < 0
      bally = 0 + ballsize
      ballspeedy=ballspeedy * -1
   endif

   bally=bally+ballspeedy
   
   //Create Ball Collision for Player
   if player1y+height>Bally-ballsize and player1y<Bally+ballsize
      if player1x+width>ballx-ballsize and player1x<Ballx+ballsize
          Ballspeedx=ballspeedx * -1
      endif
   endif
      
   //Create Ball Collision for AI
   if player2y+height>Bally-ballsize and player2y<Bally+ballsize
      if player2x+width>ballx-ballsize and player2x<Ballx+ballsize
          Ballspeedx=ballspeedx * -1
      endif
   endif
      
         
   //Create Movement of Player 1
   if upkey()=true
      player1y=player1y-playerspeed
  endif
   
   if downkey()=true
      player1y=player1y+playerspeed
  endif

  //Create AI for Player 2
 
 compball=bally-40
 
  ;Handle logic if ball is more than white line of AI space make AI move
  if compstate=false
     if ballx > sw
        Compstate=true
        if player2y > compball
           player2y = player2y - 3
      else if player2y < compball
              player2y = player2y + 3
           endif
        endif
     endif
  endif
 
 ;Handle logic if ball is less than white line of AI space make AI get in center
  if compstate=false
     if ballx < sw
        compstate=true
        if player2y > sh-40
            player2y = player2y - 3
      else if player2y < sh-40
               player2y = player2y + 3
            endif
         endif
     endif
  endif
     
        if player2y = sh-40
            compstate=false
        endif
   
  //Box Screen Collision for Player
  if player1y < 0
      player1y = 0
  endif
     
  if player1y+height > getscreenheight()
     player1y = getscreenheight() - height
  endif
 
  //Box Screen Collision for AI
  if player2y < 0
     player2y = 0
     endif
     
     if player2y+height > getscreenheight()
        player2y = getscreenheight() - height
     endif
     
      //Create Ball
      Circle ballx,bally,ballsize,1
      
      
      //Create Human Player 1
     Box player1x,player1y,player1x+width,player1y+height,1
     
     //Create AI Player 2
     Box player2x,player2y,player2x+width,player2y+height,1
     
     //Create Ball Field
     Box 398,0,403,getscreenheight(),1

     //Display the Player 1 Score
     text 120,10,"Player 1 Score: "+digits$(PlayerScore(1),1)
     
     //Display the Computers Score
     text 520,10,"Computer Score: "+digits$(PlayerScore(2),1)
   
     //If Player Miss Ball Display Message
     if ballx-ballsize < 0
        cls 0
        
        setfont 1
        centertext getscreenwidth()/2,getscreenheight()/2,"Player 1 Missed!"
        sync
        for lp=1 to 4
           wait 1000
        next
        gosub Ball_Restart
        PlayerScore(2)=PLayerScore(2)+1
        ballspeedx=ballspeedx * 1
      endif
     
      //If Computer Miss Ball Display Message
      if ballx-ballsize > getscreenwidth()
         cls 0
         
         setfont 1
         centertext getscreenwidth()/2,getscreenheight()/2,"Computer Missed!"
         sync
         for lp=1 to 4
           wait 1000
        next
        gosub Ball_Restart
        PlayerScore(1)=PlayerScore(1)+1
        ballspeedx=ballspeedx * -1
     endif
   Sync
Loop


 
 
Ball_Restart:

     ballx=getscreenwidth()/2
     bally=getscreenheight()/2
     ballspeedx=rndrange(4,5)
     ballspeedy=rndrange(4,5)

return
[/pbcode]
Title: Re: Challenge #15 - Table Tennis / Pong AI
Post by: kevin on October 30, 2009, 11:48:26 AM
      Well I'm impressed, you've done really well with this and it even seems to play fairly also ! - So a  big  congratulations are in order !   

     
QuoteAt the same time I wonder what my next level of Game Programming will be? After the Pong Game Now.

         Well, you could expand this further.   Multi Ball perhaps ?   yes, cruel I know :)

         What Pong represents is a hand of concepts that are fairly universal in 2D (and 3D) game programming,  stuff like  object management,   handling  user input, object collisions,  motion and ultimately the visual representations of the in game characters (the bat and ball).     What you're about to find out,  is that these concepts are in virtually every game ever written..  So concepts you've learnt here overlap between different game genres.

          As for what's next,  well something along the lines of Snake game is a common one,  or for the little more adventure perhaps a Space Invaders game might be a good healthy challenge next.    Alternatively  most of the major 1980's  arcade games a worth tackling.   Pac Man,  Frogger, Donkey Kong,   Asteroids,  Centipede,  Boulder Dash..   etc -  The down side of knocking up one of those,  is that you generally require at least some mock up artwork.    Atm, the more time you spend focusing upon the programming, the better..                   

        Snake Game (http://www.underwaredesign.com/forums/index.php?topic=2914.0)
        Shoot the Alien (http://www.underwaredesign.com/forums/index.php?topic=3224.0)
         

    Edit:  Another option might be an BreakOut / Arkanoid style game.  Which is basically Pong up against a wall.