You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
python/Design Five-in-a-row With P...

188 lines
7.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import pygame,sys #导入pygame和sys模块
from pygame.locals import * #导入pygame.locals模块中的常量变量
pygame.init() #要让众多pygame函数能够工作需要先调用这个函数
WINDOWWIDTH=1000 #颜色
WINDOWHEIGHT=700
BLACK=(50,50,50)
SENIORASH=(143,143,143)
TEXTCOLOR=(0,0,0)
FPS=60 #frames per second setting
space = 20 # 四周留下的边距
cell_size = 40 # 每个格子大小
cell_num = 15 #设置线条数
def drawText(text,font,surface,x,y):
textobj=font.render(text,1,TEXTCOLOR)
textrect=textobj.get_rect()
textrect.topright(x,y)
surface.blit(textobj,textrect)
#在死循环外创建一个列表,用来记录落子的横坐标和竖坐标。
#创建列表记录落子位置
chess_arr = [] #将每次落子的坐标放到列表中
#创建一个函数判断连子情况
##最新棋子的x,y和附近的x,y和m列表
def get_one_dire_num(lx, ly, dx, dy, m):
#将最后的x坐标赋值给tx
tx = lx
#将最后的y坐标赋值给ty
ty = ly
#判断连子
s = 0
while True:
#判断上下左右斜方向是否有连子
tx += dx
ty += dy
#如果没有的连子的话返回当前连子数量
if tx < 0 or tx >= cell_num or ty < 0 or ty >= cell_num or m[ty][tx] == 0: return s
#连子累加 1
s+=1
#区分黑白子
flag = 1 # 1=》黑 2=》白
#创建判断获胜的函数
def check_win(chess_arr, flag):
m = [[0] * cell_num for i in range(cell_num)] # 先定义一个15*15的全0的数组,不能用[[0]*cell_num]*cell_num的方式去定义因为一位数组会被重复引用
for x, y, c in chess_arr:
if c == flag:
m[y][x] = 1 # 上面有棋则标1
lx = chess_arr[-1][0] # 最后一个子的x
ly = chess_arr[-1][1] # 最后一个子的y
#定义个列表,里面放入上下左右斜方向各方向的坐标值:
dire_arr = [[(-1, 0), (1, 0)], [(0, -1), (0, 1)], [(-1, -1), (1, 1)],
[(-1, 1), (1, -1)]] # 4个方向数组,往左往右、往上往下、往左上往右下、往左下往右上4组判断方向
for dire1, dire2 in dire_arr: #dire1,dire2是元组
# 往左,往上,往左上,往左下判断是否有连子
dx, dy = dire1 #dx,dy是坐标值
num1 = get_one_dire_num(lx, ly, dx, dy, m) #连子数量1
# 往右,往下,往右下、往右上判断是否有连子
dx, dy = dire2
num2 = get_one_dire_num(lx, ly, dx, dy, m) #连子数量2
# 不同方向加起来的连子数为5的则获胜返回True
if num1 + num2 + 1 >= 5: return True
return False
#定义一个全局变量,来记录现在状态是否获胜
game_state = 1 # 游戏状态1.表示正常进行 2.表示白胜 3.表示黑胜
#set up the block data structure.
player=pygame.Rect(600,0,40,40)
playerImage=pygame.image.load('ok1.jpg')
playerStretchedImage=pygame.transform.scale(playerImage, (400,700))
#Loading and playing a sound effect:
pygame.mixer.music.load('backgroundmusic.wav')
pygame.mixer.music.play(-1,0.0)
musicPlaying=True
screen = pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT)) # 设置窗口长宽
pygame.display.set_caption('快乐五子棋') # 设置 pygame 窗口名
fpsClock=pygame.time.Clock() #让游戏以相同的速率运行
#main game loop
while True: # 死循环确保窗口一直显示
for event in pygame.event.get(): # 遍历所有事件
if event.type==QUIT: # 如果单击关闭窗口,则退出
pygame.quit() #关闭 pygame 程序
sys.exit() #结束程序
if game_state == 1 and event.type == pygame.MOUSEBUTTONUP: # 鼠标弹起
x, y = pygame.mouse.get_pos() # 获取鼠标位置
xi = int(round((x - space) * 1.0 / cell_size)) # 获取到x方向上取整的序号
yi = int(round((y - space) * 1.0 / cell_size)) # 获取到y方向上取整的序号
if xi >= 0 and xi < cell_num and yi >= 0 and yi < cell_num and (xi, yi,1) not in chess_arr and (xi, yi,2) not in chess_arr:
chess_arr.append((xi, yi,flag))
#调用函数判断下的该子是否获胜
if check_win(chess_arr, flag):
#若状态值为 1 则表示3否则表示2
game_state = 2 if flag == 1 else 3
else:
#若状态值为 1 则表示 2 否则为 1代表转换棋子
flag = 2 if flag == 1 else 1
screen.fill(SENIORASH) #界面颜色高级灰
#绘制棋子
for x, y,c in chess_arr:
chess_color = (30, 30, 30) if c == 1 else (225, 225, 225)
pygame.draw.circle(screen, chess_color, [x * cell_size + space, y * cell_size + space], 16, 0)
#绘制竖条
#pygame.draw.line(窗口, 线条颜色, 开始坐标, 结束坐标, 线条大小 )
for x in range(0, cell_size * cell_num, cell_size): #步长为格子大小
pygame.draw.line(screen, BLACK, (x + space, 0 + space),
(x + space, cell_size * (cell_num - 1) + space), 1)
#绘制横条
# 遍历竖位置点步长为40
# pygame.draw.line(窗口, 线条颜色, 开始坐标, 结束坐标, 线条大小 )
for y in range(0, cell_size * cell_num, cell_size):
pygame.draw.line(screen, BLACK, (0 + space, y + space),
(cell_size * (cell_num - 1) + space, y + space), 1)
# 绘制五个点
# pygame.draw.circle(窗口,颜色,坐标,圆半径,线条大小)
#优化落子:判断当该坐标上面有棋子则不显示黑点,即如果黑点的坐标不在棋子的坐标列表上,则绘制出来
if (4, 4,1) not in chess_arr and (4, 4,2) not in chess_arr:
pygame.draw.circle(screen, (0, 0, 0), (cell_size * 4 + space, cell_size * 4 + space), radius=3, width=5)
if (10, 10, 1) not in chess_arr and (10, 10, 2) not in chess_arr:
pygame.draw.circle(screen, (0, 0, 0), (cell_size * 10 + space, cell_size * 10 + space), radius=3, width=5)
if (10, 4, 1) not in chess_arr and (10, 4, 2) not in chess_arr:
pygame.draw.circle(screen, (0, 0, 0), (cell_size * 10 + space, cell_size * 4 + space),radius=3, width=5)
if (4, 10, 1) not in chess_arr and (4 ,10, 2) not in chess_arr:
pygame.draw.circle(screen, (0, 0, 0), (cell_size * 4 + space, cell_size * 10 + space), radius=3, width=5)
if (7, 7, 1) not in chess_arr and (7, 7, 2) not in chess_arr:
pygame.draw.circle(screen, (0, 0, 0), (cell_size * 7 + space, cell_size * 7 + space), radius=3, width=5)
if game_state != 1:
myfont = pygame.font.Font(None, 100) #字体,字体大小
win_text = "%s win" % ('Black' if game_state == 2 else 'White')
textImage = myfont.render(win_text, True, BLACK) #True抗锯齿
screen.blit(textImage, (120, 600))
for event in pygame.event.get():
if event.type == KEYUP:
if event.key == K_1:
if musicPlaying:
pygame.mixer.music.stop()
else:
pygame.mixer.music.play(-1,0.0)
musicPlaying = not musicPlaying
screen.blit(playerStretchedImage,player)
pygame.display.update() ## 必须调用update才能看到绘图显示
fpsClock.tick(FPS)