当前位置: 代码迷 >> 综合 >> Python3 + pygame 实现黑白棋(翻转棋)
  详细解决方案

Python3 + pygame 实现黑白棋(翻转棋)

热度:46   发布时间:2024-01-26 21:20:45.0

直接上代码:

import pygame# 确认导入成功
print(pygame.ver)EMPTY = 0
BLACK = 1
WHITE = 2
MOVEOUT = 0blackColor = [0, 0, 0]
whiteColor = [255, 255, 255]# 棋盘类
class AppleBoard(object):def __init__(self):self.board = [[]] * 8self.reset()def reset(self):# row表示行 col表示列 重置棋盘for row in range(len(self.board)):self.board[row] = [EMPTY] * 8self.board[3][4] = WHITEself.board[4][3] = WHITEself.board[3][3] = BLACKself.board[4][4] = BLACKdef move(self, row, col, isBlack):# isBlack表示当前点是黑棋还是白棋flag = False# 用来解耦 将是否可以落子与实际落子分开resultLi = []# 水平 竖直 正斜 反斜 四个方向上的坐标各存在一个列表里 并且用XXXCount记录落子点在这四个列表中的位置checkLiShuiping = []shuipingCount = colcheckLiShuzhi = []shuzhiCount = rowcheckLiZhengxie = []zhengxieCount = NonecheckLiFanxie = []fanxieCount = Noneif self.board[row][col] == EMPTY:qiziColor = BLACK if isBlack else WHITEfanseColor = WHITE if isBlack else BLACKcheckLiShuiping = self.board[row]checkLiShuzhi = [self.board[i][col] for i in range(8)]# 找正斜左上角的点:# 先去掉无效点:if [row, col] in [[0, 7], [0, 6], [1, 7], [6, 0], [7, 0], [7, 1]]:passelse:zhengxieRow = rowzhengxieCol = colwhile zhengxieRow > 0 and zhengxieCol > 0:zhengxieRow -= 1zhengxieCol -= 1zhengxieCount = row if zhengxieRow == 0 else colwhile zhengxieRow <= 7 and zhengxieCol <= 7:checkLiZhengxie.append(self.board[zhengxieRow][zhengxieCol])zhengxieRow += 1zhengxieCol += 1# 找反斜左下角的点:if [row, col] in [[0, 0], [0, 1], [1, 0], [6, 7], [7, 6], [7, 7]]:passelse:fanxieRow = rowfanxieCol = colwhile fanxieRow < 7 and fanxieCol > 0:fanxieRow += 1fanxieCol -= 1fanxieCount = 7 - row if fanxieRow == 7 else colwhile fanxieRow >= 0 and fanxieCol <= 7:checkLiFanxie.append(self.board[fanxieRow][fanxieCol])fanxieRow -= 1fanxieCol += 1# 先判断水平情况:# 先去掉无效情况# 加一个变量判断是否是贴边的情况 如最边的是白子这时在这个白子旁边落下一颗黑子 则这个白子不应该变色if BLACK not in checkLiShuiping or WHITE not in checkLiShuiping:resultLi.append(shuipingCount)resultLi.append(0)resultLi.append(0)else:tiebian = TruechangeCount = -1emptyCount = 0for i in range(shuipingCount, 0, -1):if checkLiShuiping[i] == fanseColor:changeCount += 1elif checkLiShuiping[i] == qiziColor:# 换句话说只有再次遇到相同颜色棋子才有效tiebian = Falsebreakelif checkLiShuiping[i] == EMPTY:changeCount = 0emptyCount += 1# 判断除了落子点是空之外还有其他空点则直接退出且changeCount为0if emptyCount >= 2:breakresultLi.append(shuipingCount)resultLi.append(changeCount)if changeCount > 0 and tiebian is False:flag = TruechangeCount = -1emptyCount = 0tiebian = Truefor i in range(shuipingCount, 8):if checkLiShuiping[i] == fanseColor:changeCount += 1elif checkLiShuiping[i] == qiziColor:tiebian = Falsebreakelif checkLiShuiping[i] == EMPTY:changeCount = 0emptyCount += 1if emptyCount >= 2:breakresultLi.append(changeCount)if changeCount > 0 and tiebian is False:flag = True# 竖直情况:if BLACK not in checkLiShuzhi or WHITE not in checkLiShuzhi:resultLi.append(shuzhiCount)resultLi.append(0)resultLi.append(0)else:changeCount = -1emptyCount = 0tiebian = Truefor i in range(shuzhiCount, 0, -1):if checkLiShuzhi[i] == fanseColor:changeCount += 1elif checkLiShuzhi[i] == qiziColor:tiebian = Falsebreakelif checkLiShuzhi[i] == EMPTY:changeCount = 0emptyCount += 1if emptyCount >= 2:breakresultLi.append(shuzhiCount)resultLi.append(changeCount)if changeCount > 0 and tiebian is False:flag = TrueemptyCount = 0changeCount = -1tiebian = Truefor i in range(shuzhiCount, 8):if checkLiShuzhi[i] == fanseColor:changeCount += 1elif checkLiShuzhi[i] == qiziColor:tiebian = Falsebreakelif checkLiShuzhi[i] == EMPTY:changeCount = 0emptyCount += 1if emptyCount >= 2:breakresultLi.append(changeCount)if changeCount > 0 and tiebian is False:flag = True# 正斜情况:if BLACK not in checkLiZhengxie or WHITE not in checkLiZhengxie or not checkLiZhengxie:resultLi.append(0)resultLi.append(0)elif zhengxieCount is None:resultLi.append(0)resultLi.append(0)else:tiebian = TruechangeCount = -1emptyCount = 0for i in range(zhengxieCount, -1, -1):if checkLiZhengxie[i] == fanseColor:changeCount += 1elif checkLiZhengxie[i] == qiziColor:tiebian = Falsebreakelif checkLiZhengxie[i] == EMPTY:changeCount = 0emptyCount += 1if emptyCount >= 2:breakresultLi.append(changeCount)if changeCount > 0 and tiebian is False:flag = TruechangeCount = -1emptyCount = 0tiebian = Truefor i in range(zhengxieCount, len(checkLiZhengxie)):if checkLiZhengxie[i] == fanseColor:changeCount += 1elif checkLiZhengxie[i] == qiziColor:tiebian = Falsebreakelif checkLiZhengxie[i] == EMPTY:changeCount = 0emptyCount += 1if emptyCount >= 2:breakresultLi.append(changeCount)if changeCount > 0 and tiebian is False:flag = True# 反斜情况:if BLACK not in checkLiFanxie or WHITE not in checkLiFanxie or not checkLiFanxie:resultLi.append(0)resultLi.append(0)elif fanxieCount is None:resultLi.append(0)resultLi.append(0)else:tiebian = TruechangeCount = -1emptyCount = 0for i in range(fanxieCount, -1, -1):if checkLiFanxie[i] == fanseColor:changeCount += 1elif checkLiFanxie[i] == qiziColor:tiebian = Falsebreakelif checkLiFanxie[i] == EMPTY:changeCount = 0emptyCount += 1if emptyCount >= 2:breakresultLi.append(changeCount)if changeCount > 0 and tiebian is False:flag = TruechangeCount = -1emptyCount = 0tiebian = Truefor i in range(fanxieCount, len(checkLiFanxie)):if checkLiFanxie[i] == fanseColor:changeCount += 1elif checkLiFanxie[i] == qiziColor:tiebian = Falsebreakelif checkLiFanxie[i] == EMPTY:changeCount = 0emptyCount += 1if emptyCount >= 2:breakresultLi.append(changeCount)if changeCount > 0 and tiebian is False:flag = Truereturn [flag, resultLi]def realMove(self, para, isBlack, row, col):qiziColor = BLACK if isBlack else  WHITEshuipingCount = para[0]changCountShuipingZuo = para[1]changCountShuipingYou = para[2]shuzhiCount = para[3]changCountShuzhiZuo = para[4]changCountShuzhiYou = para[5]changCountZhengxieZuo = para[6]changCountZhengxieYou = para[7]changCountFanxieZuo = para[8]changCountFanxieYou = para[9]for j in range(changCountShuipingZuo + 1):self.board[row][shuipingCount - j] = qiziColorfor j in range(changCountShuipingYou + 1):self.board[row][shuipingCount + j] = qiziColorfor j in range(changCountShuzhiZuo + 1):self.board[shuzhiCount - j][col] = qiziColorfor j in range(changCountShuzhiYou + 1):self.board[shuzhiCount + j][col] = qiziColorfor j in range(changCountZhengxieZuo + 1):self.board[row - j][col - j] = qiziColorfor j in range(changCountZhengxieYou + 1):self.board[row + j][col + j] = qiziColorfor j in range(changCountFanxieZuo + 1):self.board[row + j][col - j] = qiziColorfor j in range(changCountFanxieYou + 1):self.board[row - j][col + j] = qiziColordef draw(self, screen):for h in range(1, 10):pygame.draw.line(screen, blackColor, [40, h * 40], [320, h * 40], 1)pygame.draw.line(screen, blackColor, [h * 40, 40], [h * 40, 320], 1)pygame.draw.rect(screen, blackColor, [36, 36, 289, 289], 3)for row in range(len(self.board)):for col in range(len(self.board[row])):if self.board[row][col] != EMPTY:ccolor = blackColor if self.board[row][col] == BLACK else whiteColorpos = [40 * (col + 1), 40 * (row + 1)]pygame.draw.circle(screen, ccolor, pos, 18, 0)def isWin(board, isBlack):# 胜利有三种结算方式 一是无子 二是双方均无子可下 三是棋盘下满算数量global MOVEOUTallChess = [board.board[i][j] for i in range(8) for j in range(8)]# 情况1 单方无子if WHITE not in allChess:return "黑棋胜"if BLACK not in allChess:return "白棋胜"if EMPTY in allChess:# 正常情况下黑子和白子是连在一起的 所以只需要检查周围一圈是否可以落子即可aroundLi = []moveornotLi = []# 临时给棋盘对象最外面加一圈 这里若不使用[:][:]则为同一对象# !!!并且如果只是 checkBoard = board.board[:] 则内部的数组为同一对象checkBoard = [i[:] for i in board.board]for i in range(8):checkBoard[i].insert(0, 0)checkBoard[i].append(0)checkBoard.insert(0, [0] * 10)checkBoard.append([0] * 10)for i in range(1, 9):for j in range(1, 9):if checkBoard[i][j] == EMPTY and (checkBoard[i - 1][j - 1] != EMPTY or checkBoard[i - 1][j] != EMPTY orcheckBoard[i - 1][j + 1] != EMPTY or checkBoard[i][j - 1] != EMPTY orcheckBoard[i][j] != EMPTY or checkBoard[i][j + 1] != EMPTY orcheckBoard[i + 1][j - 1] != EMPTY or checkBoard[i + 1][j] != EMPTY orcheckBoard[i + 1][j + 1] != EMPTY):aroundLi.append([i - 1, j - 1])for i in aroundLi:moveornotLi.append(board.move(i[0], i[1], isBlack)[0])moveornot = True if True in moveornotLi else Falseif not moveornot:MOVEOUT += 1return "换棋子继续下"if MOVEOUT == 2:# 如果连续没下棋换边2次 则证明双方均无子可下baiqiCount = allChess.count(WHITE)heiqiCount = allChess.count(BLACK)if baiqiCount > heiqiCount:return "白棋胜"elif baiqiCount < heiqiCount:return "黑棋胜"else:return "和棋"return "一般情况"if EMPTY not in allChess:baiqiCount = allChess.count(WHITE)heiqiCount = allChess.count(BLACK)if baiqiCount > heiqiCount:return "白棋胜"elif baiqiCount < heiqiCount:return "黑棋胜"else:return "和棋"MOVEOUT = 0def main():# 创建棋盘对象board = AppleBoard()isBlack = Truepygame.init()pygame.display.set_caption("黑白棋")screen = pygame.display.set_mode((360, 360))screen.fill([125, 95, 24])board.draw(screen)pygame.display.flip()running = Truepause = Falsewhile running:for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseelif event.type == pygame.KEYUP:passelif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:x, y = event.posrow = round((y - 40) / 40)col = round((x - 40) / 40)moveRes = board.move(row, col, isBlack)res = isWin(board, isBlack)if res == "一般情况" or res == "换棋子继续下":if moveRes[0]:board.realMove(moveRes[1], isBlack, row, col)screen.fill([125, 95, 24])board.draw(screen)pygame.display.flip()isBlack = not isBlackelif res == "黑棋胜" or res == "白棋胜" or res == "和棋":pause = True# 游戏结束后画面暂停 按空格键重新开始while pause:print(res)for event in pygame.event.get():if event.type == pygame.QUIT:pause = Falserunning = Falseelif event.type == pygame.KEYDOWN:if event.key == pygame.K_SPACE:board.reset()screen.fill([125, 95, 24])board.draw(screen)pygame.display.flip()isBlack = Truepause = Falseif __name__ == '__main__':main()
  相关解决方案