Pygame实现《人工智能-一种现代的方法》的吸尘器空间

Agent

吸尘器空间是此书在介绍Agent时一直举例的例子,今天我们来实现它

运行过程

直接运行VacuumGUI.py程序

python ./VacuumGUI.py

# @Time    : 2021/9/29 10:49
# @Author  : AlanLiang
# @FileName: VacuumGUI.py
# @Software: VS Code
# @Github  :https://github.com/AlanLiangC
# @Mail    : liangao21@mails.ucas.ac.cn

import pygame
# 屏幕大小的常量
SCREEN_RECT = pygame.Rect(0, 0, 480, 480)
# 刷新的帧率
FRAME_PER_SEC = 60

class PlaneGame(object):
    def __init__(self):
        print("界面初始化")
        # 加载相应的图片
        self.row , self.col = eval(input("请输入环境空间的行列数: "))
        self.dirt = pygame.image.load('./dirt.png')
        self.vacuum = pygame.image.load('./vacuum.png')
        self.block = pygame.image.load('./block.png')
        self.cell_width = 10
        self.cell_height = 10
        # 创建窗口
        self.screen = pygame.display.set_mode(SCREEN_RECT.size)
        pygame.display.set_caption("吸尘器的任务环境")
        # 创建时钟
        self.clock = pygame.time.Clock()
        # 存储有垃圾的网格位置
        self.dirt_add = []
        # 存储吸尘器的初始位置并记录吸尘器的运动路径
        self.vacuum_add = None
        # 存储有障碍的网格位置
        self.block_add = []
        self.dirt_vec = []
        self.block_vec = []

    def start_game(self):
        print("开启界面...")
        while True:
            self.draw_background(self.row,self.col)
            # 设置刷新帧率
            self.clock.tick(FRAME_PER_SEC)
            # 事件监听
            self.__event_handler()
            if len(self.dirt_add) > 0:
                for point in self.dirt_add:
                    self.screen.blit(self.dirt,point)
            if len(self.block_add) > 0:
                for point in self.block_add:
                    self.screen.blit(self.block,point)
            if self.vacuum_add != None:
                self.screen.blit(self.vacuum,self.vacuum_add)
            
            # 更新显示
            pygame.display.update()

    def draw_background(self,row,col):
        self.screen.fill((255,255,255))
        WIDTH = SCREEN_RECT.size[0]
        HEIGHT = SCREEN_RECT.size[1]
        self.cell_width = WIDTH/col
        self.cell_height = HEIGHT/row
        # 将对应的图片进行方格大小的尺度缩放
        self.dirt = pygame.transform.scale(self.dirt,(int(self.cell_width),int(self.cell_height)))
        self.vacuum = pygame.transform.scale(self.vacuum,(int(self.cell_width),int(self.cell_height)))
        self.block = pygame.transform.scale(self.block,(int(self.cell_width),int(self.cell_height)))
        # 绘制行
        for r in range(row):
            pygame.draw.line(self.screen,(0,0,0),(0,r * self.cell_height),
                            (WIDTH,r * self.cell_height))
        # 绘制列
        for c in range(col):
            pygame.draw.line(self.screen,(0,0,0),(c * self.cell_width,0),
                            (c * self.cell_width,HEIGHT))

    def __event_handler(self):
        for event in pygame.event.get():

            # 判断是否退出界面
            if event.type == pygame.QUIT:
                PlaneGame.__game_over()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                x = event.pos[0] // self.cell_width 
                y = event.pos[1] // self.cell_height
                if event.button == 1:
                    print(event)
                    print("在{},{}放置了一堆垃圾".format(x,y))
                    self.dirt_add.append((x*self.cell_width,y*self.cell_height))
                    self.dirt_vec.append((x,y))
                    print(self.dirt_vec)

                elif event.button == 3:
                    print(event)
                    print("在{},{}放置了一个障碍".format(x,y))
                    self.block_add.append((x*self.cell_width,y*self.cell_height))
                    self.block_vec.append((x,y))
                    print(self.block_vec)

                elif event.button == 2 or event.button == 4 or event.button == 5:
                    print(event)
                    print("在{},{}放置了一个扫地机器人".format(x,y))
                    self.vacuum_add = (x*self.cell_width,y*self.cell_height)

    def __game_over():
        print("关闭界面")
        pygame.quit()
        exit()
if __name__ == "__main__":
    # 创建对象
    game = PlaneGame()
    # 启动界面
    game.start_game()
  • 输入环境的行列数
界面初始化
请输入环境空间的行列数: 10,10
开启界面...
  • 初始界面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TEcvaGAM-1634544774346)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211009175230224.png)]

  • 点击鼠标左键,放置“灰尘”

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OB9kUu9L-1634544774371)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211009175308630.png)]

<Event(5-MouseButtonDown {'pos': (158, 117), 'button': 1, 'window': None})>3.0,2.0放置了一堆垃圾
[(3.0, 2.0)]
<Event(5-MouseButtonDown {'pos': (195, 124), 'button': 1, 'window': None})>4.0,2.0放置了一堆垃圾
[(3.0, 2.0), (4.0, 2.0)]
<Event(5-MouseButtonDown {'pos': (271, 184), 'button': 1, 'window': None})>5.0,3.0放置了一堆垃圾
[(3.0, 2.0), (4.0, 2.0), (5.0, 3.0)]
<Event(5-MouseButtonDown {'pos': (269, 222), 'button': 1, 'window': None})>5.0,4.0放置了一堆垃圾
[(3.0, 2.0), (4.0, 2.0), (5.0, 3.0), (5.0, 4.0)]
<Event(5-MouseButtonDown {'pos': (274, 311), 'button': 1, 'window': None})>5.0,6.0放置了一堆垃圾
[(3.0, 2.0), (4.0, 2.0), (5.0, 3.0), (5.0, 4.0), (5.0, 6.0)]
<Event(5-MouseButtonDown {'pos': (273, 367), 'button': 1, 'window': None})>5.0,7.0放置了一堆垃圾
[(3.0, 2.0), (4.0, 2.0), (5.0, 3.0), (5.0, 4.0), (5.0, 6.0), (5.0, 7.0)]
<Event(5-MouseButtonDown {'pos': (343, 312), 'button': 1, 'window': None})>7.0,6.0放置了一堆垃圾
[(3.0, 2.0), (4.0, 2.0), (5.0, 3.0), (5.0, 4.0), (5.0, 6.0), (5.0, 7.0), (7.0, 6.0)]
<Event(5-MouseButtonDown {'pos': (92, 241), 'button': 1, 'window': None})>1.0,5.0放置了一堆垃圾
[(3.0, 2.0), (4.0, 2.0), (5.0, 3.0), (5.0, 4.0), (5.0, 6.0), (5.0, 7.0), (7.0, 6.0), (1.0, 5.0)]
<Event(5-MouseButtonDown {'pos': (56, 142), 'button': 1, 'window': None})>1.0,2.0放置了一堆垃圾
[(3.0, 2.0), (4.0, 2.0), (5.0, 3.0), (5.0, 4.0), (5.0, 6.0), (5.0, 7.0), (7.0, 6.0), (1.0, 5.0), (1.0, 2.0)]
<Event(5-MouseButtonDown {'pos': (381, 395), 'button': 1, 'window': None})>7.0,8.0放置了一堆垃圾
[(3.0, 2.0), (4.0, 2.0), (5.0, 3.0), (5.0, 4.0), (5.0, 6.0), (5.0, 7.0), (7.0, 6.0), (1.0, 5.0), (1.0, 2.0), (7.0, 8.0)]
<Event(5-MouseButtonDown {'pos': (433, 141), 'button': 1, 'window': None})>9.0,2.0放置了一堆垃圾
[(3.0, 2.0), (4.0, 2.0), (5.0, 3.0), (5.0, 4.0), (5.0, 6.0), (5.0, 7.0), (7.0, 6.0), (1.0, 5.0), (1.0, 2.0), (7.0, 8.0), (9.0, 2.0)]
<Event(5-MouseButtonDown {'pos': (335, 65), 'button': 1, 'window': None})>6.0,1.0放置了一堆垃圾
[(3.0, 2.0), (4.0, 2.0), (5.0, 3.0), (5.0, 4.0), (5.0, 6.0), (5.0, 7.0), (7.0, 6.0), (1.0, 5.0), (1.0, 2.0), (7.0, 8.0), (9.0, 2.0), (6.0, 1.0)]
  • 点击鼠标右键,放置“障碍”

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4rPOUYCH-1634544774374)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211009175341428.png)]

<Event(5-MouseButtonDown {'pos': (116, 246), 'button': 3, 'window': None})>2.0,5.0放置了一个障碍
[(2.0, 5.0)]
<Event(5-MouseButtonDown {'pos': (206, 276), 'button': 3, 'window': None})>4.0,5.0放置了一个障碍
[(2.0, 5.0), (4.0, 5.0)]
<Event(5-MouseButtonDown {'pos': (176, 345), 'button': 3, 'window': None})>3.0,7.0放置了一个障碍
[(2.0, 5.0), (4.0, 5.0), (3.0, 7.0)]
<Event(5-MouseButtonDown {'pos': (165, 307), 'button': 3, 'window': None})>3.0,6.0放置了一个障碍
[(2.0, 5.0), (4.0, 5.0), (3.0, 7.0), (3.0, 6.0)]
<Event(5-MouseButtonDown {'pos': (159, 267), 'button': 3, 'window': None})>3.0,5.0放置了一个障碍
[(2.0, 5.0), (4.0, 5.0), (3.0, 7.0), (3.0, 6.0), (3.0, 5.0)]
<Event(5-MouseButtonDown {'pos': (166, 207), 'button': 3, 'window': None})>3.0,4.0放置了一个障碍
[(2.0, 5.0), (4.0, 5.0), (3.0, 7.0), (3.0, 6.0), (3.0, 5.0), (3.0, 4.0)]
<Event(5-MouseButtonDown {'pos': (163, 165), 'button': 3, 'window': None})>3.0,3.0放置了一个障碍
[(2.0, 5.0), (4.0, 5.0), (3.0, 7.0), (3.0, 6.0), (3.0, 5.0), (3.0, 4.0), (3.0, 3.0)]
<Event(5-MouseButtonDown {'pos': (164, 85), 'button': 3, 'window': None})>3.0,1.0放置了一个障碍
[(2.0, 5.0), (4.0, 5.0), (3.0, 7.0), (3.0, 6.0), (3.0, 5.0), (3.0, 4.0), (3.0, 3.0), (3.0, 1.0)]
<Event(5-MouseButtonDown {'pos': (165, 40), 'button': 3, 'window': None})>3.0,0.0放置了一个障碍
[(2.0, 5.0), (4.0, 5.0), (3.0, 7.0), (3.0, 6.0), (3.0, 5.0), (3.0, 4.0), (3.0, 3.0), (3.0, 1.0), (3.0, 0.0)]
<Event(5-MouseButtonDown {'pos': (400, 30), 'button': 3, 'window': None})>8.0,0.0放置了一个障碍
[(2.0, 5.0), (4.0, 5.0), (3.0, 7.0), (3.0, 6.0), (3.0, 5.0), (3.0, 4.0), (3.0, 3.0), (3.0, 1.0), (3.0, 0.0), (8.0, 0.0)]
<Event(5-MouseButtonDown {'pos': (399, 64), 'button': 3, 'window': None})>8.0,1.0放置了一个障碍
[(2.0, 5.0), (4.0, 5.0), (3.0, 7.0), (3.0, 6.0), (3.0, 5.0), (3.0, 4.0), (3.0, 3.0), (3.0, 1.0), (3.0, 0.0), (8.0, 0.0), (8.0, 1.0)]
<Event(5-MouseButtonDown {'pos': (407, 124), 'button': 3, 'window': None})>8.0,2.0放置了一个障碍
[(2.0, 5.0), (4.0, 5.0), (3.0, 7.0), (3.0, 6.0), (3.0, 5.0), (3.0, 4.0), (3.0, 3.0), (3.0, 1.0), (3.0, 0.0), (8.0, 0.0), (8.0, 1.0), (8.0, 2.0)]
<Event(5-MouseButtonDown {'pos': (407, 155), 'button': 3, 'window': None})>8.0,3.0放置了一个障碍
[(2.0, 5.0), (4.0, 5.0), (3.0, 7.0), (3.0, 6.0), (3.0, 5.0), (3.0, 4.0), (3.0, 3.0), (3.0, 1.0), (3.0, 0.0), (8.0, 0.0), (8.0, 1.0), (8.0, 2.0), (8.0, 3.0)]
<Event(5-MouseButtonDown {'pos': (410, 306), 'button': 3, 'window': None})>8.0,6.0放置了一个障碍
[(2.0, 5.0), (4.0, 5.0), (3.0, 7.0), (3.0, 6.0), (3.0, 5.0), (3.0, 4.0), (3.0, 3.0), (3.0, 1.0), (3.0, 0.0), (8.0, 0.0), (8.0, 1.0), (8.0, 2.0), (8.0, 3.0), (8.0, 6.0)]
<Event(5-MouseButtonDown {'pos': (413, 370), 'button': 3, 'window': None})>8.0,7.0放置了一个障碍
[(2.0, 5.0), (4.0, 5.0), (3.0, 7.0), (3.0, 6.0), (3.0, 5.0), (3.0, 4.0), (3.0, 3.0), (3.0, 1.0), (3.0, 0.0), (8.0, 0.0), (8.0, 1.0), (8.0, 2.0), (8.0, 3.0), (8.0, 6.0), (8.0, 7.0)]
<Event(5-MouseButtonDown {'pos': (413, 390), 'button': 3, 'window': None})>8.0,8.0放置了一个障碍
[(2.0, 5.0), (4.0, 5.0), (3.0, 7.0), (3.0, 6.0), (3.0, 5.0), (3.0, 4.0), (3.0, 3.0), (3.0, 1.0), (3.0, 0.0), (8.0, 0.0), (8.0, 1.0), (8.0, 2.0), (8.0, 3.0), (8.0, 6.0), (8.0, 7.0), (8.0, 8.0)]
<Event(5-MouseButtonDown {'pos': (413, 451), 'button': 3, 'window': None})>8.0,9.0放置了一个障碍
[(2.0, 5.0), (4.0, 5.0), (3.0, 7.0), (3.0, 6.0), (3.0, 5.0), (3.0, 4.0), (3.0, 3.0), (3.0, 1.0), (3.0, 0.0), (8.0, 0.0), (8.0, 1.0), (8.0, 2.0), (8.0, 3.0), (8.0, 6.0), (8.0, 7.0), (8.0, 8.0), (8.0, 9.0)]
  • 滚动鼠标滚轮,或点击鼠标中键,放置“吸尘器”

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GPhdFSdl-1634544774377)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211009175431441.png)]

<Event(5-MouseButtonDown {'pos': (90, 26), 'button': 5, 'window': None})>1.0,0.0放置了一个扫地机器人

对只有两个方格的吸尘下Agent,可直接定义其Action

# @FileName: Vacuum.py
def vacuum(A_state,B_state,Vacuum_state):
    # print("在初始状态设置中,“0”为干净,“1”为不干净")
    # A_state,B_state = eval(input("A,B方块的初始状态: "))
    # Vacuum_state = str(input("输入吸尘器的初始位置A/B:"))
    performance = 0
    if Vacuum_state == "A":
        if A_state == 0:
            print("方块A是干净的,现移动到方块B")
            print("performance - 1")
            performance -= 1
            if B_state == 0:
                print("方块B是干净的,结束任务")
                print("性能评分为:{}".format(performance))
            else:
                print("方块B不干净,执行动作suck")
                performance += 10
                print("performance + 10")
                print("性能评分为:{}".format(performance))
        else:
            print("方块A不干净,执行动作suck")
            performance += 10
            print("performance + 10")
            print("A干净了,现移动到方块B")
            performance -= 1
            print("performance - 1")
            if B_state == 0:
                print("方块B是干净的,结束任务")
                print("性能评分为:{}".format(performance))
            else:
                print("方块B不干净,执行动作suck")
                performance += 10
                print("performance + 10")

                print("性能评分为:{}".format(performance))

    elif Vacuum_state == "B":
        if B_state == 0:
            print("方块B是干净的,现移动到方块A")
            print("performance - 1")
            performance -= 1
            if A_state == 0:
                print("方块A是干净的,结束任务")
                print("性能评分为:{}".format(performance))
            else:
                print("方块A不干净,执行动作suck")
                performance += 10
                print("performance + 10")
                print("性能评分为:{}".format(performance))
        else:
            print("方块B不干净,执行动作suck")
            performance += 10
            print("performance + 10")
            print("B干净了,现移动到方块A")
            performance -= 1
            print("performance - 1")
            if B_state == 0:
                print("方块A是干净的,结束任务")
                print("性能评分为:{}".format(performance))
            else:
                print("方块A不干净,执行动作suck")
                performance += 10
                print("performance + 10")
                print("性能评分为:{}".format(performance))
    return performance
if __name__ == "__main__":
    performance_vec = []
    performance_add = 0
    Vacuum_state = ["A","B"]
    for str in Vacuum_state:
        for i in range(2):
            for j in range(2):
                print("此时的环境为: |A:{}|B:{}|,吸尘器的初始位置为 {}".format(i,j,str))
                performance = vacuum(i,j,str)
                performance_add += performance
                print("*-------------------------------------*")
                performance_vec.append((i,j,str,performance))
    print("每种情况的评分为:")
    print(performance_vec)
    print("平均评分为: {}".format(performance_add/len(performance_vec)))

直接运行Vacuuma.py文件

python Vacuum.py

此时的环境为: |A:0|B:0|,吸尘器的初始位置为 A
方块A是干净的,现移动到方块B
performance - 1
方块B是干净的,结束任务
性能评分为:-1
*-------------------------------------*
此时的环境为: |A:0|B:1|,吸尘器的初始位置为 A
方块A是干净的,现移动到方块B
performance - 1
方块B不干净,执行动作suck
performance + 10
性能评分为:9
*-------------------------------------*
此时的环境为: |A:1|B:0|,吸尘器的初始位置为 A
方块A不干净,执行动作suck
performance + 10
A干净了,现移动到方块B
performance - 1
方块B是干净的,结束任务
性能评分为:9
*-------------------------------------*
此时的环境为: |A:1|B:1|,吸尘器的初始位置为 A
方块A不干净,执行动作suck
performance + 10
A干净了,现移动到方块B
performance - 1
方块B不干净,执行动作suck
performance + 10
性能评分为:19
*-------------------------------------*
此时的环境为: |A:0|B:0|,吸尘器的初始位置为 B
方块B是干净的,现移动到方块A
performance - 1
方块A是干净的,结束任务
性能评分为:-1
*-------------------------------------*
此时的环境为: |A:0|B:1|,吸尘器的初始位置为 B
方块B不干净,执行动作suck
performance + 10
B干净了,现移动到方块A
performance - 1
方块A不干净,执行动作suck
performance + 10
性能评分为:19
*-------------------------------------*
此时的环境为: |A:1|B:0|,吸尘器的初始位置为 B
方块B是干净的,现移动到方块A
performance - 1
方块A不干净,执行动作suck
performance + 10
性能评分为:9
*-------------------------------------*
此时的环境为: |A:1|B:1|,吸尘器的初始位置为 B
方块B不干净,执行动作suck
performance + 10
B干净了,现移动到方块A
performance - 1
方块A不干净,执行动作suck
performance + 10
性能评分为:19
*-------------------------------------*
每种情况的评分为:
[(0, 0, 'A', -1), (0, 1, 'A', 9), (1, 0, 'A', 9), (1, 1, 'A', 19), (0, 0, 'B', -1), (0, 1, 'B', 19), (1, 0, 'B', 9), (1, 1, 'B', 19)]
平均评分为: 10.25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值