流程圖依舊需要:
喫子的條件是啥呢?
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))