使用tkinter实现三子棋游戏

本文介绍了一个简单的五子棋游戏实现,玩家对弈,包含初步的胜利判断及平局处理。未涉及电脑AI算法,着重于基本交互界面和游戏逻辑。同时展示了TicTacToeModel的模型和核心函数,如棋盘操作和胜负检测。
摘要由CSDN通过智能技术生成

整体游戏很简单。下棋,判断胜利或者平局。没有加入电脑下棋的算法。

游戏界面:

代码:

import tkinter as tk
from tkinter import messagebox, Label, Button
from TicTacToeModel import TicTacToeModel
import requests
from PIL import ImageTk, Image
from io import BytesIO


class TicTacToeGUI:

    def __init__(self, root):
        # Create the model instance ...
        self.model = TicTacToeModel()

        # Create a 2D list to hold an array of buttons ...
        self.b = []
        for row in range(self.model.boardSize):
            q = []
            for col in range(self.model.boardSize):
                q.append(None)
            self.b.append(q)
        # You can now address b like a 2D matrix e.g. b[0][0]

        # Create the GUI .....
        menubar = tk.Menu()

        menubar.add_command(label='ResetGame', command=self.resetGUI)
        menubar.add_command(label='ResetImage', command=self.resetImg)
        menubar.add_command(label='Quit', command=root.destroy)
        root.config(menu=menubar)
        self.frame1 = tk.Frame(root, width=400, height=300, bg="GREY", borderwidth=2)
        self.frame2 = tk.Frame(root, width=400, height=200, bg="WHITE", borderwidth=2)
        self.createGUIAssets()
        self.createframe2()
        self.frame2.pack()
        self.frame1.pack()

        messagebox.showinfo("Hello", "Human player to start!")

    def getImg(self):
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36'
        }
        # img_src = ' https://api.ixiaowai.cn/api/api.php'
        img_src = ' https://api.ixiaowai.cn/gqapi/gqapi.php'
        response = requests.get(url=img_src, headers=headers)
        # print(response)
        image = Image.open(BytesIO(response.content))
        x, y = image.size
        y_s = 200
        x_s = int(x * y_s / y)
        img = image.resize((x_s, y_s), Image.ANTIALIAS)
        image = ImageTk.PhotoImage(img)
        return image

    def resetImg(self):
        self.image = self.getImg()
        self.Label.config(image=self.image)

    def createframe2(self):
        self.image = self.getImg()
        self.Label = tk.Label(self.frame2, image=self.image)
        self.Label.pack()
        # image.show()

    def createGUIAssets(self):
        for x in range(self.model.boardSize):
            self.frame1.columnconfigure(x, pad=20)
            self.frame1.grid_rowconfigure(x, pad=20)

        for row in range(self.model.boardSize):
            for col in range(self.model.boardSize):
                self.b[row][col] = Button(self.frame1, text='', bg='WHITE',
                                          relief='groove', borderwidth=20,
                                          height=3, width=8,
                                          command=lambda row=row, col=col: self.takeTurn(row, col))
                self.b[row][col].grid(row=row, column=col)

    def takeTurn(self, row, col):
        if not self.model.playSpace(row, col):
            return
        else:
            self.b[row][col].configure(bg="Green")
            status = self.model.checkWinStatus()
            if status == 1:  # Player win
                messagebox.showinfo("Result", "Player wins!!!!")
                self.resetGUI()
            elif status == 0:  # Draw
                messagebox.showinfo("Result", "Draw!!!!")
                self.resetGUI()
            elif status == -2:  # On going ...
                (r, c) = self.model.computerTurn()
                self.b[r][c].configure(bg='red')
                if self.model.checkWinStatus() == -1:
                    messagebox.showinfo("Result", "Computer wins!!!!")
                    self.resetGUI()
            else:
                # Should not get here ...
                pass

    def resetGUI(self):
        for row in range(self.model.boardSize):
            for col in range(self.model.boardSize):
                self.b[row][col].configure(bg='WHITE')
        # And reset the model ...
        self.model.resetBoard()
        self.resetImg()


def main():
    win = tk.Tk()  # Create a window
    win.title("noughts-and-crosses")  # Set window title
    win.geometry("400x580")  # Set window size
    win.resizable(False, False)  # Both x and y dimensions ...

    # Create the GUI as a Frame
    # and attach it to the window ...
    myApp = TicTacToeGUI(win)

    # Call the GUI mainloop ...
    win.mainloop()


if __name__ == "__main__":
    main()
TicTacToeModel:
import numpy as np
import random


class TicTacToeModel:
    """ The board is represented as 2D numpy array.
        A player marks their space with a 1, the
        computer with a -1"""

    def __init__(self):
        """Create the board as a 2D matrix"""
        self.resetBoard()

    def resetBoard(self):
        self.boardSize = 3
        a = (self.boardSize, self.boardSize)
        self.board = np.zeros(a)

    def playSpace(self, row, col):
        """User plays a space
        Return True if space can be played, False otherwise"""
        if row > self.boardSize or row < 0 \
                or col > self.boardSize or col < 0:
            return False
        else:
            # Check if space is occupied ...
            if self.board[row][col] != 0:
                return False
            else:
                self.board[row][col] = 1
                return True

    def checkWinStatus(self):
        """ Looks for 3 in a row, column or diagonal
            Return 0 if draw, 1 if the player has won
            and -1 if the computer has won, and -2 is the game is
            ongoing"""
        # Check the columns ...
        for row in range(self.boardSize):
            sum = 0
            for col in range(self.boardSize):
                sum += self.board[row][col]
            if sum == 3:
                return 1
            elif sum == -3:
                return -1
        # Check the rows ...
        for col in range(self.boardSize):
            sum = 0
            for row in range(self.boardSize):
                sum += self.board[row][col]
            if sum == 3:
                return 1
            elif sum == -3:
                return -1

        # Check the diagonals ...
        sum1 = 0
        sum2 = 0
        for diag in range(self.boardSize):
            sum1 += self.board[diag][diag]
            sum2 += self.board[diag][self.boardSize - 1 - diag]
        if sum1 == 3 or sum2 == 3:
            return 1
        elif sum1 == -3 or sum2 == -3:
            return -1

        # Check for incomplete game ...
        for row in range(self.boardSize):
            for col in range(self.boardSize):
                if self.board[row][col] == 0:
                    return -2

        # If we get here, it's a draw ...
        return 0

    def computerTurn(self):
        """ The computer chooses an unoccupied
            space at random. Returns a tuple
            (row, col) when chosen"""
        # To prevent infinite loops ....
        if self.checkWinStatus() != -2:
            return (-1, -1)
        played = False

        while played == False:
            row = random.randrange(self.boardSize)
            col = random.randrange(self.boardSize)
            if self.board[row][col] == 0:
                self.board[row][col] = -1
                played = True

        return (row, col)


def main():
    # Basic check that the game works ...
    # You can expand this if you like ...
    game = TicTacToeModel()

    game.playSpace(0, 0)
    (r, c) = game.computerTurn()
    print(game.board)
    print(game.checkWinStatus())


if __name__ == "__main__":
    main()

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值