有没有小火伴是特别喜欢玩五子棋的,我记得我初中是特别喜欢的。于是,我今天就用Python给大家写了一个黑白棋游戏。代码放在下面了。
01、绘制棋盘
Python学习交流Q群:906715085###
import pygame, sys, random
from pygame.locals import *
BACKGROUNDCOLOR = (255, 255, 255)
FPS = 40
# 初始化
pygame.init()
mainClock = pygame.time.Clock()
# 加载图片
boardImage = pygame.image.load('board.png')
boardRect = boardImage.get_rect()
blackImage = pygame.image.load('black.png')
blackRect = blackImage.get_rect()
whiteImage = pygame.image.load('white.png')
whiteRect = whiteImage.get_rect()
# 设置窗口
windowSurface = pygame.display.set_mode((boardRect.width, boardRect.height))
pygame.display.set_caption('黑白棋')
# 游戏主循环
while True:
for event in pygame.event.get():
if event.type == QUIT:
terminate()
#鼠标事件完成玩家走棋(见下文)…..
#电脑走棋(见下文)…..
windowSurface.fill(BACKGROUNDCOLOR)
windowSurface.blit(boardImage, boardRect, boardRect)
#重画所有的棋子(见下文)…..
#游戏结束,显示双方棋子数量(见下文)……
pygame.display.update()
mainClock.tick(FPS)
02、绘制棋子
(1)黑白棋的规则,开局时先放置上黑白各两个棋子在中间。
(2)用一个8x8列表保存棋子。
CELLWIDTH = 80
CELLHEIGHT = 80
PIECEWIDTH = 78
PIECEHEIGHT = 78
BOARDX = 40
BOARDY = 40
# 重置棋盘
def resetBoard(board):
for x in range(8):
for y in range(8):
board[x][y] = 'none'
# Starting pieces:
board[3][3] = 'black'
board[3][4] = 'white'
board[4][3] = 'white'
board[4][4] = 'black'
# 开局时建立新棋盘
def getNewBoard():
board = []
for i in range(8):
board.append(['none'] * 8)
return board
mainBoard = getNewBoard()
resetBoard(mainBoard)
for x in range(8):
for y in range(8):
rectDst = pygame.Rect(BOARDX+x*CELLWIDTH+2, BOARDY+y*CELLHEIGHT+2, PIECEWIDTH, PIECEHEIGHT)
if mainBoard[x][y] == 'black':
windowSurface.blit(blackImage, rectDst, blackRect) #画黑棋
elif mainBoard[x][y] == 'white':
windowSurface.blit(whiteImage, rectDst, whiteRect) #画白棋
03、随机决定谁先走棋
# 谁先走
def whoGoesFirst():
if random.randint(0, 1) == 0:
return 'computer'
else:
return 'player'
turn = whoGoesFirst()
if turn == 'player':
playerTile = 'black'
computerTile = 'white'
else:
playerTile = 'white'
computerTile = 'black'
04、鼠标事件
(1)鼠标操纵,完成玩家走棋
(2)轮流走棋
for event in pygame.event.get():
if event.type == QUIT:
terminate()
#玩家走棋
if turn == 'player' and event.type == MOUSEBUTTONDOWN and event.button == 1:
x, y = pygame.mouse.get_pos()
col = int((x-BOARDX)/CELLWIDTH)
row = int((y-BOARDY)/CELLHEIGHT)
if makeMove(mainBoard, playerTile, col, row) == True:
if getValidMoves(mainBoard, computerTile) != []:
turn = 'computer' #轮到电脑走棋
#电脑走棋
if (gameOver == False and turn == 'computer'):
x, y = getComputerMove(mainBoard, computerTile)
makeMove(mainBoard, computerTile, x, y)
savex, savey = x, y
# 玩家没有可行的走法了,则电脑继续,否则切换到玩家走
if getValidMoves(mainBoard, playerTile) != []:
turn = 'player' #轮到玩家走棋
windowSurface.fill(BACKGROUNDCOLOR)
windowSurface.blit(boardImage, boardRect, boardRect)
05、游戏规则实现
(1)是否允许落子
(2)落子后的翻转
# 是否是合法走法,如果合法返回需要翻转的棋子列表
def isValidMove(board, tile, xstart, ystart):
# 如果该位置已经有棋子或者出界了,返回False
if not isOnBoard(xstart, ystart) or board[xstart][ystart] != 'none':
return False
# 临时将tile 放到指定的位置
board[xstart][ystart] = tile
if tile == 'black':
otherTile = 'white'
else:
otherTile = 'black'
# 要被翻转的棋子
tilesToFlip = []
for xdirection, ydirection in [ [0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1] ]:
x, y = xstart, ystart
x += xdirection
y += ydirection
if isOnBoard(x, y) and board[x][y] == otherTile:
x += xdirection
y += ydirection
if not isOnBoard(x, y):
continue
# 一直走到出界或不是对方棋子的位置
while board[x][y] == otherTile:
x += xdirection
y += ydirection
if not isOnBoard(x, y):
break
# 出界了,则没有棋子要翻转OXXXXX
if not isOnBoard(x, y):
continue
# 是自己的棋子OXXXXXXO
if board[x][y] == tile:
while True:
x -= xdirection
y -= ydirection
# 回到了起点则结束
if x == xstart and y == ystart:
break
# 需要翻转的棋子
tilesToFlip.append([x, y])
# 将前面临时放上的棋子去掉,即还原棋盘
board[xstart][ystart] = 'none' # restore the empty space
# 没有要被翻转的棋子,则走法非法。翻转棋的规则。
if len(tilesToFlip) == 0: # If no tiles were flipped, this is not a valid move.
return False
return tilesToFlip
# 是否出界
def isOnBoard(x, y):
return x >= 0 and x <= 7 and y >= 0 and y <=7
# 获取可落子的位置
def getValidMoves(board, tile):
validMoves = []
for x in range(8):
for y in range(8):
if isValidMove(board, tile, x, y) != False:
validMoves.append([x, y])
return validMoves
# 将一个tile棋子放到(xstart, ystart)
def makeMove(board, tile, xstart, ystart):
tilesToFlip = isValidMove(board, tile, xstart, ystart)
if tilesToFlip == False:
return False
board[xstart][ystart] = tile
for x, y in tilesToFlip: #tilesToFlip是需要翻转的棋子列表
board[x][y] = tile #翻转棋子
06、电脑AI走法
如果电脑在所有落子的选择中,有四个边角,可落子在边角,因为边角的棋子无法被翻转。如果没有边角,则选择可以翻转对手最多的位置落子。
def getComputerMove(board, computerTile):
# 获取所以合法走法
possibleMoves = getValidMoves(board, computerTile)
# 打乱所有合法走法
random.shuffle(possibleMoves)
# [x, y]在角上,则优先走,因为角上的不会被再次翻转
for x, y in possibleMoves:
if isOnCorner(x, y):
return [x, y]
bestScore = -1
for x, y in possibleMoves:
dupeBoard = getBoardCopy(board)
makeMove(dupeBoard, computerTile, x, y)
# 按照分数选择走法,优先选择翻转后分数最多的走法
score = getScoreOfBoard(dupeBoard)[computerTile]
if score > bestScore:
bestMove = [x, y]
bestScore = score
return bestMove
# 是否游戏结束
def isGameOver(board):
for x in range(8):
for y in range(8):
if board[x][y] == 'none':
return False
return True
# 获取棋盘上黑白双方的棋子数
def getScoreOfBoard(board):
xscore = 0
oscore = 0
for x in range(8):
for y in range(8):
if board[x][y] == 'black':
xscore += 1
if board[x][y] == 'white':
oscore += 1
return {
'black':xscore, 'white':oscore}
主程序中加入游戏结束,显示双方棋子数量功能。
if isGameOver(mainBoard): #游戏结束,显示双方棋子数量
scorePlayer = getScoreOfBoard(mainBoard)[playerTile]
scoreComputer = getScoreOfBoard(mainBoard)[computerTile]
outputStr = gameoverStr + str(scorePlayer) + ":" + str(scoreComputer)
text = basicFont.render(outputStr, True, BLACK, BLUE)
textRect = text.get_rect()
textRect.centerx = windowSurface.get_rect().centerx
textRect.centery = windowSurface.get_rect().centery
windowSurface.blit(text, textRect)
至此完成基于Pygame的黑白棋游戏设计。游戏效果如图所示。今天的分享就到这里了,下一章见。