import pygame
from pygame.locals import *
import graphics
import sys
import time
SIZE = 16 #多少条线
UNIT = 35
BORDER_WIDTH = 50 #边框宽度
C_WRITE = (255,255,255)#纯白
C_BLACK = (0,0,0)
screen = None
chess_map = []
his_stack = []#颜色,X,Y坐标,坐标从(0,0)开始
# 获取当前状态
# 0 ~ 未开局
# 1 ~ 等待黑棋落子
# 2 ~ 等待白棋落子
# 3 ~ 结束(一方获胜)
status = 2
winner = 0.
#游戏初始化
def game_init():
pygame.init()
global screen,chess_map,his_stack,sound_black,sound_white,sound_win,\
sound_error
#初始化二维map
#0~无棋子,1~黑旗,-1~白旗
chess_map = [[0 for y in range(0,SIZE)] for x in range(0,SIZE)]
#设置背景显示格式,横是X,竖是Y
screen = pygame.display.set_mode((2*BORDER_WIDTH+UNIT*(SIZE-1),
2*BORDER_WIDTH+UNIT*(SIZE-1)))
#设置标题
pygame.display.set_caption("五子棋")
sy_img = pygame.image.load('img.png')
#(0,0)是对其的坐标
screen.blit(sy_img,(0,0))
# 设置标题
pygame.display.set_caption("五子棋")
sound_black = pygame.mixer.Sound('1.wav')
sound_white = pygame.mixer.Sound('2.wav')
sound_win = pygame.mixer.Sound('3.wav')
sound_error = pygame.mixer.Sound('4.wav')
#绘制棋盘
def draw_map():
#设置字体
s_font= pygame.font.SysFont('arial',16)
#行
for row in range(SIZE):
pygame.draw.line(screen,C_BLACK,
(BORDER_WIDTH,BORDER_WIDTH+UNIT*row),
(BORDER_WIDTH+UNIT*(SIZE-1),BORDER_WIDTH+UNIT*row))
#设置字母下标,ord函数返回ASCII数值
s_surface = s_font.render(chr(ord('A')+row),True,C_BLACK)
screen.blit(s_surface,(BORDER_WIDTH+UNIT*row-4,BORDER_WIDTH-25))
#列
for col in range(SIZE):
pygame.draw.line(screen,C_BLACK,
(BORDER_WIDTH+UNIT*col,BORDER_WIDTH),
(BORDER_WIDTH+UNIT*col,BORDER_WIDTH+UNIT*(SIZE-1)))
s_surface = s_font.render(f'{col}', True, C_BLACK)
screen.blit(s_surface, (BORDER_WIDTH-20, BORDER_WIDTH+UNIT*col-8))
# 判断输赢的算法: 只需要判断当前落子相关的四条直线(横、竖、左斜、右斜),是否形成5个连子。
# 将直线上的落子(黑~ 1,白~ -1),依次相加,连续的子绝对值之和达到5,即可判定为胜利
def __check_winner_():
tmp = 0
last_step = his_stack[-1]
# 竖向直线, x 固定
a=last_step[1]
b=last_step[2]
for y in range(0, SIZE):
# 必须是连续的,last_step[1]为上一步的X坐标
tmp = 0
if abs(chess_map[a][y-1]) > 0:
tmp += abs(chess_map[a][y-1])
if tmp >= 5:
tmp = 0
for x in range(0, SIZE):
# 必须是连续的,last_step[2]为上一步的Y坐标
if abs(chess_map[x-1][b]) > 0:
tmp += abs(chess_map[x-1][b])
if abs(tmp) >= 5:
return last_step[0]
# # 横向直线, y 固定
# tmp = 0
# for x in range(0, SIZE):
# # 必须是连续的,last_step[2]为上一步的Y坐标
# if x > 0 \
# and chess_map[x][b] != chess_map[x - 1][b]:
# tmp = 0
# tmp += chess_map[x][b]
# if abs(tmp) >= 5:
# return last_step[0]
# 右斜直线,计算出左上角顶点的坐标。然后x,y都递增,到达最右下角顶点。
tmp = 0
min_dist = min(last_step[1], last_step[2])
top_point = [last_step[1] - min_dist, last_step[2] - min_dist]
for incr in range(0, SIZE):
# 不能超出棋盘边界
if top_point[0] + incr > SIZE - 1 \
or top_point[1] + incr > SIZE - 1:
break
# 必须是连续的
if incr > 0 \
and chess_map[top_point[0] + incr][top_point[1] + incr] \
!= chess_map[top_point[0] + incr - 1][top_point[1] + incr - 1]:
tmp = 0
tmp += chess_map[top_point[0] + incr][top_point[1] + incr]
if abs(tmp) >= 5:
return last_step[0]
# 左斜直线,计算出右上角顶点的坐标。然后x递减、y递增,到达最左下角顶点。
tmp = 0
min_dist = min(SIZE - 1 - last_step[1], last_step[2])
top_point = [last_step[1] + min_dist, last_step[2] - min_dist]
for incr in range(0, SIZE):
# 不能超出棋盘边界
if top_point[0] - incr < 0 \
or top_point[1] + incr > SIZE - 1:
break
# 必须是连续的
if incr > 0 \
and chess_map[top_point[0] - incr][top_point[1] + incr] \
!= chess_map[top_point[0] - incr + 1][top_point[1] + incr - 1]:
tmp = 0
tmp += chess_map[top_point[0] - incr][top_point[1] + incr]
if abs(tmp) >= 5:
return last_step[0]
return 0
#判断·是否结束
def __check_end():
# global winner
# # 赢了,winner记录谁赢了
winner = __check_winner_()
if winner != 0:
return 1
# 未结束
return 0
def move(pos):
#X,Y不能越界
global status
if pos[0]<BORDER_WIDTH or pos[0]>BORDER_WIDTH+UNIT*(SIZE-1)\
or pos[1]<BORDER_WIDTH or pos[1]>BORDER_WIDTH+UNIT*(SIZE-1):
sound_error.play()
return
x = round((pos[0] - BORDER_WIDTH)/UNIT)
y = round((pos[1] - BORDER_WIDTH) / UNIT)
#已经有棋子
if chess_map[x][y]!= 0:
return
#加音效
if status == 1:
sound_black.play()
else:
sound_white.play()
t = 1 if status == 1 else -1
his_stack.append([t,x,y])
#表示这个位置新加了棋子
chess_map[x][y] = t
status = 2 if status == 1 else 1
pygame.draw.circle(screen, t,
(BORDER_WIDTH + UNIT * x, BORDER_WIDTH + UNIT * y),
int(UNIT / 2.5))
pygame.display.flip()
if __check_end() == 1:
sound_win.play()
time.sleep(3)
sys.exit()
#游戏运行
def game_run():
while True:
for event in pygame.event.get(): #监听用户事件
if event.type == pygame.QUIT: # 判断用户是否点击了关闭按钮
exit()
if event.type == MOUSEBUTTONUP:
move(event.pos)
# 刷新画面
pygame.display.flip()
if __name__== '__main__':
game_init()
draw_map()
game_run()
Python小游戏(附带详细注释)
最新推荐文章于 2024-04-27 21:34:56 发布