# Shortest Pong, AI vs AI

Your task is to write the shortest possible Pong game without human interaction, so AI plays vs AI. I assume all of you know Pong, just to make sure, this is the target (just as running code):

The following game rules apply:

1. No ASCII "graphics".
2. You must actually have code to count the scores, even if the AI never scores.
3. It must be possible to adjust the size of the output window/area in some way to any (reasonable) size. Which means you must include some form of output scaling.
4. No need for a menu or other features of the game, just what's in the video.

The following play fair rules apply as well:

• No language specifically designed for code golfing.
• You may only use standard libraries offered by the language of your choice. No external library downloading, no jQuery, no full-sized game-libraries.
Exception: if no library for graphical output is available with the default offering of the language of your choice, you are allowed to use a library that offers basic graphical output similar to what other languages include in their basic library set.
• import statements (or however they are called in your language) can be skipped in the character count.
• Doorknob-rule: The paddles may not be bigger than 15% of the game area.

Bonus points:

• -50 if you include sound. External sound sources (e.g. wav) do not need to be added to the char count and may be downloaded during execution. If you choose to copy & paste the data into the code, only the actual data is allowed to be skipped for character count.
• Another -150 (for -200 total) if you do not use external sounds but generate it. Generate means: you have some form of sound synthesizing, copy & pasting e.g. wav data does not count.
• Your "No language specifically designed for code golfing." rule is basically the opposite of "fair"...
– Doorknob
Mar 8 '14 at 14:23
• It is very fair, because otherwise the solution would be: A Where A is the language specifically designed to display an automatic AI vs AI Pong game. Mar 8 '14 at 14:33
• Your wording suggests that golfing languages like J or GolfScript disallowed. Perhaps you may want to reword that. In any case, it's automatically disallowed in the first place.
– Doorknob
Mar 8 '14 at 14:33
• No ASCII "graphics". That's a bit mean to non-http languages, don't you think? Mar 9 '14 at 11:42
• I don't think that a drawRect is that much longer than the definition of a colored div with style-sheets, the graphics are not that detailed after all. ;) And both need to come up with a way to actually move those. Mar 9 '14 at 14:13

# Pure HTML and CSS, 355 characters

<div class=p></div><div style="height:300px"></div><div class=p></div><div id=b></div>0-0<style>.p{width:99px;height:20px;background:#000}*{margin:0}#b{position:absolute;background:#F00;width:20px;height:20px;animation-name:b;animation-duration:3s;animation-iteration-count:infinite;left:40px}@keyframes b{from{top:20px}50%{top:300px}to{top:20px}}</style>


You may need an up-to-date or beta browser for the CSS animation properties.

Here is a fiddle, with -webkit- vendor prefixes added so that it works in latest Chrome.

The ball just bounces back and forth. The AIs are extremely smart and know not to move.

The 0-0 at the bottom is the score, and you can resize the window.

• It is now against the rules, but +1 for pointing that out. :P Mar 8 '14 at 14:35
• @TwoThe that still will work as long as the ball doesnt go diagonal :P Mar 8 '14 at 14:38
• @TwoThe Actually, the real playing area is much larger; I just took a small screenshot. See the fiddle.
– Doorknob
Mar 8 '14 at 14:38
• It wouldn't be "as the video" anyways. Game field is sideways, ball needs to actually bounce off and paddles need to move. Mar 8 '14 at 14:39
• nitpicking after Doorknob escaped the rules :P Mar 8 '14 at 21:57

# Scratch, 1605 – 50 = 1555

I don't know how to count the score here and it doesn't meet the "resizing the window" rule... I just thought it was fun. Some unrealistic speed though, and one known bug: if the ball hit the bar at an almost vertical angle, it will somehow get trapped.

Edit: updated score as per community consensus.

The bars will only move if the ball is moving towards its direction. I could make it always move, but I think that would be too boring.

Sprite1: the "ball"

Sprite2: the right vertical "bar" (don't know what it's called)

Sprite3: the left vertical "bar": essentially the same as Sprite2, except the first if condition, which is changed to direction of Sprite1 < 0

Note: you can change the "intelligence" of the AI by changing the glide speed. They will move slower, so higher chance of missing the ball.

Sprite4 and Sprite5 are two white vertical bars placed on either side of the "field". They have no scripts.

Code used for byte counting: (Using snippet to hide code)

when green flag clicked
set [score1 v] to [0]
set [score2 v] to [0]
forever
go to x: (0) y: (0)
wait (1) secs
point in direction (pick random (70) to (290))
repeat until <<touching [Sprite4 v] ?> or <touching [Sprite5 v] ?>>
move (10) steps
if <touching color [#000] ?> then
play sound [pop v]
point in direction (((360) - (direction)) + (pick random (-5) to (5)))
end
if <touching [edge v] ?> then
if on edge, bounce
point in direction ((direction) + (pick random (-5) to (5)))
end
end
if <touching [Sprite4 v] ?> then
change [score1 v] by (1)
end
if <touching [Sprite5 v] ?> then
change [score2 v] by (1)
end
end

when green flag clicked
forever
if <[0] < ([direction v] of [Sprite1 v])> then
if <([y position v] of [Sprite1 v]) > [140]> then
glide (.1) secs to x: (x position) y: (140)
else
if <([y position v] of [Sprite1 v]) < [-140]> then
glide (.1) secs to x: (x position) y: (-140)
else
glide (.1) secs to x: (x position) y: ([y position v] of [Sprite1 v])
end
end
end
end

when green flag clicked
forever
if <([direction v] of [Sprite1 v]) < [0]> then
if <([y position v] of [Sprite1 v]) > [140]> then
glide (.1) secs to x: (x position) y: (140)
else
if <([y position v] of [Sprite1 v]) < [-140]> then
glide (.1) secs to x: (x position) y: (-140)
else
glide (.1) secs to x: (x position) y: ([y position v] of [Sprite1 v])
end
end
end
end

Note: Code automatically generated using scratchblocks generator, modified as somehow the generator doesn't correctly handle decimal numbers (treating .1 as 0).

See it run online here.

Old version (the bars move randomly).

A screenshot:

• I like that XD Whether or not that qualifies as "No use of full solution libraries" I leave up to the community votes. If you manage to join the Y-position of the paddles with the one of the ball, the AD should turn into AI, however there is no requirement for them being smart. ;) Mar 9 '14 at 16:36
• @TwoThe Thanks for the tip, see edit. Mar 9 '14 at 17:21
• Could someone please add the byte count? meta.codegolf.stackexchange.com/a/5013/34718 Sep 26 '16 at 15:23
• @mbomb007 Done. Sep 26 '16 at 19:00

# HTML / JavaScript, 476

<body onload="for(p in r=c.getClientRects()[0])top[p[0]]=c[p]=r[p];t=c.getContext('2d');t.T=t.fillText;t.R=t.fillRect;A=B=0;a=b=h/2;H=h/9|0;x=w/2;y=h/2;v=w/550;z=h/250;setInterval('x<w/3&&(a+=a<y?3:-3);x>2*w/3&&(b+=b<y?3:-3);y<0|y>h?z=-z:0;x<8&&y>a&&y<a+H||x>w-8&&y>b&&y<b+H?v=-v:0;x+=v;y+=z;(x<0?++A:x>w?++B:0)&&(x=w/2,y=h/2);with(t)clearRect(0,0,w,h),R(x,y,5,5),R(2,a,6,H),R(w-8,b,6,H),T(A,H,9),T(B,w-H,9)',16)"><style>*{margin:0;width:100%;height:100%}</style><canvas id=c>


Un-golfed:

<body>
<style>*{margin:0;width:100%;height:100%;}</style>
<canvas id="c"></canvas>
<script>
// Resize canvas
for(p in r=c.getClientRects()[0])top[p[0]]=c[p]=r[p];

// Get drawing context
t = c.getContext('2d');

// Shorter names
t.T=t.fillText;t.R=t.fillRect;

// Scores
A=B=0;

a=b=h/2;
H=h/9|0;

// Ball position
x=w/2;
y=h/2;

// Ball velocity
dx=w/550;
dy=h/250;

setInterval(function() {
// Process AI
x<w/3&&(a+=a<y?3:-3);
x>2*w/3&&(b+=b<y?3:-3);

// Wall collisions
y<0|y>h?dy=-dy:0;

x<8&&y>a&&y<a+H||x>w-8&&y>b&&y<b+H?dx=-dx:0;

// Update ball position
x+=dx;
y+=dy;

// Update score if the ball is behind the paddle.
// If so, reset the ball position
(x<0?++A:x>w?++B:0)&&(x=w/2,y=h/2);

with(t){
// Clear screen
clearRect(0,0,w,h);

// Draw ball
R(x,y,5,5);