象棋小游戏(python)棋子的翻转和移动

源码及资源请前往github获取
如果觉得还不错的话,请赏个 star 呗。

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

继续贴出流程图:
这里写图片描述

从流程图中可以看出,首先判断棋子有没有被选中(鼠标点击位置是否有棋子)
pygame 提供了现成的方法:

def is_chess_clicked(chess_list,event):
    for each in chess_list:
        if (each.rect.collidepoint(event.pos)):#----------------现成的方法
            return each
    return None

如果是 hidden 状态,则进行翻转,翻转之后该棋子状态变为 active,这样翻转就实现了

 elif selected.state == ChessPieces.HIDDEN_STATE:
                            # 翻转
                            selected.state = ChessPieces.ACTIVE_STATE

然后我们来看棋子的移动功能的实现
移动棋子有两个步骤:
1、选中一枚本方棋子(选中之后 select_chess就被赋值了)
2、第二次点击位置没有棋子,并且满足选中棋子的移动规则
棋子的移动规则:
棋子的移动只能向左,向右,向上,向下移动。

 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:
                                # 当前用户点击别人的棋子
                                pass

                        elif selected.state == ChessPieces.HIDDEN_STATE:
                            # 翻转
                            selected.state = ChessPieces.ACTIVE_STATE
                    else:
                        # 本次点击没有点击棋子,只是点击到了棋盘
                        print('本次点击没有点击棋子,只是点击到了棋盘')
                        print(select_chess)

                        if select_chess is not None:
                            # 判断被选中的棋子是否可以移动到当前位置
                            if select_chess.move(event.pos):
                                select_chess=None #------------------- 如果成功发生了移动,则该轮操作完成

棋子是否可以移动到鼠标点击的当前位置,怎么来判断呢?
思路如下:
这里写图片描述
如果鼠标点击位置在对应的区域内,就修改选中对象的位置,这样就实现了棋子的移动。

    def move(self,pos):
        return can_move_one_step(self,pos)
	
	def can_move_one_step(self,pos):
    # 首先判断移动方向,然后进行移动
    # 判断移动方向
    # 判断是否在棋盘之内
    if pos[0] < 80 or pos[0] > 399 or pos[1] < 63 or pos[1] > 596:
        print("点击超出了范围")
    elif self.rect.left - 90 < pos[0] < self.rect.left - 50 and self.rect.top < pos[1] < self.rect.top + 50:
        # 需要向左移动一位
        self.rect.left -= 90
        print('需要向左移动一位')
        return True
    elif self.rect.left < pos[0] < self.rect.left + 40 and self.rect.top - 70 < pos[1] < self.rect.top - 40:
        # 需要向上移动一位
        self.rect.top -= 71
        print('需要向上移动一位')
        return True
    elif self.rect.left + 90 < pos[0] < self.rect.left + 130 and self.rect.top < pos[1] < self.rect.top + 40:
        # 需要向右移动一位
        self.rect.left += 90
        print('需要向右移动一位')
        return True
    elif self.rect.left < pos[0] < self.rect.left + 40 and self.rect.top + 70 < pos[1] < self.rect.top + 110:
        # 需要向下移动一位
        self.rect.top += 71
        print('需要向下移动一位')
        return True

这款小游戏是一个双人对战的游戏,那总有一个标志来决定每一方玩家行为的开始和结束。再通俗点儿,就是什么标志着行为的开始,那些标志着行为的结束(交接)。思考之后,大概是以下三种情况:

  • 翻牌完毕
  • 棋子移动完毕
  • 棋子吃子完毕

注意,都是要完毕,意味着三个动作必须有一个动作完成才能交接,我这儿使用 selelct_chess 变量来判定
select_chess 存储的是要移动或要去吃子的棋子,一旦一个动作完成,我们就将 sellect_chess 置为 None。

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
          
# 判断被选中的棋子是否可以移动到当前位置
if select_chess.move(event.pos):
    operation_completed()
    select_chess=None
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python国际象棋小游戏代码可以通过各种方式实现。这里提供一种简单的实现方式: ``` class ChessGame: def __init__(self): self.board = [ ["R", "N", "B", "Q", "K", "B", "N", "R"], ["P", "P", "P", "P", "P", "P", "P", "P"], [" ", ".", " ", ".", " ", ".", " ", "."], [".", " ", ".", " ", ".", " ", ".", " "], [" ", ".", " ", ".", " ", ".", " ", "."], [".", " ", ".", " ", ".", " ", ".", " "], ["p", "p", "p", "p", "p", "p", "p", "p"], ["r", "n", "b", "q", "k", "b", "n", "r"] ] self.current_player = 0 self.game_over = False def play(self, start, end): x1, y1 = start x2, y2 = end piece = self.board[x1][y1] if piece == ' ' or piece == '.': return False if (piece.islower() and self.current_player == 0) or (piece.isupper() and self.current_player == 1): return False if piece.lower() == 'p' and x2 == x1 + 2 and y1 == y2: if self.board[x1 + 1][y1] != ' ': return False if piece.lower() == 'p' and x2 == x1 + 1 and abs(y2 - y1) == 1: if self.board[x2][y2] == ' ': return False if piece.lower() == 'p' and x2 == x1 + 1 and y2 == y1: if self.board[x2][y2] != ' ': return False if piece.lower() == 'r' and x1 != x2 and y1 != y2: return False if piece.lower() == 'n' and not ((abs(x2 - x1) == 2 and abs(y2 - y1) == 1) or (abs(x2 - x1) == 1 and abs(y2 - y1) == 2)): return False if piece.lower() == 'b' and abs(x2 - x1) != abs(y2 - y1): return False if piece.lower() == 'q' and not ((x1 == x2 or y1 == y2) or (abs(x2 - x1) == abs(y2 - y1))): return False if piece.lower() == 'k' and not ((abs(x2 - x1) <= 1) and (abs(y2 - y1) <= 1)): return False self.board[x2][y2] = self.board[x1][y1] self.board[x1][y1] = ' ' self.current_player = 1 - self.current_player return True def print_board(self): print(" A B C D E F G H ") print(" +--+") for i in range(8): print(str(8-i) + " | ", end="") for j in range(8): print(self.board[i][j] + " ", end="") print("| " + str(8-i)) print(" +---------------+") print(" A B C D E F G H ") def check_game_over(self): kings = [] for i in range(8): for j in range(8): if self.board[i][j].lower() == 'k': kings.append((i, j)) for king in kings: x, y = king for i in range(max(0, x-1), min(8, x+2)): for j in range(max(0, y-1), min(8, y+2)): if i != x or j != y: if self.board[i][j] == ' ' or self.board[i][j].isupper() == self.board[x][y].isupper(): continue if self.check_move_valid((x, y), (i, j)): return False self.game_over = True return True def check_move_valid(self, start, end): copy_board = [row[:] for row in self.board] copy_game = ChessGame() copy_game.board = copy_board copy_game.current_player = self.current_player return copy_game.play(start, end) game = ChessGame() while not game.game_over: game.print_board() player = game.current_player + 1 start = input("Player {} move: ".format(player)) end = input("to: ") x1, y1 = ord(start) - ord('A'), 8 - int(start[1]) x2, y2 = ord(end) - ord('A'), 8 - int(end) valid_move = game.check_move_valid((x1, y1), (x2, y2)) while not valid_move: print("Invalid move!") start = input("Player {} move: ".format(player)) end = input("to: ") x1, y1 = ord(start) - ord('A'), 8 - int(start) x2, y2 = ord(end) - ord('A'), 8 - int(end) valid_move = game.check_move_valid((x1, y1), (x2, y2)) game.play((x1, y1), (x2, y2)) game.check_game_over() print("Game over!") ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值