编程语言
首页 > 编程语言> > Python3 + pygame 实现黑白棋(翻转棋)

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

作者:互联网

直接上代码:

import pygame

# 确认导入成功
print(pygame.ver)

EMPTY = 0
BLACK = 1
WHITE = 2
MOVEOUT = 0

blackColor = [0, 0, 0]
whiteColor = [255, 255, 255]


# 棋盘类
class AppleBoard(object):
    def __init__(self):
        self.board = [[]] * 8
        self.reset()

    def reset(self):
        # row表示行 col表示列 重置棋盘
        for row in range(len(self.board)):
            self.board[row] = [EMPTY] * 8
        self.board[3][4] = WHITE
        self.board[4][3] = WHITE
        self.board[3][3] = BLACK
        self.board[4][4] = BLACK

    def move(self, row, col, isBlack):
        # isBlack表示当前点是黑棋还是白棋
        flag = False
        # 用来解耦 将是否可以落子与实际落子分开
        resultLi = []
        # 水平 竖直 正斜 反斜 四个方向上的坐标各存在一个列表里 并且用XXXCount记录落子点在这四个列表中的位置
        checkLiShuiping = []
        shuipingCount = col
        checkLiShuzhi = []
        shuzhiCount = row
        checkLiZhengxie = []
        zhengxieCount = None
        checkLiFanxie = []
        fanxieCount = None
        if self.board[row][col] == EMPTY:
            qiziColor = BLACK if isBlack else WHITE
            fanseColor = WHITE if isBlack else BLACK
            checkLiShuiping = 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]]:
                pass
            else:
                zhengxieRow = row
                zhengxieCol = col
                while zhengxieRow > 0 and zhengxieCol > 0:
                    zhengxieRow -= 1
                    zhengxieCol -= 1
                zhengxieCount = row if zhengxieRow == 0 else col
                while zhengxieRow <= 7 and zhengxieCol <= 7:
                    checkLiZhengxie.append(self.board[zhengxieRow][zhengxieCol])
                    zhengxieRow += 1
                    zhengxieCol += 1
            # 找反斜左下角的点:
            if [row, col] in [[0, 0], [0, 1], [1, 0], [6, 7], [7, 6], [7, 7]]:
                pass
            else:
                fanxieRow = row
                fanxieCol = col
                while fanxieRow < 7 and fanxieCol > 0:
                    fanxieRow += 1
                    fanxieCol -= 1
                fanxieCount = 7 - row if fanxieRow == 7 else col
                while fanxieRow >= 0 and fanxieCol <= 7:
                    checkLiFanxie.append(self.board[fanxieRow][fanxieCol])
                    fanxieRow -= 1
                    fanxieCol += 1
            # 先判断水平情况:
            # 先去掉无效情况
            # 加一个变量判断是否是贴边的情况 如最边的是白子这时在这个白子旁边落下一颗黑子 则这个白子不应该变色
            if BLACK not in checkLiShuiping or WHITE not in checkLiShuiping:
                resultLi.append(shuipingCount)
                resultLi.append(0)
                resultLi.append(0)
            else:
                tiebian = True
                changeCount = -1
                emptyCount = 0
                for i in range(shuipingCount, 0, -1):
                    if checkLiShuiping[i] == fanseColor:
                        changeCount += 1
                    elif checkLiShuiping[i] == qiziColor:
                        # 换句话说只有再次遇到相同颜色棋子才有效
                        tiebian = False
                        break
                    elif checkLiShuiping[i] == EMPTY:
                        changeCount = 0
                        emptyCount += 1
                        # 判断除了落子点是空之外还有其他空点则直接退出且changeCount为0
                        if emptyCount >= 2:
                            break
                resultLi.append(shuipingCount)
                resultLi.append(changeCount)
                if changeCount > 0 and tiebian is False:
                    flag = True

                changeCount = -1
                emptyCount = 0
                tiebian = True
                for i in range(shuipingCount, 8):
                    if checkLiShuiping[i] == fanseColor:
                        changeCount += 1
                    elif checkLiShuiping[i] == qiziColor:
                        tiebian = False
                        break
                    elif checkLiShuiping[i] == EMPTY:
                        changeCount = 0
                        emptyCount += 1
                        if emptyCount >= 2:
                            break
                resultLi.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 = -1
                emptyCount = 0
                tiebian = True
                for i in range(shuzhiCount, 0, -1):
                    if checkLiShuzhi[i] == fanseColor:
                        changeCount += 1
                    elif checkLiShuzhi[i] == qiziColor:
                        tiebian = False
                        break
                    elif checkLiShuzhi[i] == EMPTY:
                        changeCount = 0
                        emptyCount += 1
                        if emptyCount >= 2:
                            break
                resultLi.append(shuzhiCount)
                resultLi.append(changeCount)
                if changeCount > 0 and tiebian is False:
                    flag = True

                emptyCount = 0
                changeCount = -1
                tiebian = True
                for i in range(shuzhiCount, 8):
                    if checkLiShuzhi[i] == fanseColor:
                        changeCount += 1
                    elif checkLiShuzhi[i] == qiziColor:
                        tiebian = False
                        break
                    elif checkLiShuzhi[i] == EMPTY:
                        changeCount = 0
                        emptyCount += 1
                        if emptyCount >= 2:
                            break
                resultLi.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 = True
                changeCount = -1
                emptyCount = 0
                for i in range(zhengxieCount, -1, -1):
                    if checkLiZhengxie[i] == fanseColor:
                        changeCount += 1
                    elif checkLiZhengxie[i] == qiziColor:
                        tiebian = False
                        break
                    elif checkLiZhengxie[i] == EMPTY:
                        changeCount = 0
                        emptyCount += 1
                        if emptyCount >= 2:
                            break
                resultLi.append(changeCount)
                if changeCount > 0 and tiebian is False:
                    flag = True

                changeCount = -1
                emptyCount = 0
                tiebian = True
                for i in range(zhengxieCount, len(checkLiZhengxie)):
                    if checkLiZhengxie[i] == fanseColor:
                        changeCount += 1
                    elif checkLiZhengxie[i] == qiziColor:
                        tiebian = False
                        break
                    elif checkLiZhengxie[i] == EMPTY:
                        changeCount = 0
                        emptyCount += 1
                        if emptyCount >= 2:
                            break
                resultLi.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 = True
                changeCount = -1
                emptyCount = 0
                for i in range(fanxieCount, -1, -1):
                    if checkLiFanxie[i] == fanseColor:
                        changeCount += 1
                    elif checkLiFanxie[i] == qiziColor:
                        tiebian = False
                        break
                    elif checkLiFanxie[i] == EMPTY:
                        changeCount = 0
                        emptyCount += 1
                        if emptyCount >= 2:
                            break
                resultLi.append(changeCount)
                if changeCount > 0 and tiebian is False:
                    flag = True

                changeCount = -1
                emptyCount = 0
                tiebian = True
                for i in range(fanxieCount, len(checkLiFanxie)):
                    if checkLiFanxie[i] == fanseColor:
                        changeCount += 1
                    elif checkLiFanxie[i] == qiziColor:
                        tiebian = False
                        break
                    elif checkLiFanxie[i] == EMPTY:
                        changeCount = 0
                        emptyCount += 1
                        if emptyCount >= 2:
                            break
                resultLi.append(changeCount)
                if changeCount > 0 and tiebian is False:
                    flag = True

        return [flag, resultLi]

    def realMove(self, para, isBlack, row, col):
        qiziColor = BLACK if isBlack else  WHITE
        shuipingCount = 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] = qiziColor
        for j in range(changCountShuipingYou + 1):
            self.board[row][shuipingCount + j] = qiziColor
        for j in range(changCountShuzhiZuo + 1):
            self.board[shuzhiCount - j][col] = qiziColor
        for j in range(changCountShuzhiYou + 1):
            self.board[shuzhiCount + j][col] = qiziColor
        for j in range(changCountZhengxieZuo + 1):
            self.board[row - j][col - j] = qiziColor
        for j in range(changCountZhengxieYou + 1):
            self.board[row + j][col + j] = qiziColor
        for j in range(changCountFanxieZuo + 1):
            self.board[row + j][col - j] = qiziColor
        for j in range(changCountFanxieYou + 1):
            self.board[row - j][col + j] = qiziColor

    def 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 whiteColor
                    pos = [40 * (col + 1), 40 * (row + 1)]
                    pygame.draw.circle(screen, ccolor, pos, 18, 0)


def isWin(board, isBlack):
    # 胜利有三种结算方式 一是无子 二是双方均无子可下 三是棋盘下满算数量
    global MOVEOUT
    allChess = [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 or
                                                          checkBoard[i - 1][j + 1] != EMPTY or checkBoard[i][
                        j - 1] != EMPTY or
                                                          checkBoard[i][j] != EMPTY or checkBoard[i][j + 1] != EMPTY or
                                                          checkBoard[i + 1][j - 1] != EMPTY or checkBoard[i + 1][
                    j] != EMPTY or
                                                          checkBoard[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 False
        if not moveornot:
            MOVEOUT += 1
            return "换棋子继续下"
        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 = 0


def main():
    # 创建棋盘对象
    board = AppleBoard()
    isBlack = True
    pygame.init()
    pygame.display.set_caption("黑白棋")
    screen = pygame.display.set_mode((360, 360))
    screen.fill([125, 95, 24])
    board.draw(screen)
    pygame.display.flip()

    running = True
    pause = False
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.KEYUP:
                pass
            elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                x, y = event.pos
                row = 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 isBlack
                elif res == "黑棋胜" or res == "白棋胜" or res == "和棋":
                    pause = True
                    # 游戏结束后画面暂停 按空格键重新开始
                    while pause:
                        print(res)
                        for event in pygame.event.get():
                            if event.type == pygame.QUIT:
                                pause = False
                                running = False
                            elif event.type == pygame.KEYDOWN:
                                if event.key == pygame.K_SPACE:
                                    board.reset()
                                    screen.fill([125, 95, 24])
                                    board.draw(screen)
                                    pygame.display.flip()
                                    isBlack = True
                                    pause = False


if __name__ == '__main__':
    main()

本能優勢 发布了1 篇原创文章 · 获赞 0 · 访问量 33 私信 关注

标签:黑白棋,changeCount,self,append,range,pygame,row,Python3,board
来源: https://blog.csdn.net/qq_42952335/article/details/104595720