井字棋(Python)

井字棋(Python)

效果

井字棋

代码

import pgzrun

TITLE = "井字棋"
WIDTH = 640
HEIGHT = 500

man_machine = False
people_people = False

btn1 = Actor("button")
btn1.left = 230
btn1.top = 200

btn2 = Actor("button")
btn2.left = 230
btn2.top = 300

bg = Actor("chess_bg")
PhotoSize = 120
backgrounds = []
n = 1
for i in range(3):
    for j in range(3):
        background = Actor("blank")
        background.left = 140 + j * PhotoSize;
        background.top = 60 + i * PhotoSize;
        backgrounds.append(background)
        n += 1

chessPieces = []
clicks = 0
isClick = [-1, -1, -1, -1, -1, -1, -1, -1, -1]

rightIcon = Actor("smallright")
rightIcon.left = 80
rightIcon.top = 435
wrongIcon = Actor("smallwrong")
wrongIcon.left = 280
wrongIcon.top = 435
rightWin = 0
wrongWin = 0
dogfall = 0
isFinish = False
temp = -1
man_machine_location = -1
flag = 0

one_move = [4, 0, 2, 6, 8, 1, 3, 5, 7]

def draw():
    if not man_machine and not people_people:
        screen.clear()
        bg.draw()
        btn1.draw()
        btn2.draw()
        screen.draw.text('人机对战', (250, 210), fontsize=40, fontname='fzshuangqtjw_cu', color="black")
        screen.draw.text('人人对战', (250, 310), fontsize=40, fontname='fzshuangqtjw_cu', color="black")
    else:
        screen.clear()
        bg.draw()
        for background in backgrounds:
            background.draw()
        for i in range(4):
            screen.draw.line((140, 60 + 120 * i), (500, 60 + 120 * i), 'black')
            screen.draw.line((140 + 120 * i, 60), (140 + 120 * i, 420), 'black')
        for cp in chessPieces:
            cp.draw()
        rightIcon.draw()
        screen.draw.text("赢:" + str(rightWin), (130, 445), fontsize=30,
                         fontname='simhei', color=(161, 102, 43))
        wrongIcon.draw()
        screen.draw.text("赢:" + str(wrongWin), (330, 445), fontsize=30,
                         fontname='simhei', color=(161, 102, 43))
        screen.draw.text("平局:" + str(dogfall), (480, 445), fontsize=30,
                         fontname='simhei', color=(161, 102, 43))
        if isFinish:
            screen.draw.text('游戏结束', (200, 200), fontsize=60, fontname='fzshuangqtjw_cu', color="red")
            screen.draw.text('再来一次', (100, 350), fontsize=40, fontname='fzshuangqtjw_cu', color="red")
            screen.draw.text('回主菜单', (400, 350), fontsize=40, fontname='fzshuangqtjw_cu', color="red")
            screen.draw.rect(Rect((90, 350), (180, 50)), "red")
            screen.draw.rect(Rect((390, 350), (180, 50)), "red")

def update():
    global rightWin, wrongWin, dogfall, isFinish, clicks, man_machine_location, temp
    if people_people and not isFinish:
        isFinish = whoWin(isClick)
    elif man_machine and not isFinish:
        if clicks % 2 == 1:
            man_machine_location = computermove(isClick)
            chessPiecesWhite = Actor("right")
            chessPiecesWhite.left = 140 + man_machine_location % 3 * PhotoSize
            chessPiecesWhite.top = 60 + man_machine_location // 3 * PhotoSize
            chessPieces.append(chessPiecesWhite)
            isClick[man_machine_location] = 0
            clicks += 1
        isFinish = whoWin(isClick)

def on_mouse_down(pos, button):
    global PhotoSize, clicks, isClick, isFinish, man_machine, people_people, temp, one_move, flag, rightWin, wrongWin, dogfall
    if button == mouse.LEFT and not man_machine and not people_people:
        if btn1.collidepoint(pos):
            man_machine = True
        elif btn2.collidepoint(pos):
            people_people = True

    if people_people:
        if not isFinish and button == mouse.LEFT:
            flag += 1
            if flag > 1:
                for k in range(9):
                    if backgrounds[k].collidepoint(pos):
                        if clicks % 2 == 1:
                            if isClick[k] == -1:
                                chessPiecesWhite = Actor("right")
                                isClick[k] = 0
                                clicks += 1
                            elif isClick[k] == 1:
                                chessPiecesWhite = Actor("wrong")
                            else:
                                chessPiecesWhite = Actor("right")
                        elif clicks % 2 == 0:
                            if isClick[k] == -1:
                                chessPiecesWhite = Actor("wrong")
                                isClick[k] = 1
                                clicks += 1
                            elif isClick[k] == 0:
                                chessPiecesWhite = Actor("right")
                            else:
                                chessPiecesWhite = Actor("wrong")
                        chessPiecesWhite.left = 140 + k % 3 * PhotoSize
                        chessPiecesWhite.top = 60 + k // 3 * PhotoSize
                        chessPieces.append(chessPiecesWhite)
        else:
            if button == mouse.LEFT and pos[0] > 90 and pos[0] < 270 and pos[1] > 350 and pos[1] < 400:
                chessPieces.clear()
                isClick = [-1, -1, -1, -1, -1, -1, -1, -1, -1]
                flag = 1
                clicks = 0
                isFinish = False
            elif button == mouse.LEFT and pos[0] > 390 and pos[0] < 570 and pos[1] > 350 and pos[1] < 400:
                people_people = False
                flag = 0
                chessPieces.clear()
                isClick = [-1, -1, -1, -1, -1, -1, -1, -1, -1]
                isFinish = False
                wrongWin = 0
                rightWin = 0
                dogfall = 0
                clicks = 0

    elif man_machine:
        if not isFinish and button == mouse.LEFT:
            flag += 1
            if flag > 1:
                for k in range(9):
                    if backgrounds[k].collidepoint(pos):
                        temp = k
                        if clicks % 2 == 0:
                            if isClick[k] == -1:
                                chessPiecesWhite = Actor("wrong")
                                isClick[k] = 1
                                clicks += 1
                            elif isClick[k] == 0:
                                chessPiecesWhite = Actor("right")
                            else:
                                chessPiecesWhite = Actor("wrong")
                        chessPiecesWhite.left = 140 + k % 3 * PhotoSize
                        chessPiecesWhite.top = 60 + k // 3 * PhotoSize
                        chessPieces.append(chessPiecesWhite)
                        isFinish = whoWin(isClick)

                for i in range(len(one_move)):
                    if temp == one_move[i]:
                        del one_move[i]
                        break
        else:
            if button == mouse.LEFT and pos[0] > 90 and pos[0] < 270 and pos[1] > 350 and pos[1] < 400:
                chessPieces.clear()
                isClick = [-1, -1, -1, -1, -1, -1, -1, -1, -1]
                one_move = [4, 0, 2, 6, 8, 1, 3, 5, 7]
                flag = 1
                clicks = 0
                isFinish = False
            elif button == mouse.LEFT and pos[0] > 390 and pos[0] < 570 and pos[1] > 350 and pos[1] < 400:
                man_machine = False
                flag = 0
                chessPieces.clear()
                isClick = [-1, -1, -1, -1, -1, -1, -1, -1, -1]
                one_move = [4, 0, 2, 6, 8, 1, 3, 5, 7]
                isFinish = False
                wrongWin = 0
                rightWin = 0
                dogfall = 0
                clicks = 0

def whoWin(board):
    global isFinish, rightWin, wrongWin, dogfall
    _to_win = {(0, 1, 2), (3, 4, 5), (6, 7, 8), (0, 3, 6), (1, 4, 7), (2, 5, 8), (0, 4, 8), (2, 4, 6)}
    for r in _to_win:
        if board[r[0]] == board[r[1]] == board[r[2]] != -1:
            if board[r[0]] == 0:
                print("O赢了")
                rightWin += 1
                return True
            elif board[r[0]] == 1:
                print("X赢了")
                wrongWin += 1
                return True
    if -1 not in isClick:
        print("平局")
        dogfall += 1
        return True

def winner(board):
    # 判断所给棋子是否获胜
    _to_win = {(0, 1, 2), (3, 4, 5), (6, 7, 8), (0, 3, 6), (1, 4, 7), (2, 5, 8), (0, 4, 8), (2, 4, 6)}
    for r in _to_win:
        if board[r[0]] == board[r[1]] == board[r[2]] != -1:
            return True
    return False

def computermove(board):
    # 核心算法:计算AI的落子位置
    boardcopy = board.copy()

    # 规则一:判断如果某位置落子可以获胜,则选择这个位置
    for i in range(9):
        if boardcopy[i] == -1:
            boardcopy[i] = 0
            if winner(boardcopy):
                for j in range(len(one_move) - 1):
                    if i == one_move[j]:
                        del one_move[j]
                return i
            else:
                boardcopy[i] = -1

    # 规则二:某个位置玩家下一步落子就可以获胜,则选择该位置
    for i in range(9):
        if boardcopy[i] == -1:
            boardcopy[i] = 1
            if winner(boardcopy):
                for j in range(len(one_move) - 1):
                    if i == one_move[j]:
                        del one_move[j]
                return i
            else:
                boardcopy[i] = -1
    # 规则三:按照中心、角、边的选择空的位置
    for move in one_move:
        del one_move[0]
        return move

pgzrun.go()

说明

人机模式实现了简单的智能化,但是还是有方法可以赢人机的(暂时不想修改了)。Bug应该也还有但是我暂时还没有发现。嗯,就这样吧

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值