# Simple Python Pong Game

I'm trying to code a machine learning version of pong in python. So far, all I have is the game without any AI.

I personally have very little experience with Python and coding in general, so any feedback would really help! If possible, I'd like to know what the common best practices are when working on a project like this and to what degree I am complying with those practices.

Anyway, here is the code:

import pygame

### Colors
WHITE = (255, 255, 255)
BLACK = (0,0,0)

### Constants
W = 600
H = 600
pygame.font.init()
comic = pygame.font.SysFont('Comic Sans MS', 30)

### Variables
wt = 10
mplay = False

p1x = W/30
p1y = H/2 - ((W/60)**2)/2

p2x = W-(W/30)
p2y = H/2 - ((W/60)**2)/2

p1score = 0
p2score = 0

w_p = False
s_p = False
wsr = False
u_p = False
d_p = False
udr = False

dm = H/40

bsd = 1

bx = W/2
by = H/2
bw = W/65
bxv = H/60
bxv = -bxv
byv = 0

### Functions
pygame.draw.rect(screen, WHITE, (x, y, w, h))

def drawball(x, y):
pygame.draw.circle(screen, WHITE, (int(x), int(y)), int(bw))

def uploc():
global p1y
global p2y
if w_p:
if p1y-(dm) < 0:
py1 = 0
else:
p1y -= dm
elif s_p:
else:
p1y += dm
if u_p:
if p2y-(dm) < 0:
p2y = 0
else:
p2y -= dm
elif d_p:
else:
p2y += dm

def upblnv():
global bx
global bxv
global by
global byv
global p2score
global p1score

if (bx+bxv < p1x+paddle_width) and ((p1y < by+byv+bw) and (by+byv-bw < p1y+paddle_height)):
bxv = -bxv
byv = -byv/((5*bw)/7)
elif bx+bxv < 0:
p2score += 1
bx = W/2
bxv = H/60
by = H/2
byv = 0
if (bx+bxv > p2x) and ((p2y < by+byv+bw) and (by+byv-bw < p2y+paddle_height)):
bxv = -bxv
byv = -byv/((5*bw)/7)
elif bx+bxv > W:
p1score += 1
bx = W/2
bxv = -H/60
by = H/2
byv = 0
if by+byv > H or by+byv < 0:
byv = -byv

bx += bxv
by += byv

def drawscore():
score = comic.render(str(p1score) + " - " + str(p2score), False, WHITE)
screen.blit(score, (W/2,30))

### Initialize
screen = pygame.display.set_mode((W, H))
pygame.display.set_caption('Snake ML v.1.0.0')
screen.fill(BLACK)
pygame.display.flip()

running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
if event.key == pygame.K_w:
w_p = True
if s_p == True:
s_p = False
wsr = True
if event.key == pygame.K_s:
s_p = True
if w_p == True:
w_p = False
wsr = True
if event.key == pygame.K_UP:
u_p = True
if d_p == True:
d_p = False
udr = True
if event.key == pygame.K_DOWN:
d_p = True
if u_p == True:
u_p = False
udr = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_w:
w_p = False
if wsr == True:
s_p = True
wsr = False
if event.key == pygame.K_s:
s_p = False
if wsr == True:
w_p = True
wsr = False
if event.key == pygame.K_UP:
u_p = False
if udr == True:
d_p = True
udr = False
if event.key == pygame.K_DOWN:
d_p = False
if udr == True:
u_p = True
udr = False

screen.fill(BLACK)
uploc()
upblnv()
drawscore()
drawball(bx, by)
pygame.display.flip()
pygame.time.wait(wt)

• That's a lot of awfully short variable names. How do you keep track of what they mean? What parts have you implemented so far, what's still missing and are the parts implemented working as intended? – Mast May 13 '18 at 13:51

First of all, welcome to CodeReview!

I'd like to know what the common best practices are when working on a project

1. naming

It has been mentioned in the comments by @mast, naming is a very important part of coding. Would you still understand this code after a hiatus of a few months? I have a hard time understanding the code as is. I would have been able to give a better review if your code was more readable. Good code should be readable at first glance, the below variables have no meaning for me...

bsd = 1
bx = W/2
by = H/2
bw = W/65
bxv = H/60
bxv = -bxv
byv = 0

2. Divide code into more functions/classes!

You say you want to make it run by an AI... as is, your code would require a heck of a rewrite. But if you would have divided your code into more functions, the AI can reuse a lot of the functions you created for a single player game, and thus making your code easier to maintain, or add functionality.

What functions/classes should a game of pong have?

• a Player (class) <-- This player class can be used by both Players.

class Player:
"""A player class
name: a string of the Players name
score: The score of the player
movement_keys: list of Keys used to move the player [pygame.K_DOWN, ...]"""
pass

def move(self, dy):
pass

pass

• a Pong enviroment (class)

class Pong:
def __init__(self, players):
pass

def start_game(self):
pass

def reset_game(self):
pass


Using a structure like this will improve the code alot, and adding an AI (or other improvements will be easier after this)

3. Avoid working in the global namespace

This point is interwoven with dividing the code into functions/classes, see this link as to WHY working in the global namespace is considered bad.

4. Wrap up your code into a if __name__ == "__main__": guard.

This will make your code be runnable from the command line, while also be able to be imported into other scripts