象棋小游戏(pygame)吃子判赢

点击查看象棋小游戏系列目录导航

这里写图片描述

流程图依旧需要:
吃子的条件是啥呢?
1、当前自己的棋子有被选中(select_chess 不为空)·
2、鼠标点击了对方的棋子
3、按照吃子规则,对方的棋子可吃
4、按照吃子规则,对方的棋子在位置上可以被吃。

第四条进一步解释:
这里写图片描述

比如说,车只能吃与它相邻的上下左右的对方棋子,不能吃斜角或其它位置的棋子,这就是位置上可以被吃。

 if event.type == MOUSEBUTTONDOWN:
                if event.button == 1:# 按下鼠标左键
                    #print(event.pos)
                    selected = is_chess_clicked(chess_list,event)
                    #print(selected)
                    if selected is not None:
                        # 本次点击点击到了棋子
                        if selected.state == ChessPieces.CHOOSED_STATE:
                            pass
                        elif selected.state == ChessPieces.ACTIVE_STATE:
                            if player_role == selected.role:
                                # 当前用户点击自己的棋子
                                # 重复点击了多次自己的某一个棋子
                                # 或例子:
                                # 先点击了自己的车,又点击了自己的马
                                select_chess = selected
                                selected.state = ChessPieces.ACTIVE_STATE
                            else:
                                # 当前用户点击别人的棋子
                                # 选定自己要吃的对方的子
                                if select_chess is not None:
                                    # 判断是否可以吃该子
                                    if select_chess.eat(selected,event.pos,chess_list):
                                        select_chess = None
    #  ‘将’ 可以吃 其它所有
    # 是否可吃需要满足两个条件
    # 1、是否满足该子的行走规律
    # 2、是否满足该子的吃子规律
    def eat(self,enemy_chess,pos,chess_list):
        if can_eat(self.type,enemy_chess.type):
            # 吃子规则判断可吃
            if self.move(pos):
                # 将select_chess 移动到选定位置
                # 并将被吃子状态修改为死亡状态
                self.rect.left = enemy_chess.rect.left
                self.rect.top = enemy_chess.rect.top
                enemy_chess.state = DEAD_STATE
                return True
            else:
                print('点击位置不在范围内,无法吃子')
        return False
# 吃子规则
# 这个规则我们可以自己随便写
# 我的规则是 值大的可以吃值小的 兵可以吃将,炮可以吃全部,不过炮翻山才可以吃

JIANG_TYPE = 11
SHI_TYPE = 12
XIANG_TYPE = 13
CHE_TYPE = 14
MA_TYPE = 15
PAO_TYPE = 16
ZU_TYPE = 17

def can_eat(typea,typeb):
    if typea in (JIANG_TYPE,PAO_TYPE):
        return True
    elif typea in (SHI_TYPE,XIANG_TYPE,MA_TYPE,CHE_TYPE):
        if typea <= typeb:
            return True
    elif typea == ZU_TYPE:
        if typeb == JIANG_TYPE or typeb == ZU_TYPE:
            return True
    return False

那我们有不同的吃子的方法,那我们就可以修改它对应的 move 方法,比如说 ‘炮’、

    def eat(self,enemy_chess,pos,chess_list):
        if can_eat(self.type,enemy_chess.type):
            if self.can_move_and_eat(enemy_chess,pos,chess_list):
                self.rect.left = enemy_chess.rect.left
                self.rect.top = enemy_chess.rect.top
                enemy_chess.state = DEAD_STATE
                enemy_chess.rect.left = -100
                enemy_chess.rect.top = -100
                return True
            else:
                print('点击位置不在范围内,无法吃子')
        return False

    def can_move_and_eat(self,enemy_chess,pos,chess_list):
        # 首先判断,pos 和当前棋子是否在同一行或同一列
        # 然后判断,两个棋子之间有几个棋子
        if self.rect.left -10 < enemy_chess.rect.left < self.rect.left + 50:
            # 说明在同一列
            count = 0
            for each in chess_list:
                if self.rect.left -10 < each.rect.left < self.rect.left + 50 \
                        and min(self.rect.center[1],enemy_chess.rect.center[1]) < \
                        each.rect.center[1] < max(self.rect.center[1],enemy_chess.rect.center[1]):
                    count+=1
            if count==1:
                return True
        elif self.rect.top -10 < enemy_chess.rect.top < self.rect.top +50:
            # 说明在同一行
            count = 0
            for each in chess_list:
                if self.rect.top -10 < each.rect.top < self.rect.top +50 and \
                        min(self.rect.center[0], enemy_chess.rect.center[0]) < \
                            each.rect.center[0] < max(self.rect.center[0], enemy_chess.rect.center[0]):
                    count += 1
            if count==1:
                return True
        return False

这一块,主要是炮翻山吃子的验证方法,看图:
这里写图片描述

验证横坐标在 x 范围内,纵坐标在 y 范围内,并且棋子状态为 Active 的棋子个数,如果只有一个,那就构成炮翻山的条件,否则无法吃子。

添加判赢机制
那么,怎么样才算赢呢?当棋盘上某方的状态为 active 的棋子为 0 的时候,就有一方获胜了。

 # 判断游戏是否结束
        # 方法,计算棋盘上存活的棋子数量,如果为零就,停止
        black_count = 0
        red_count = 0
        for each in chess_list:
            # 这个地方
            if each.state == ChessPieces.ACTIVE_STATE or each.state == ChessPieces.HIDDEN_STATE:
                if each.role == ChessPieces.BLACK_ROLE:
                    black_count +=1
                else:
                    red_count+=1

        if black_count == 0:
            # 红方胜利
            draw_text('红方胜利!',RED,(width//2,height//2))
        elif red_count ==0:
            # 黑方胜利
            draw_text('黑方胜利',BLACK,(width//2,height//2))

猜你喜欢

转载自blog.csdn.net/chenxiaoping1993/article/details/80194470