编写五子棋的完整python代码_python实现五子棋游戏(pygame版)

本文实例为大家分享了python五子棋游戏的具体代码,供大家参考,具体内容如下

目录

简介

实现过程

结语

简介

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

环境:Windows系统+python3.8.0

游戏规则:

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

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

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

游戏运行效果如下:

2020119100520333.gif

实现过程

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

class Settings():

def __init__(self):

"""初始化的游戏配置"""

# 屏幕宽高

self.width = 700

self.height = 554

# 文字颜色和大小

self.fontsize = 14

self.fonttype = 'simsunnsimsun'

# 棋盘格数

self.number = 15

# 棋盘左边距、上边距和间隔

self.bd_left = 30

self.bd_top = 30

self.bd_space = 36

# 判断游戏是否结束(默认开始)

self.game_active = True

# 判断哪方下棋(默认黑子先写)

self.chess_player = 1

self.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 sys

import pygame

class 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.font

class 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 sys

import 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 True

def 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 pygame

from settings import Settings

from checkerboard import Checkerboard

from collections import namedtuple

import game_functions as gf

from infopanel import Infopanel

def 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博客。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的五子棋程序的Python实现代码中包括了游戏界面的绘制、游戏规则的判定和AI的实现。 ```python import pygame import random # 初始化游戏 pygame.init() # 设置游戏界面大小 SIZE = width, height = 650, 650 # 设置窗口标题 pygame.display.set_caption("五子棋") # 设置游戏界面背景色 background_color = (249, 214, 91) # 设置棋盘大小 board_size = 15 # 设置棋子大小 piece_size = 40 # 设置棋子颜色 BLACK = (0, 0, 0) WHITE = (255, 255, 255) # 创建游戏界面 screen = pygame.display.set_mode(SIZE) # 创建棋盘 board = [[0 for i in range(board_size)] for j in range(board_size)] # 初始化游戏状态 game_over = False winner = None # 绘制棋盘 def draw_board(): for i in range(board_size): pygame.draw.line(screen, BLACK, [piece_size // 2, piece_size // 2 + i * piece_size], [piece_size // 2 + (board_size - 1) * piece_size, piece_size // 2 + i * piece_size], 2) pygame.draw.line(screen, BLACK, [piece_size // 2 + i * piece_size, piece_size // 2], [piece_size // 2 + i * piece_size, piece_size // 2 + (board_size - 1) * piece_size], 2) # 绘制棋子 def draw_piece(row, col, color): pygame.draw.circle(screen, color, [(col+1)*piece_size, (row+1)*piece_size], piece_size//2-2) # 判断是否胜利 def check_win(row, col, color): # 水平方向 count = 1 for i in range(1, 5): if col+i >= board_size or board[row][col+i] != color: break count += 1 for i in range(1, 5): if col-i < 0 or board[row][col-i] != color: break count += 1 if count >= 5: return True # 垂直方向 count = 1 for i in range(1, 5): if row+i >= board_size or board[row+i][col] != color: break count += 1 for i in range(1, 5): if row-i < 0 or board[row-i][col] != color: break count += 1 if count >= 5: return True # 对角线方向 count = 1 for i in range(1, 5): if row+i >= board_size or col+i >= board_size or board[row+i][col+i] != color: break count += 1 for i in range(1, 5): if row-i < 0 or col-i < 0 or board[row-i][col-i] != color: break count += 1 if count >= 5: return True # 反对角线方向 count = 1 for i in range(1, 5): if row+i >= board_size or col-i < 0 or board[row+i][col-i] != color: break count += 1 for i in range(1, 5): if row-i < 0 or col+i >= board_size or board[row-i][col+i] != color: break count += 1 if count >= 5: return True return False # AI下棋 def ai_move(): empty_list = [] for i in range(board_size): for j in range(board_size): if board[i][j] == 0: empty_list.append((i, j)) if empty_list: return random.choice(empty_list) else: return None # 游戏循环 while not game_over: # 处理事件 for event in pygame.event.get(): if event.type == pygame.QUIT: game_over = True elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: if winner is None: x, y = event.pos row = y // piece_size - 1 col = x // piece_size - 1 if row >= 0 and row < board_size and col >= 0 and col < board_size and board[row][col] == 0: draw_piece(row, col, BLACK) board[row][col] = 1 if check_win(row, col, 1): winner = "黑方" else: move = ai_move() if move is not None: row, col = move draw_piece(row, col, WHITE) board[row][col] = 2 if check_win(row, col, 2): winner = "白方" else: winner = "平局" # 绘制界面 screen.fill(background_color) draw_board() for i in range(board_size): for j in range(board_size): if board[i][j] == 1: draw_piece(i, j, BLACK) elif board[i][j] == 2: draw_piece(i, j, WHITE) if winner is not None: font = pygame.font.Font(None, 36) text = font.render(winner + "胜利!", True, BLACK) screen.blit(text, ((width - text.get_width()) // 2, (height - text.get_height()) // 2)) # 更新界面 pygame.display.update() # 退出游戏 pygame.quit() ``` 这个程序实现了一个基本的五子棋游戏,包括了游戏界面的绘制、游戏规则的判定和AI的实现。用户可以通过鼠标点击来下棋,游戏界面会实时更新棋局情况,并在胜利时显示胜者信息。AI的实现比较简单,只是随机选择一个空位置落子,没有使用任何高级算法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值