7
\$\begingroup\$

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 paddle_width = W/60 paddle_height = paddle_width**2 bsd = 1 bx = W/2 by = H/2 bw = W/65 bxv = H/60 bxv = -bxv byv = 0 ### Functions def drawpaddle(x, y, w, h): 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: if p1y+(dm)+paddle_height > H: p1y = H-paddle_height else: p1y += dm if u_p: if p2y-(dm) < 0: p2y = 0 else: p2y -= dm elif d_p: if p2y+(dm)+paddle_height > H: p2y = H-paddle_height 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 = ((p1y+(p1y+paddle_height))/2)-by 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 = ((p2y+(p2y+paddle_height))/2)-by 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) drawpaddle(p1x, p1y, paddle_width, paddle_height) drawpaddle(p2x, p2y, paddle_width, paddle_height) pygame.display.flip() pygame.time.wait(wt) 
\$\endgroup\$
1
  • \$\begingroup\$ 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? \$\endgroup\$ Commented May 13, 2018 at 13:51

1 Answer 1

8
\$\begingroup\$

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 paddle_x: an int of the players paddle x position paddle_y: an int of the players paddle y position score: The score of the player movement_keys: list of Keys used to move the player [pygame.K_DOWN, ...]""" def __init__(self, name, paddle_x, paddle_y, score, movement_keys): pass def move(self, dy): pass def draw_paddle(self): 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

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.