【问题标题】:Artificial inteligence in python and pygame for Pong clone用于 Pong 克隆的 python 和 pygame 中的人工智能
【发布时间】:2012-12-05 15:42:31
【问题描述】:

我正在根据教程制作一个克隆 pong 的程序,并且我已经将该程序用于与两个不同的人进行多人游戏的地方。我想在程序中添加一个 AI 而不是玩家 2。我已经坚持了很长一段时间,希望能提供任何帮助!这是目前的代码:

import sys, os, math, random, pygame from pygame.locals import *

class paddle(pygame.sprite.Sprite):

def __init__(self, xy):
    pygame.sprite.Sprite.__init__(self)
    self.image = pygame.image.load(os.path.join('assets', 'pong_paddle.gif'))
    self.rect = self.image.get_rect()

    self.rect.centerx, self.rect.centery = xy

    self.movementspeed = 5

    self.velocity = 0

def up(self):
    # increases vertical velocity
    self.velocity -= self.movementspeed

def down(self):
    # decreases vertical velocity
    self.velocity += self.movementspeed

def move(self, dy):
    # moves the paddle y, doesn't go out of top or bottom
    if self.rect.bottom + dy > 400:
        self.rect.bottom = 400
    elif self.rect.top + dy < 0:
        self.rect.top = 0
    else:
        self.rect.y += dy

def update(self):
    # makes the paddle move every frame
    self.move(self.velocity)

class aiplayer(object):

def __init__(self):
    self.bias = random.random() - 0.5
    self.hit_count = 0



def update(self, paddle, game,):


    if (paddle.rect.centerx < game.bounds.centerx and game.ball.rect.centerx < game.bounds.centerx) or (paddle.rect.centerx > game.bounds.centerx and game.ball.rect.centerx > game.bounds.centerx):
        delta = (paddle.rect.centery + self.bias * paddle.rect.height) - game.ball.rect.centery 
        if abs(delta) > paddle.velocity:
            if delta > 0:
                paddle.direction = -1
            else:
                paddle.direction = 1
        else:
            paddle.direction = 0
    else:
        paddle.direction = 0

def hit(self):
    self.hit_count += 1
    if self.hit_count > 6:
        self.bias = random.random() - 0.5
        self.hit_count = 0

def lost(self):
    self.bias = random.random() - 0.5

    def won(self):
        pass


def render(self, surface):

    x, y = self.location
    w, h = self.image.get_size()
    surface.blitz(self.image, (x-w/2, y-h/2))

class Ball(pygame.sprite.Sprite):

def __init__(self, xy):
    pygame.sprite.Sprite.__init__(self)
    self.image = pygame.image.load(os.path.join('assets', 'pong_ball.gif'))
    self.rect = self.image.get_rect()

    self.rect.centerx, self.rect.centery = xy
    self.maxspeed = 10
    self.servespeed = 5
    self.velx = 0
    self.vely = 0

def reset(self):
    self.rect.centerx, self.rect.centery = 400, 200
    self.velx = 0
    self.vely = 0

def serve(self):
    angle = random.randint(-45, 45)

    if abs(angle) < 5 or abs(angle-180) < 5:
        angle = random.randint(10, 20)

    if random.random() > .5:
        angle += 180

    # this gets the velocity for the x and y coords
    x = math.cos(math.radians(angle))
    y = math.sin(math.radians(angle))

    self.velx = self.servespeed * x
    self.vely = self.servespeed * y

class Game(object):

def __init__(self):

    pygame.init()

    # creates the window
    self.window = pygame.display.set_mode((800, 400))

    # makes a clock
    self.clock = pygame.time.Clock()

    # window title
    pygame.display.set_caption("Pong")

    # tells pygame to watch for these certain events so we can close window
    pygame.event.set_allowed([QUIT, KEYDOWN, KEYUP])

    self.background = pygame.Surface((800, 400))
    self.background.fill((55, 255, 85))
    pygame.draw.line(self.background, (0,0,0), (400, 0), (400, 400), 2)
    self.window.blit(self.background, (0,0))
    #lets the background show up
    pygame.display.flip()



    #renders the sprites so that they actually show up
    self.sprites = pygame.sprite.RenderUpdates()

    # makes the paddles, adds to sprite group
    self.leftpaddle = paddle((50, 200))
    self.sprites.add(self.leftpaddle)
    self.rightpaddle = paddle((750, 200))
    self.sprites.add(self.rightpaddle)

    # makes the ball
    self.ball = Ball((400, 200))
    self.sprites.add(self.ball)


def run(self):
    # this lets the game run using a loop so its always active and never closes
    running = True

    while running:
        self.clock.tick(60)

        # pygame event, if user closes the game, then stop running
        running = self.handleEvents()

        pygame.display.set_caption("Pong %d fps" % self.clock.get_fps())

        self.manageBall()

        # updates the sprites(paddles, ball)
        for sprite in self.sprites:
            sprite.update()

        # renders the sprites
        self.sprites.clear(self.window, self.background)
        dirty = self.sprites.draw(self.window)
        pygame.display.update(dirty)

def handleEvents(self):

    for event in pygame.event.get():
        if event.type == QUIT:
            return False

        elif event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                return False

            # controls the right paddle
            if event.key == K_w:
                self.leftpaddle.up()
            if event.key == K_s:
                self.leftpaddle.down()
            if event.key == K_UP:
                self.rightpaddle.up()
            if event.key == K_DOWN:
                self.rightpaddle.down()

            # serves the ball
            if event.key == K_SPACE:
                if self.ball.velx == 0 and self.ball.vely == 0:
                    self.ball.serve()

        elif event.type == KEYUP:
            if event.key == K_w:
                self.leftpaddle.down()
            if event.key == K_s:
                self.leftpaddle.up()
            if event.key == K_UP:
                self.rightpaddle.down()
            if event.key == K_DOWN:
                self.rightpaddle.up()

        elif event.type == 


    return True



def manageBall(self):

    # this moves the ball
    self.ball.rect.x += self.ball.velx
    self.ball.rect.y += self.ball.vely

    if self.ball.rect.top < 0:
        self.ball.rect.top = 1

        # makes the ball bounce
        self.ball.vely *= -1

    elif self.ball.rect.bottom > 400:
        self.ball.rect.bottom = 399

        # makes ball bounce off bottom
        self.ball.vely *= -1

    # resets the ball if it hits the left or right screen
    if self.ball.rect.left < 0:
        self.ball.reset()
        return

    elif self.ball.rect.right > 800:
        self.ball.reset()
        return

    collision = pygame.sprite.spritecollide(self.ball, [self.leftpaddle, self.rightpaddle], dokill = False)

    if len(collision) > 0:
        hitpaddle = collision[0]

        # sends the ball back
        self.ball.velx *= -1

        # makes sure the ball doesn't get stuck in the paddle
        self.ball.rect.x += self.ball.velx

# makes the game and runs it if __name__ == '__main__': game = Game() game.run()

【问题讨论】:

  • 您应该提供更具体的问题。
  • 您是否考虑过一个函数,它每 x 毫秒调用一次,查看球的位置,然后将球拍移向球?您也可以将其注册为活动。
  • 你追求的不是真正的“人工智能”吗?如果桨在球“下方”,则将其向上移动,如果在“上方”,则将球向下移动。
  • 我同意 JohnnyMopp 的问题应该更具体
  • 我正在寻找一个人工智能,正如你在我的课堂 aiplayer 中看到的那样,我试图让它到达人工智能将跟随球的位置,但我不知道如何实现人工智能进入其余代码,以便它可以运行。我会尝试这个想法舒兰

标签: python artificial-intelligence pygame


【解决方案1】:

在aiplayer中创建一个函数AI并让它向上或向下返回

int AI(self.position,ball.position):
       if self.y>ball.y:
            return -1
       elif self.y<ball.y:
             return 1

然后,在 aiplayer 的 update() 代码中,做类似的事情

self.y += movespeed*AI(self.position,ball.position)

然后,它会根据球的位置向上或向下移动桨叶(如果您添加或减去移动速度以使桨叶朝正确的方向移动,您可能需要切换)。此外,使用桨的中心可能更有效,这样它就不会将桨的顶部或底部边缘放在球上。

【讨论】:

  • 我按照你所说的做了,并在游戏函数中调用了 aiplayer 函数,希望它能运行,但在 python shell 中我收到错误消息“游戏”对象没有属性“aiplayer”。关于这意味着什么的任何想法,我试图修复它,但似乎无法得到它。
  • 你把AI功能放在aiplayer类里了吗?如果你没有,请确保你这样做。然后,如果这不能解决问题,请调用 self.AI() 而不是 AI()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-20
  • 1970-01-01
  • 1970-01-01
  • 2011-04-17
  • 1970-01-01
相关资源
最近更新 更多