2
\$\begingroup\$

I have made this pong game as a 1 player game, versus the computer. however it is impossible to beat the ai. Any ideas to make the code better would be appreciated.

import pygame
from pygame.locals import *
pointcounter = 0
class Pong(object):
 def __init__(self, screensize):
 self.screensize = screensize
 self.centerx = int(screensize[0]*0.5)
 self.centery = int(screensize[1]*0.5)
 self.radius = 8
 self.rect = pygame.Rect(self.centerx-self.radius,
 self.centery-self.radius,
 self.radius*2, self.radius*2)
 self.color = (255,255,255)
 self.direction = [1,1]
 #speed of ball
 self.speedx = 5
 self.speedy = 5
 self.hit_edge_left = False
 self.hit_edge_right = False
 def update(self, player_paddle, ai_paddle):
 global pointcounter
 self.centerx += self.direction[0]*self.speedx
 self.centery += self.direction[1]*self.speedy
 self.rect.center = (self.centerx, self.centery)
 if self.rect.top <= 0:
 self.direction[1] = 1
 elif self.rect.bottom >= self.screensize[1]-1:
 self.direction[1] = -1
 if self.rect.right >= self.screensize[0]-1:
 self.hit_edge_right = True
 elif self.rect.left <= 0:
 self.hit_edge_left = True
 if self.rect.colliderect(player_paddle.rect):
 self.direction[0] = -1
 pointcounter += 1
 if self.rect.colliderect(ai_paddle.rect):
 self.direction[0] = 1
 def render(self, screen):
 pygame.draw.circle(screen, self.color, self.rect.center, self.radius, 0)
 pygame.draw.circle(screen, (0,0,0), self.rect.center, self.radius, 1)
#creates the AI paddle
class AIPaddle(object):
 def __init__(self, screensize):
 self.screensize = screensize
 self.centerx = 5
 self.centery = int(screensize[1]*0.5)
 #ai paddle dimensions
 self.height = 100
 self.width = 10
 self.rect = pygame.Rect(0, self.centery-int(self.height*0.5), self.width, self.height)
 self.color = (255,255,255)
 #ai paddle speed
 self.speed = 6
 def update(self, pong):
 if pong.rect.top < self.rect.top:
 self.centery -= self.speed
 elif pong.rect.bottom > self.rect.bottom:
 self.centery += self.speed
 self.rect.center = (self.centerx, self.centery)
 def render(self, screen):
 pygame.draw.rect(screen, self.color, self.rect, 0)
 pygame.draw.rect(screen, (0,0,0), self.rect, 1)
#creates the player paddle
class PlayerPaddle(object):
 def __init__(self, screensize):
 self.screensize = screensize
 self.centerx = screensize[0]-5
 self.centery = int(screensize[1]*0.5)
 #player paddle dimensions
 self.height = 100
 self.width = 10
 self.rect = pygame.Rect(0, self.centery-int(self.height*0.5), self.width, self.height)
 self.color = (255,255,255)
 #player paddle speed
 self.speed = 10
 self.direction = 0
 def update(self):
 self.centery += self.direction*self.speed
 self.rect.center = (self.centerx, self.centery)
 if self.rect.top < 0:
 self.rect.top = 0
 if self.rect.bottom > self.screensize[1]-1:
 self.rect.bottom = self.screensize[1]-1
 def render(self, screen):
 pygame.draw.rect(screen, self.color, self.rect, 0)
 pygame.draw.rect(screen, (0,0,0), self.rect, 1)
def main():
 pygame.init()
 global pointcounter
 screensize = (640,480)
 screen = pygame.display.set_mode(screensize)
 clock = pygame.time.Clock()
 pong = Pong(screensize)
 ai_paddle = AIPaddle(screensize)
 player_paddle = PlayerPaddle(screensize)
 running = True
 while running:
 clock.tick(64)
 for event in pygame.event.get():
 if event.type == QUIT:
 running = False
 if event.type == KEYDOWN:
 if event.key == K_UP:
 player_paddle.direction = -1
 elif event.key == K_DOWN:
 player_paddle.direction = 1
 if event.type == KEYUP:
 if event.key == K_UP and player_paddle.direction == -1:
 player_paddle.direction = 0
 elif event.key == K_DOWN and player_paddle.direction == 1:
 player_paddle.direction = 0
 ai_paddle.update(pong)
 player_paddle.update()
 pong.update(player_paddle, ai_paddle)
 if pong.hit_edge_left:
 print ('You Won')
 running = False
 elif pong.hit_edge_right:
 print ('Your Score')
 print (pointcounter)
 running = False
 screen.fill((0,0,0))
 ai_paddle.render(screen)
 player_paddle.render(screen)
 pong.render(screen)
 pygame.display.flip()
 pygame.quit()
main()
200_success
145k22 gold badges190 silver badges478 bronze badges
asked Oct 21, 2016 at 10:27
\$\endgroup\$
0

1 Answer 1

2
\$\begingroup\$

The AI needs some random loss of concentration. The AIPaddle.update method needs to start pretending that self.speed is zero and continue to do so for a while (about a second).

To the player it will appear that the game will lose concentration every now and then and give the human player a chance to score. You could also try to make the AI look at a previous position of the ball to cause some human-like decision making lag, but I doubt it's worth it.

An alternative approach would be to simply increase the speed of the ball but not the paddles. The AI looks defensive, so it might not be able to score, and increasing the speed of the ball would give the human player a chance to score more often by intentionally positioning the paddle in advantageous ways.

This is what I would do differently

import time
import random
class AIPaddle(object):
 def __init__(self, screensize):
 # ...
 # If time.time() > self.AI_time: the AI will work
 self.AI_on_after = time.time()
 # Probability of AI failing each second: 0 <= P <= 1
 self.P_AI_fail = 0.1
 # Duration in which AI won't do anything when it has failed
 self.T_AI_fail = 1.0
 self.next_fail_decision_T = time.time()
 def update(self, pong):
 # Each second: Decide if it's time to fail
 if time.time() > self.next_fail_decision_T:
 if random.random() <= self.P_AI_fail:
 self.AI_on_after = time.time() + self.T_AI_fail
 self.next_fail_decision_T = time.time() + 1.0
 # Random loss of concentration
 if time.time() > self.AI_on_afer:
 speed = 0
 else:
 speed = self.speed
 if pong.rect.top < self.rect.top:
 self.centery -= speed
 elif pong.rect.bottom > self.rect.bottom:
 self.centery += speed
answered Oct 21, 2016 at 11:04
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.