使用pygame实现的五子棋,状态机, 估值函数

本文介绍了使用pygame库开发的五子棋游戏,包括人机对弈和机机对弈功能。通过状态机设计,程序实现了游戏对象的有效管理,同时采用估值函数评估棋盘局势。主要涉及状态类、状态机类、世界类和游戏实体类等关键组件。文章还展示了部分核心代码和资源链接。
摘要由CSDN通过智能技术生成
成果展示

首先展示一下程序的成果,最后的画面会是这个模样:
Alt
。。。右边的两颗一黑一白的棋子比较调皮,它会动。


主要功能

主要实现了人机对弈,机机对弈(手动改几行注释就可以了),利用Pygame绘制游戏界面,运用了状态机, 估值函数。 由于状态机的运用,使得所有对象都可以被一个对象管理,方便了程序的扩展,只需要添加状态和创建实体类,就可以增加新的模块与功能。


程序的架构

这个程序文件包括了主要有以下类:
包含14个类与一个运行函数
———————————————————————————

重要的类

按理来说,只要具备了以下四个类,就可以按照这个框架写出所有游戏。。。
只是我说说而已,有待百度。

状态类

该类是虚类,实体的状态类需要继承它
状态 <- 是实体类的成员,该对象描述某个具体的实体类状态,以及在该状态下会做些什么,做之前要有什么准备工作,做完了怎么退出动作,怎么改变状态。比如一个智能棋手有一个下棋状态,、、、

# 状态
class State(object):
    def __init__(self, name):
        self.name = name

    # 执行动作
    def do_actions(self):
        pass

    # 检测外界条件
    def check_conditions(self):
        pass

    # 进入动作
    def entry_actions(self):
        pass

    # 退出动作
    def exit_actions(self):
        pass
状态机类

该类对状态进行统一管理
状态机 <- 是实体类的成员,它是实体类的大脑,管理着实体类的所有状态,以及状态间的转换(哪个状态是激活态)

# 状态机
class StateMachine(object):
    def __init__(self):
        self.states = {}
        self.active_state = None

    # 添加状态
    def add_state(self, state):
        self.states[state.name] = state

    # 决策(思考)
    def think(self):
        if self.active_state is None:
            return
        self.active_state.do_actions()
        new_state_name = self.active_state.check_conditions()
        if new_state_name is not None and new_state_name is not self.active_state:
            self.set_state(new_state_name)

    # 设置活动状态
    def set_state(self, new_state_name):
        if self.active_state is not None:
            self.active_state.exit_actions()
        self.active_state = self.states[new_state_name]
        self.active_state.entry_actions()
世界类

管理所有实体类对象
世界 <- 所有对象由它来处理,实体对象必须被它管理才能发挥作用。。。

# 世界类
class World(object):
    def __init__(self):
        self.entities = {}
        self.entity_id = 0
        self.update_time = 0
        self.is_over = False	# 游戏结束
        self.playing = False	#游戏正在进行
        # 下面两句本不应该出现在这里,应该是出现在某个实体类中的,。。。。
        # 谁叫我比较懒。。。。。破坏了代码的美感,应该干掉,,,谁有兴趣就做做吧,,
        self.background = pygame.surface.Surface(SCREEN_SIZE).convert()
        self.background.blit(pygame.image.load(CHESS_BOX).convert_alpha(), (0, 0))

    # 添加实体
    def add_entity(self, entity):
        self.entities[self.entity_id] = entity
        entity.id = self.entity_id
        self.entity_id += 1

    # 移除实体
    def remove_entity(self, entity):
        del self.entities[entity.id]

    # 获取实体
    def get(self, entity_id):
        if entity_id in self.entities:
            return self.entities[entity_id]
        else:
            return None

    # 处理各个实体
    def process(self, time_passed):
        time_passed_seconds = time_passed / 1000.0
        for entity in list(self.entities.values()):
            entity.process(time_passed_seconds)

    # 绘图
    def render(self, surface, current_time):
        if self.update_time < current_time:
            surface.blit(self.background, (0, 0))
            for entity in list(self.entities.values()):
                entity.render(surface)
            self.update_time = current_time + 30

    # 得到接近的实体
    def get_close_entity(self, name, location, range=10.):
        location = Vector2(*location)
        for entity in list(self.entities.values()):
            if entity.name == name:
                distance = location.get_distance_to(entity.location)
                if distance < range:
                    return entity
        return None
游戏实体类

该类需要被其它具有实际意义的实体类继承
实体类 <- 描述了一个实体,比如:一个智能棋手类,一个棋子, ,,,

# 游戏实体类
class GameEntity(object):

    def __init__(self, world, name, image=None):

        self.world = world
        self.name = name
        self.image = image
        self.location = Vector2(0, 0)
        self.destination = Vector2(0, 0)
        self.speed = 0.
        self.brain = StateMachine()
        self.id = 0

    # 绘图
    def render(self, surface):
        if self.image is None:
            return
        x, y = self.location
        w, h = self.image.get_size()
        surface.blit(self.image, (x-w/2, y-h/2))

    # 处理实体对象
    def process(self, time_passed):
        self.brain.think()
        if self.speed > 0. and self.location != self.destination:
            vec_to_destination = self.destination - self.location
            distance_to_destination = vec_to_destination.get_length()
            heading = vec_to_destination.get_normalized()
            travel_distance = min(distance_to_destination, time_passed * self.speed)
            self.location += travel_distance * heading


———————————————————————————

不那么重要的类,但对于这个五子棋来说,就是核心类

这里放一个大概,后面会给出全部代码

棋子类

GameEntity的子类

# 棋子类
class Chessman(GameEntity):
    def __init__(self, world, image):
        GameEntity.__init__(self, world, "Chessman", image)
棋盘局势类

棋盘局势 <- 整个棋盘的局势走向

# 棋盘局势
class ChessBoxSituations(object):
    def __init__(self, size=(19, 19)):
        self.size = size
        self.situations = {}		#棋盘局势(棋子在棋盘的点集)
        self.last_drop_position = (0, 0)
        self.current_drop_player = 0
        self.count = 0

    # 局势发展(棋子增加)
    def evolve(self, chessman_point, owner):
        self.situations[chessman_point] = owner
        self.last_drop_position = chessman_point
        self.count += 1

    # 获取棋盘某点坐标的状态
    def get_state(self, point):
        px, py = point
        x, y = self.size
        if x - px < 0 or y - py < 0 or x - px >= 19 or y - py >= 19:
            return self.OutOfRange()
        if point not in self.situations:
            return None
        return self.situations[point]

    class OutOfRange(object):
        pass
智能体棋手类

对战的AI

附:

# 八个方向 N:北, E:东, S:南, W:西
D_N = Vector2(0, -1)
D_EN = Vector2(1, -1)
D_E = Vector2(1, 0)
D_ES = Vector2(1, 1)
D_S = Vector2(0, 1)
D_WS = Vector2(-1, 1)
D_W = Vector2(-1, 0)
D_WN = Vector2(-1, -1)
DIRECTION = (D_N, D_EN, D_E, D_ES, D_S, D_WS, D_W, D_WN)
# 智能体棋手类
class PlayerAgent(GameEntity):
    def __init__(self, world, box_situations, chess_image, no=1, opponent=0):
        GameEntity.__init__(self, world, "PlayerAgent")
        self.no = no	#自己
        self.opponent = opponent	#对手
        self.box_situations = box_situations
        self.chess_image = chess_image
        self.drop_points = []	# 可选的将要下的棋子位点
        self.points_weight = 0	# drop_points里的点的权重(里面所有点权重相同)
        wait_state = PlayerAgentStateWait(self)
        drop_state = PlayerAgentStateDrop(self)
        self.brain.add_state(drop_state)
        self.brain.add_state(wait_state)

    # 更新下棋点集
    def update_drop_points(self, location, weight):
        if self.points_weight < weight:
            self.drop_points.clear()
            self.drop_points.append(location)
            self.points_weight = weight

        elif self.points_weight == weight:
            self.drop_points.append(location)

    # 决策(获取下棋位置)
    def decision_making(self):
        self.points_weight = 0
        self.drop_points.clear()
        filter_point = []

        # 棋盘上所有的有棋子的点
        for point in self.box_situations.situations:

            # 获取该点的相邻八个点的空位点
            for DIR in DIRECTION:
                cur_point = point+DIR
                x, y = cur_point
                if self.box_situations.get_state((x, y)) is None:
                    if cu
  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值