象棋小遊戲(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))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章