龙空技术网

python实现五子棋游戏(pygame版)

东少笔记 163

前言:

目前姐妹们对“python棋盘游戏”大体比较注意,看官们都想要知道一些“python棋盘游戏”的相关内容。那么小编同时在网摘上收集了一些关于“python棋盘游戏””的相关文章,希望大家能喜欢,你们快快来学习一下吧!

前言简介

使用python实现pygame版的五子棋游戏;

环境:Windows系统+python3.8.0

游戏规则:

1、分两位棋手对战,默认黑棋先下;当在棋盘点击左键,即在该位置绘制黑棋;

2、自动切换到白棋,当在棋盘点击左键,即在该位置绘制白棋;

3、轮流切换棋手下棋,当那方先形成5子连线者获胜(横、竖、斜、反斜四个方向都可以)。

游戏运行效果如下:

实现过程

1、新建文件settings.py,用来定义一些必须的基本属性和初始值;

class Settings():def __init__(self):"""初始化的游戏配置"""# 屏幕宽高self.width = 700self.height = 554# 文字颜色和大小self.fontsize = 14self.fonttype = 'simsunnsimsun'# 棋盘格数self.number = 15# 棋盘左边距、上边距和间隔self.bd_left = 30self.bd_top = 30self.bd_space = 36# 判断游戏是否结束(默认开始)self.game_active = True# 判断哪方下棋(默认黑子先写)self.chess_player = 1self.prompt_info = '当前棋手:黑棋'# 开始校验输赢(两边合计9,因为已经有一边5步)self.win_number = 0# 设置背景图、黑棋图片、白棋图片路径self.checkerboard_bg = 'images/checkerboard_bg.png'self.black_chess = 'images/black_chess.png'self.white_chess = 'images/white_chess.png'# 存储落子数据self.move_chess = []

2、新建文件checkerboard.py,主要用来绘制背景图和网格线;

import sysimport pygameclass Checkerboard():  def __init__(self, ck_settings, screen, position):    self.ck_settings = ck_settings    self.screen = screen    self.position = position    # 颜色和坐标大小    self.text_color = (0, 0, 0)    self.font = pygame.font.SysFont(ck_settings.fonttype, ck_settings.fontsize)    # 存储棋子坐标    self.checkerboard = []    # 加载背景图、黑棋和白棋(当有图片不存在时,打印错误并退出游戏)    try:      self.bg_image = pygame.image.load(ck_settings.checkerboard_bg)          self.black_image = pygame.image.load(ck_settings.black_chess).convert_alpha() # convert_alpha背景透明      self.white_image = pygame.image.load(ck_settings.white_chess).convert_alpha()      self.chess_rect = self.black_image.get_rect()    except Exception as e:      print('error:', e)      sys.exit()  def draw_board(self):        # 存储棋子坐标        for i in range(self.ck_settings.number):      self.checkerboard.append([])      for j in range(self.ck_settings.number):        self.checkerboard[i].append(self.position(self.ck_settings.bd_left + i * self.ck_settings.bd_space, self.ck_settings.bd_top + j * self.ck_settings.bd_space))    # 绘制棋盘坐标    for i in range(0, self.ck_settings.number):      # ord返回字符的ASCII数值,chr再返回字符      x_text = self.font.render(chr(ord('A') + i), True, self.text_color) # A-O      y_text = self.font.render(str(i + 1), True, self.text_color) # 1-15      # 绘制xy轴坐标(在棋盘背景图绘制)      self.bg_image.blit(x_text, (self.checkerboard[i][0].x - x_text.get_width() / 2, self.checkerboard[i][0].y - 20))      self.bg_image.blit(y_text, (self.checkerboard[0][i].x - 20, self.checkerboard[0][i].y - y_text.get_height() / 2))      # 绘制横竖线(在棋盘背景图绘制)      pygame.draw.line(self.bg_image, self.text_color, self.checkerboard[0][i], self.checkerboard[self.ck_settings.number-1][i])      pygame.draw.line(self.bg_image, self.text_color, self.checkerboard[i][0], self.checkerboard[i][self.ck_settings.number-1])    # 绘制棋盘背景图    self.screen.blit(self.bg_image, (0, 0))

3、新建文件infopanel.py,主要用来绘制棋盘右边提示信息(暂时只有显示下棋方和获胜信息);

import pygame.fontclass Infopanel():  def __init__(self, ck_settings, screen):    """初始化属性"""    self.settings = ck_settings    self.screen = screen    self.screen_rect = screen.get_rect()    # 设置文字颜色和字体大小    self.info_color = (217, 8, 10)    self.font = pygame.font.SysFont(ck_settings.fonttype, 16)  def draw_info(self, info):    """将文字渲染为图像,并定位到右边水平居中"""    self.info_image = self.font.render(info, True, self.info_color)    self.info_image_rect = self.info_image.get_rect()    self.info_image_rect.right = self.screen_rect.right - (self.screen_rect.width - 536 - self.info_image_rect.width) / 2    self.info_image_rect.top = 50    # 绘制到屏幕    self.screen.blit(self.info_image, self.info_image_rect)

4.新建文件“game_functions.py”,存放跟游戏有关的所有业务逻辑函数;

import sysimport pygame# 棋def update_board(ck_settings, cb, index_coordinates, position):  """更新棋盘信息"""  # 判断棋手(黑棋或白棋)  if ck_settings.chess_player == 1:    ck_settings.prompt_info = '当前棋手:白棋'    img = cb.black_image    chess_type = 'black'  else:    ck_settings.prompt_info = '当前棋手:黑棋'    img = cb.white_image    chess_type = 'white'  """落棋"""  dropState = check_at(ck_settings, index_coordinates)  if dropState:    i, j = index_coordinates    chess_x = cb.checkerboard[j][i].x - cb.chess_rect.width / 2    chess_y = cb.checkerboard[j][i].y - cb.chess_rect.height / 2    # 累计步数(两边合计)    ck_settings.win_number += 1    # 落子并转换棋手    ck_settings.move_chess.append({'type': chess_type, 'coord': position(i, j)})    cb.bg_image.blit(img, (chess_x, chess_y))    ck_settings.chess_player *= -1    # 合计9步开始校验输赢    if ck_settings.win_number >= 9:      check_stats(ck_settings, (i, j))        else:    ck_settings.prompt_info = '已经有其他棋子'# 检查(i,j)位置是否已占用  def check_at(ck_settings, index_coordinates):  for item in ck_settings.move_chess:    if index_coordinates == item['coord']:      return False  return Truedef check_stats(ck_settings, pos):  """校验四个方向,是否有了输赢"""  pos_i, pos_j = pos  directs = [(1, 0), (0, 1), (1, 1), (1, -1)]  # 横、竖、斜、反斜 四个方向检查    for direct in directs:    line_checkerboard = []    d_x, d_y = direct    last = ck_settings.move_chess[-1]    line_ball = []  # 存放在一条线上的棋子    for ball in ck_settings.move_chess:      # 跟最后落子判断      if ball['type'] == last['type']:        x = ball['coord'].x - last['coord'].x        y = ball['coord'].y - last['coord'].y        if d_x == 0:          if x == 0:            line_ball.append(ball['coord'])        if d_y == 0:          if y == 0:            line_ball.append(ball['coord'])        if x * d_y == y * d_x:          line_ball.append(ball['coord'])    if len(line_ball) >= 5:  # 只有5子及以上才继续判断      sorted_line = sorted(line_ball)      for i, item in enumerate(sorted_line):        index = i + 4        if index < len(sorted_line):          if d_x == 0:            y1 = item.y            y2 = sorted_line[index].y            # 此点和第5个点比较y值,如相差为4则连成5子            if abs(y1 - y2) == 4:              ck_settings.prompt_info = '黑棋获胜' if last['type'] == 'black' else '白棋获胜'          else:            x1 = item.x            x2 = sorted_line[index].x            # 此点和第5个点比较x值,如相差为4则连成5子            if abs(x1 - x2) == 4:              ck_settings.prompt_info = '黑棋获胜' if last['type'] == 'black' else '白棋获胜'        else:          break# 事件def check_events(ck_settings, cb, position):  """监听事件"""  for event in pygame.event.get():    if event.type == pygame.QUIT:      sys.exit()    elif event.type == pygame.MOUSEBUTTONDOWN:      # 点击左键      if event.button == 1:        pos = pygame.mouse.get_pos() # 获取点击实际坐标        # 判断是否溢出        x_first = cb.checkerboard[0][0].x        x_last = cb.checkerboard[ck_settings.number - 1][ck_settings.number - 1].x        y_first = cb.checkerboard[0][0].y        y_last = cb.checkerboard[ck_settings.number - 1][ck_settings.number - 1].y        if pos[0] < x_first or pos[0] > x_last or pos[1] < y_first or pos[1] > y_last:          ck_settings.prompt_info = '落子位置不正确!'        else:          index_coordinates = to_index(ck_settings, pos)          update_board(ck_settings, cb, index_coordinates, position)def to_index(ck_settings, pos):  """实际坐标转换为棋盘下标"""  i = round((pos[1] - ck_settings.bd_top) / ck_settings.bd_space)  j = round((pos[0] - ck_settings.bd_left) / ck_settings.bd_space)  return (i, j)

5、新建文件gobang.py,主函数用来初始化程序,并同步更新程序的信息;

import pygamefrom settings import Settingsfrom checkerboard import Checkerboardfrom collections import namedtupleimport game_functions as gffrom infopanel import Infopaneldef run_game():  """运行游戏"""  # 初始化游戏屏幕  pygame.init()  # 创建时钟对象 (可以控制游戏循环频率)  clock = pygame.time.Clock()  # 配置实例化  ck_settings = Settings()    screen = pygame.display.set_mode((ck_settings.width, ck_settings.height))  pygame.display.set_caption('五子棋游戏')  # namedtuple创建类似于元组的数据类型,除了可以用索引访问,能够迭代,还能用属性名访问数据  position = namedtuple('Position', ['x', 'y'])  # 创建实例  cb = Checkerboard(ck_settings, screen, position)  # 实例化面板信息  infopanel = Infopanel(ck_settings, screen)  while ck_settings.game_active:    # 绘制棋盘    cb.draw_board()    # 绘制面板信息    infopanel.draw_info(ck_settings.prompt_info)    # 检查玩家事件并更新棋盘    gf.check_events(ck_settings, cb, position)    # 让最近绘制的屏幕可见    pygame.display.flip()    # 通过时钟对象指定循环频率    clock.tick(60) # 每秒循环60次run_game()

6、在文件gobang.py目录路径下,执行命令“python gobang.py”弹出窗口,即可对其操作游玩。

结语

该游戏只是实现了基础功能,还有很多可优化的功能:

1、根据实际情况加上更详细的面板信息(比如倒计时等);

2、加上开始游戏按钮,可参考前面python实例;

3、胜负榜单等,可参考前面python实例。

标签: #python棋盘游戏 #pythonpygame教程 #window自带的五字棋在哪个开始程序