基于pygame实现五子棋
掌握核心算法,怎么判断是否连成五个以及落子位置的模糊判断
1.只需要判断最后一个棋子周围4个方向(上下,左右,左上右下,右下左上)这些方向棋子的颜色是否和最后一个落子颜色连续一致!(详情看代码)
2.落子位置的模糊判断对下棋的体验感提升十分明显!采用基本的四舍五入就行了,超过两棋盘线一半就可以认为是在下一行,反之成立!
有其他问题欢迎交流!
生成棋盘的样子
import pygame
pygame.init()
pygame.display.set_caption('五子棋') #窗口名称
dir1=[(-1, 0), (1, 0)]
dir2=[(0, -1), (0, 1)]
dir3=[(-1, -1), (1, 1)]
dir4=[(-1, 1), (1, -1)]
direct=[dir1,dir2,dir3,dir4]#设定判断连子方向
space=60#四周边距
cell_size=40#每个格子大小
cell_number=15#行列数
screen_size=cell_size*(cell_number-1)+2*space#窗口边长
screen = pygame.display.set_mode((screen_size,screen_size))#窗口大小
chess_arr=[]#已经落下的棋子的屏幕坐标
chess_done=[]#已经落下的棋子的坐标
chess=0#总棋子数
flag='black'#先下者为黑
game_state='good'
chess_board=[[0]*15 for i in range(15)]#设定棋盘集合
'''#第一次的失败实验
def chess_number(chess_board,dx,dy,lastx,lasty):#判断连子数
tempx=lastx
tempy=lasty
num=0
while True:
tempx += dx#将tempx移动一格,以便判断连子数
tempy += dy
if tempx<0 or tempy< 0 or tempx >14 or tempy >14 or chess_board[tempy][tempx] == '0':num
num=num+1
'''
def chess_number(chess_board,dx,dy,lastx,lasty):#判断连子数
tempx=lastx
tempy=lasty
num=0
while True:
tempx += dx#将tempx移动一格,以便判断连子数
tempy += dy
if 0<=tempx<=14 and 0<=tempy<=14 and chess_board[tempy][tempx]==flag:
num+=1
elif 0<=tempx<=14 and 0<=tempy<=14 and chess_board[tempy][tempx]!=flag:
return num
if tempx<0 or tempy<0 or tempx>14 or tempy>14 or chess_board[tempy][tempx]==0:
return num
def check_win(chess_done,flag):
for dir in direct:#遍历方向
di1,di2=dir
dx,dy=di1
number1=chess_number(chess_board,dx,dy,xi,yi)
dx,dy=di2
number2=chess_number(chess_board,dx,dy,xi,yi)
print(number1+number2)
if number1+number2>=4:#包括最后一颗子在内,连子数大于等于5
return True
while True: # 死循环确保窗口一直显示
for event in pygame.event.get(): # 遍历所有事件
if event.type == pygame.QUIT: # 如果单击关闭窗口,则退出
pygame.quit()
if event.type == pygame.MOUSEBUTTONUP and game_state == 'good': # 鼠标弹起
x, y = pygame.mouse.get_pos() # 获取鼠标位置
if (x-space)//cell_size in [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]:#判断在格子附近
if (x-space)%cell_size>0.5*cell_size:#向大取整
xi=(x-space)//cell_size+1
else:#向小取整
xi=(x-space)//cell_size
else:
break
if (y-space)//cell_size in [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]:#判断在格子附近
if (y-space)%cell_size>0.5*cell_size:#向大取整
yi=(y-space)//cell_size+1
else:#向小取整
yi=(y-space)//cell_size
else:
break
if xi in [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14] and yi in [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14] and (xi*cell_size+space,yi*cell_size+space,'black') not in chess_arr and (xi*cell_size+space,yi*cell_size+space,'white') not in chess_arr:
chess_arr.append((xi*cell_size+space,yi*cell_size+space,flag))#将落子坐标加入集合
chess_done.append((xi,yi,flag))
chess_board[yi][xi]=flag
if check_win(chess_done, flag):
game_state = 'black' if flag == 'black' else 'white'#判断输赢
else:
flag = 'white' if flag == 'black' else 'black'#切换棋子颜色
chess+=1
if chess==225:
game_state='tie'
screen.fill((222,171,138))#设置底色
for x in range(0, cell_size * cell_number, cell_size):
pygame.draw.line(screen,(255,255,255),(x+space,space),(x+space,screen_size-space),1)#窗口, 线条颜色, 开始坐标, 结束坐标, 线条大小
for y in range(0, cell_size * cell_number, cell_size):
pygame.draw.line(screen,(255,255,255),(space,y+space),(screen_size-space,y+space),1)#窗口, 线条颜色, 开始坐标, 结束坐标, 线条大小
for i in [4,10]:
for j in [4,10]:
pygame.draw.circle(screen,(255,255,255),(i*cell_size+space,j*cell_size+space),5,5)
pygame.draw.circle(screen,(255,255,255),(7*cell_size+space,7*cell_size+space),5,5)
for x,y,c in chess_done:
if c == 'black':
color=(0,0,0)#定义颜色
else:
color=(255,255,255)
pygame.draw.circle(screen,color,(x*cell_size+space,y*cell_size+space),12,12)#画出集合内所有棋子
if game_state != 'good':
myfont = pygame.font.Font(None,120)
color= 221,207,113#胜利者金黄色
if game_state=='white':#判断输出语句
win_text='white win'
elif game_state == 'black':
win_text='black win'
elif game_state == 'tie':
win_text='TIE'
textImage = myfont.render(win_text, True, color)
screen.blit(textImage, (260,320))
pygame.display.update()