用tkinter的Python棋盘游戏

用tkinter的Python棋盘游戏,python,tkinter,Python,Tkinter,我正在尝试创建一个python游戏,玩家可以点击棋盘,用自己的颜色填充棋盘,直到游戏完成,有更多填充框的玩家获胜。 如果你点击一个方框,并且任何相邻的方框都填充了其他玩家的颜色,它会将颜色更改为你的颜色,我找到了这个棋盘代码,但我无法让它填充相邻的方框 import Tkinter as tk board = [ [None]*10 for _ in range(10) ] counter = 0 root = tk.Tk() def on_click(i,j,event): g

我正在尝试创建一个python游戏,玩家可以点击棋盘,用自己的颜色填充棋盘,直到游戏完成,有更多填充框的玩家获胜。 如果你点击一个方框,并且任何相邻的方框都填充了其他玩家的颜色,它会将颜色更改为你的颜色,我找到了这个棋盘代码,但我无法让它填充相邻的方框

import Tkinter as tk

board = [ [None]*10 for _ in range(10) ]

counter = 0

root = tk.Tk()

def on_click(i,j,event):
    global counter
    color = "green" if counter%2 else "red"
    event.widget.config(bg=color)
    board[i][j] = color
    counter += 1


for i,row in enumerate(board):
    for j,column in enumerate(row):
        L = tk.Label(root,text='    ',bg='grey')
        L.grid(row=i,column=j,padx='3',pady='3')
        L.bind('<Button-1>',lambda e i=i,j=j: on_click(i,j,e))

root.mainloop()
将Tkinter作为tk导入
board=[[None]*10表示范围内(10)]
计数器=0
root=tk.tk()
单击时的def(i、j、事件):
全局计数器
color=“绿色”如果计数器%2,否则为“红色”
event.widget.config(bg=color)
板[i][j]=颜色
计数器+=1
对于i,枚举中的行(板):
对于j,枚举(行)中的列:
L=tk.Label(根,文本='',bg='grey')
L.网格(行=i,列=j,padx='3',pady='3')
L.bind(“”,lambda e i=i,j=j:on_单击(i,j,e))
root.mainloop()

问题:当玩家点击一个方框时,我如何才能做到这一点?相邻的方框中已经充满了敌人的颜色,也会变成红色/绿色?另外,我如何计算特定颜色的填充框的数量,以确定谁获胜?谢谢您的帮助。

如果您将标签存储在
板中,则可以使用

board[i][j]['bg']
您可以使用更改背景颜色

board[i][j].config(bg=...)
甚至

board[i][j]['bg'] = ...

由于您希望访问
线路板上某个点的相邻点
,因此自然会使用
for loop
s,例如:

for ii in range(i - 1, i + 2):
    for jj in range(j - 1, j + 2):
或者,等效但嵌套使用较少:

现在您可以使用
board[ii][jj]
访问邻居,记住
ii
jj
可能是一个越界索引。我们可以使用
if
-语句处理越界索引:

if ii<0 or ii>=rows or jj<0 or jj>=cols: continue

将Tkinter作为tk导入
按原样导入itertools
导入集合
cols,rows=3,3
board=[[None]*cols用于范围内(行)]
其他={'green':'red','red':'green'}
玩家=‘红色’
单击时的def(事件,i,j):
全球玩家
棋盘[i][j]['bg']=玩家
对于ii,IT产品中的jj(范围(i-1,i+2),范围(j-1,j+2)):
如果ii=行或jj=列:继续
邻居=董事会[ii][jj]
如果邻居['bg']!='灰色和(ii,jj)!=(i,j):
邻居['bg']=其他[邻居['bg']]
检查是否有优胜者()
玩家=其他[玩家]
def check_for_winner():
s=分数()
如果s['red']+s['green']==cols*行:
#每个盒子都装满了
胜利者=最大值(s,key=s.get)
打印('获胜者是:{}'。格式(获胜者))
root.after(1,flash_winner,winner,'blue')
def分数():
退换货。柜台(
板[i][j]['bg']用于IT中的i,j.产品(范围(行),范围(列)))
def flash_优胜者(优胜者,altcolor):
对于IT.product中的i,j(范围(行),范围(列)):
如果董事会[i][j]['bg']==获胜者:
板[i][j][bg']=altcolor
root.after(250,flash_优胜者,altcolor优胜者)
root=tk.tk()
对于IT.product中的i,j(范围(行),范围(列)):
board[i][j]=L=tk.Label(根,文本='',背景=''灰色')
L.网格(行=i,列=j,padx=3,pady=3)
L.bind(“”,λe,i=i,j=j:on_单击(e,i,j))
root.mainloop()

这花了一段时间!以下是我的版本:

import Tkinter as tk
import TkMessageBox as messagebox

board = [ [None]*10 for _ in range(10) ]

counter = 0
root = tk.Tk()

def check_board():
    freespaces = 0
    redspaces = 0
    greenspaces = 0
    for i,row in enumerate(board):
        for j,column in enumerate(row):
            if board[i][j] == "red":
                redspaces += 1
            elif board[i][j] == "green":
                greenspaces += 1
            elif board[i][j] == None:
                freespaces += 1

    if freespaces == 0:
        if greenspaces > redspaces:
            winner = "green"
        elif greenspaces < redspaces:
            winner = "red"
        else:
            winner = "draw"

        if winner != "draw":
            messagebox.showinfo("Game Over!",winner+" wins!")
        else:
            messagebox.showinfo("Game Over!","The game was a draw!")




def on_click(i,j,event):
    global counter
    if counter < 100:
        if board[i][j] == None:
            color = "green" if counter%2 else "red"
            enemycolor = "red" if counter%2 else "green"
            event.widget.config(bg=color)
            board[i][j] = color
            for k in range(-1,2):
                for l in range(-1,2):
                    try:
                        if board[i+k][j+l] == enemycolor:
                            board[i+k][j+l] = color
                    except IndexError:
                        pass
            counter += 1
            global gameframe
            gameframe.destroy()
            redraw()
            root.wm_title(enemycolor+"'s turn")
        else:
            messagebox.showinfo("Alert","This square is already occupied!")
        check_board()


def redraw():
    global gameframe
    gameframe = tk.Frame(root)
    gameframe.pack()

    for i,row in enumerate(board):

        for j,column in enumerate(row):
            name = str(i)+str(j)
            L = tk.Label(gameframe,text='    ',bg= "grey" if board[i][j] == None else board[i][j])
            L.grid(row=i,column=j,padx='3',pady='3')
            L.bind('<Button-1>',lambda e,i=i,j=j:on_click(i,j,e))


redraw()
root.mainloop()

谢谢!现在我要学习一些你以前理解的东西。谢谢你的帮助!我有个问题。是否有可能将关于哪个玩家回合的警告作为标签放在棋盘顶部而不是窗口中,或者需要重新编码棋盘并创建一个类?我对董事会的创建方式感到困惑。是的!更新答案,将最后一部分添加到重画函数。理想情况下,您应该从头开始重新创建整个程序,并在类中正确地编写代码以了解更多信息。使用self传递变量要好得多。和Tk变量,而不是使用混乱的全局变量。
import collections
collections.Counter(
        board[i][j]['bg'] for i, j in IT.product(range(rows), range(cols)))
import Tkinter as tk
import itertools as IT
import collections

cols, rows = 3, 3
board = [[None] * cols for _ in range(rows)]    
other = {'green': 'red', 'red': 'green'}

player = 'red'   

def on_click(event, i, j):
    global player
    board[i][j]['bg'] = player
    for ii, jj in IT.product(range(i - 1, i + 2), range(j - 1, j + 2)):
        if ii<0 or ii>=rows or jj<0 or jj>=cols: continue
        neighbor = board[ii][jj]
        if neighbor['bg'] != 'grey' and (ii, jj) != (i, j):
            neighbor['bg'] = other[neighbor['bg']]
    check_for_winner()
    player = other[player]

def check_for_winner():
    s = score()
    if s['red'] + s['green'] == cols*rows:
        # every box filled
        winner = max(s, key=s.get)
        print('Winner is: {}'.format(winner))
        root.after(1, flash_winner, winner, 'blue')

def score():
    return collections.Counter(
        board[i][j]['bg'] for i, j in IT.product(range(rows), range(cols)))

def flash_winner(winner, altcolor):
    for i, j in IT.product(range(rows), range(cols)):
        if board[i][j]['bg'] == winner:
            board[i][j]['bg'] = altcolor
    root.after(250, flash_winner, altcolor, winner)

root = tk.Tk()
for i, j in IT.product(range(rows), range(cols)):
    board[i][j] = L = tk.Label(root, text='    ', bg='grey')
    L.grid(row=i, column=j, padx=3, pady=3)
    L.bind('<Button-1>', lambda e, i=i, j=j: on_click(e, i, j))

root.mainloop()
import Tkinter as tk
import TkMessageBox as messagebox

board = [ [None]*10 for _ in range(10) ]

counter = 0
root = tk.Tk()

def check_board():
    freespaces = 0
    redspaces = 0
    greenspaces = 0
    for i,row in enumerate(board):
        for j,column in enumerate(row):
            if board[i][j] == "red":
                redspaces += 1
            elif board[i][j] == "green":
                greenspaces += 1
            elif board[i][j] == None:
                freespaces += 1

    if freespaces == 0:
        if greenspaces > redspaces:
            winner = "green"
        elif greenspaces < redspaces:
            winner = "red"
        else:
            winner = "draw"

        if winner != "draw":
            messagebox.showinfo("Game Over!",winner+" wins!")
        else:
            messagebox.showinfo("Game Over!","The game was a draw!")




def on_click(i,j,event):
    global counter
    if counter < 100:
        if board[i][j] == None:
            color = "green" if counter%2 else "red"
            enemycolor = "red" if counter%2 else "green"
            event.widget.config(bg=color)
            board[i][j] = color
            for k in range(-1,2):
                for l in range(-1,2):
                    try:
                        if board[i+k][j+l] == enemycolor:
                            board[i+k][j+l] = color
                    except IndexError:
                        pass
            counter += 1
            global gameframe
            gameframe.destroy()
            redraw()
            root.wm_title(enemycolor+"'s turn")
        else:
            messagebox.showinfo("Alert","This square is already occupied!")
        check_board()


def redraw():
    global gameframe
    gameframe = tk.Frame(root)
    gameframe.pack()

    for i,row in enumerate(board):

        for j,column in enumerate(row):
            name = str(i)+str(j)
            L = tk.Label(gameframe,text='    ',bg= "grey" if board[i][j] == None else board[i][j])
            L.grid(row=i,column=j,padx='3',pady='3')
            L.bind('<Button-1>',lambda e,i=i,j=j:on_click(i,j,e))


redraw()
root.mainloop()
global counter
whosturn = "Green" if counter%2 else "Red"
turnLbl = tk.Label(gameframe,text=color+"'s Turn")
turnLbl.grid(row=11,column = 0,columnspan = 10)