'Event' object is not subscriptable - python

I am trying to write a tic-tac-toe in Python but I get this error: 'Event' object is not subscriptable
The general idea is that when a button is pressed, if it doesn't have a text, it will change it's text in an "X" or "O" depending on the turn.
But I am stuck due to this error.
I have not much experience with Python so I need a fix easy to understand and implement. Thanks!
Code:
from tkinter import *
window = Tk()
btn = [None] * 9
btn_id = [None] * 9
#position of button array
def BTNposition():
i = 0
c = 0
k = 0
while i < 9:
#declaration of button array
btn[i] = Button(window, text = "", height = 10, width = 20, borderwidth = 5, command = lambda i=i: GAME)
btn[i].place(x= c, y= k)
btn_id[i] = btn[i]
print(btn[i], btn_id[i])
i+= 1
if c == 300:
k += 150
c = 0
else:
c += 150
BTNposition()
def GAME(btn):
turn = 0
if btn["text"] == "" and turn % 2 == 0: #here the error
btn.config(text = "X")
turn += 1
elif btn["text"] == "" and turn % 2 == 1:
btn.config(text = "O")
turn += 1
i = 0
#while i < 9:
#btn[i].bind("<Button 1>", GAME)
#find button pressed
window.bind("<Button 1>", GAME)
#print(click_position.btnp_x, click_position.btnp_y)
window.title('PyTris')
window.geometry("700x450")
window.mainloop()
I will update the post whenever I do major changes to the code.

Several problems:
window.bind("<Button 1>", GAME) a useless button that calls to GAME without providing a parameter hence it getting provided the default ButtonPressEvent as parameter which GAME is indexing into wich leads to the reported error
no exact button placement although you calculate positions
confused usages of = vs == inside GAME function
use of global variables with danger of confusing global and local identically named ones
variable names reused (or not used at all in case of the lambda i)
Fixing your code with minimalistic changes to it:
from tkinter import *
window = Tk()
btn = [None] * 9
turn = 0
#position of button array
def BTNposition():
c, k = 0, 0
for i in range(9):
# put button in array, callback is provided with the buttons index
# in the global array holding all the buttons
btn[i] = Button(window, text="", height=10, width=20, borderwidth=5,
command= lambda idx=i: GAME(idx))
# fix button on coordinates
btn[i].place(x=c, y=k)
if c == 300:
k += 150
c = 0
else:
c += 150
# btn_nr is supposed to be an index into the global btn-array holding your buttons
def GAME(btn_nr):
global turn # turn count is held globally, we want to modify it
button = btn[btn_nr] # get the button we are at
# only allow modification on buttons that are not yet X or O
if button["text"] == "":
# place the correct marker and advance turns
button["text"] = "X" if turn % 2 == 0 else "O"
turn += 1
BTNposition()
window.title('PyTris')
window.geometry("700x450")
window.mainloop()

Related

How Do I add reset button on Python

Can someone help me add a reset button oroption?
I am a beginner and I could not find how to do this, hope somebody can help me. It's a python card matching game, it's a school project so it doesn't need to be the best looking, I just need to put a option to restart the game
import random
import time
from tkinter import Tk, Button, DISABLED, messagebox
def close_window(self):
root.destroy()
def show_symbol(x, y):
global first
global previousX, previousY
global moves
global pairs
buttons[x, y]['text'] = button_symbols[x, y]
buttons[x, y].update_idletasks()
if first:
previousX = x
previousY = y
first = False
moves = moves + 1
elif previousX != x or previousY != y:
if buttons[previousX, previousY]['text'] != buttons[x, y]['text']:
time.sleep(0.5)
buttons[previousX, previousY]['text'] = ''
buttons[x, y]['text'] = ''
else:
buttons[previousX, previousY]['command'] = DISABLED
buttons[x, y]['command'] = DISABLED
pairs = pairs + 1
if pairs == len(buttons) / 2:
messagebox.showinfo('Matching', 'Broj poteza: ' + str(moves))
first = True
root = Tk()
root.title('Igra Memorije')
root.resizable(width=False, height=False)
buttons = {}
first = True
previousX = 0
previousY = 0
moves = 0
pairs = 0
button_symbols = {}
symbols = [u'\u2702', u'\u2702', u'\u2705', u'\u2705', u'\u2708', u'\u2708',
u'\u2709', u'\u2709', u'\u270A', u'\u270A', u'\u270B', u'\u270B',
u'\u270C', u'\u270C', u'\u270F', u'\u270F', u'\u2712', u'\u2712',
u'\u2714', u'\u2714', u'\u2716', u'\u2716', u'\u2728', u'\u2728',
]
random.shuffle(symbols)
for x in range(6):
for y in range(4):
button = Button(command=lambda x=x, y=y: show_symbol(x, y), width=5, height=3, border=2)
button.grid(column=x, row=y,padx=15,pady=20)
buttons[x, y] = button
button_symbols[x, y] = symbols.pop()
root.mainloop()
this is the code hope you dont find it messy
To keep your coding style, I'd do something like this:
import random
import time
from tkinter import Tk, Button, DISABLED, messagebox
def close_window(self):
root.destroy()
def show_symbol(x, y):
global first
global previousX, previousY
global moves
global pairs
buttons[x, y]['text'] = button_symbols[x, y]
buttons[x, y].update_idletasks()
if first:
previousX = x
previousY = y
first = False
moves = moves + 1
elif previousX != x or previousY != y:
if buttons[previousX, previousY]['text'] != buttons[x, y]['text']:
time.sleep(0.5)
buttons[previousX, previousY]['text'] = ''
buttons[x, y]['text'] = ''
else:
buttons[previousX, previousY]['command'] = DISABLED
buttons[x, y]['command'] = DISABLED
pairs = pairs + 1
if pairs == len(buttons) / 2:
messagebox.showinfo('Matching', 'Broj poteza: ' + str(moves))
for k in tuple(buttons):
buttons.pop(k).grid_forget()
Button(root, text='Restart', command=start).grid(padx=15, pady=20)
first = True
root = Tk()
root.title('Igra Memorije')
root.resizable(width=False, height=False)
buttons = {}
first = True
previousX = 0
previousY = 0
moves = 0
pairs = 0
button_symbols = {}
symbols = [u'\u2702', u'\u2702', u'\u2705', u'\u2705', u'\u2708', u'\u2708',
u'\u2709', u'\u2709', u'\u270A', u'\u270A', u'\u270B', u'\u270B',
u'\u270C', u'\u270C', u'\u270F', u'\u270F', u'\u2712', u'\u2712',
u'\u2714', u'\u2714', u'\u2716', u'\u2716', u'\u2728', u'\u2728',
]
def start():
global buttons
global symbols
global first
global previousX, previousY
global moves
global pairs
first = True
previousX = 0
previousY = 0
moves = 0
pairs = 0
random.shuffle(symbols)
for child in root.winfo_children():
child.grid_forget()
width, height = 6, 4
for x in range(width):
for y in range(height):
button = Button(root, command=lambda x=x, y=y: show_symbol(x, y), width=5, height=3, border=2)
button.grid(column=x, row=y,padx=15,pady=20)
buttons[x, y] = button
button_symbols[x, y] = symbols[x * height + y]
Button(root, text='Start', command=start).grid(padx=15,pady=20)
root.mainloop()
The things I've changed:
Added a new function start that can initialize the game (and the buttons).
Added start and restart buttons at the beginning and when game ends.
symbols is no more popped, because otherwise you wouldn't have any more symbols for the second game.
When switching from starting the game to the actual game (and vice versa), all the widgets on the root are grid_forget so that you can delete any shown button and display instead some new buttons.
Your game is really nice. If you want some simple improvements from here, I'd suggest you to:
Have symbols with only unique unicodes, and then just doing symbols *= 2 so that you avoid bothering with whether you've duplicated all the symbols or not.
Instanciate your game as a class. In this way, you avoid using global variables which may mess up you program.
Fix a size of your window so that it does not shrink and enlarge when switching game.
Determine the width and height of your grid automatically, to avoid defining ranges "4" and "6".

Countup method using Python (Tkinter)

I got my motivation from this post: Incerasing number by every second +1 in Tkinter label
So I decided to make a Scoreboard with Tkinter and I am about to pull my hair out because I know its a basic question with a most likely obvious answer, I just cant figure it out.
Its a football scoreboard. Comprised of 4 buttons
score_dict = {"Touchdown": 6, "Extra Point": 1, 'Field Goal': 3, "Conversion": 2, "Safety": 2}
Every time I hit the button I want the label to reflect the score but I cant figure out how to keep the previous amount of the label and add on to it.
So if the label reads 6 and I add a field goal it should read 10 instead of starting over again.
# Creating label + buttons and putting them on screen
label = Label(root, text=0)
buttons = [Button(root, text=i, command=lambda i=i: press(i)) for i in score_dict.keys()]
for i in range(len(buttons)):
buttons[i].grid(row=1, column=i)
label.grid(row=0, column=2)
# press function from button list comprehension:
def press(i):
global label
if score_dict[i] == 6:
if label['text'] < score_dict[i]:
label['text'] += 1
root.after(100, press, i)
if score_dict[i] == 1:
if label['text'] < score_dict[i]:
label['text'] += 1
root.after(100, press, i)
if score_dict[i] == 3:
if label['text'] < score_dict[i]:
label['text'] += 1
root.after(100, press, i)
if score_dict[i] == 2:
if label['text'] < score_dict[i]:
label['text'] += 1
root.after(100, press, i)
The problem is the if statement. When I press the button once, just as long as the score is more than the label reads it doesn't fit any of the conditions but I'm not sure how else to phrase it.
I posted this all over Reddit for 5 days with no answers and I'm ready to give up on it.
I've made necessary changes to function press. Code requires a working dictionary to keep track of score and a static dictionary to reset the testing statement.
Total score is in label.
import tkinter as tk
score_dict = {"Touchdown": 6, "Extra Point": 1,
"Field Goal": 3, "Conversion": 2,
"Safety": 2}
working_dict = score_dict.copy()
root = tk.Tk()
label = tk.Label(root, text = 0)
label.grid(sticky = tk.NSEW)
def press(i):
if working_dict[i] > 0:
working_dict[i] -= 1
label['text'] += 1
root.after(100, press, i)
else:
working_dict[i] = score_dict[i]
buttons = [tk.Button(root, text = i, command = lambda i = i: press(i)) for i in score_dict.keys()]
for i in range(len(buttons)):
buttons[i].grid(row = 1, column = i)
root.mainloop()

Python Tkinter Multiple buttons are getting created on clicking on radio buttons

These are few lines from my actual code - I am aware this is not the best way of writing a code, but as I am new and getting familiarize with Tkinter (py2) consider this as my scratch work.
I am listing a question and multiple options. When the user selects an option, a SUBMIT button is created and when clicks on SUBMIT button it will accordingly change the color of Option to green or red. If green then another NEXT button will be available to clean and move to next question.
The issue that I am facing is if a user selects option A but then without clicking the SUBMIT button selects another option the submit button multiplies. I want to destroy the unwanted buttons or even do not want to create multiple SUBMIT buttons.
Please do help in achieving the same.
import Tkinter
from Tkinter import *
import yaml
import random
grey = "#808080"
offwhite = "#e3e3e3"
filepath = "chapter-2.yaml"
tk = Tkinter.Tk()
tk.title("iCodet Learnings")
tk.geometry("800x600")
x = ''
tk.config(background=offwhite)
tk.resizable(0,0)
q_count = 0
def yaml_loader(filepath):
with open (filepath, "r") as fileread:
data = yaml.load(fileread)
return data
def cleaner(hint):
global rbutton
global q_count
global quest_label
global radio1
global button_game
quest_label.destroy()
radio1.destroy()
# destroys the radio buttons
for b in rbutton:
b.destroy()
# destroys the SUBMIT button
button_game.destroy()
# go to ext question
if hint == 'next':
q_count += 1
game_loop()
# This is display the first element from the yaml i.e the question
def display_question(questions, qc):
global quest_label
q = questions.keys()[qc]
a = questions[q]
v = a.keys()
quest_label = Label(tk, text = q, font = ("Consolas", 16), width = 500, justify = "center", wraplength = 400)
quest_label.pack(pady = (50,0))
return v
# This is for selecting the radio buttons
def selected():
global radio_default, button_next,radio1, val
global x, data,q_count, vali, rbutton, select_val
x = radio_default.get()
select_val = rbutton[x]
if q_count <= len(data):
q = data.keys()[q_count]
a = data[q] #second dictionary
v = a.keys() #second dictionary keys
# True or False from Yaml
val = a[v[x]][0]
press_button(val)
else:
print ("Mid way")
# This will list all the options under question
def display_answer(ans):
global radio1, rbutton
global x, q_count
global radio_default
radio_default = IntVar()
rbutton = []
rad_select = []
val_count = 0
for i in ans:
radio1 = Radiobutton(tk, text = i, font = ("times", 14, "bold"), value = val_count, variable = radio_default, command = selected, background = 'NavajoWhite3')
rbutton.append(radio1)
val_count += 1
radio1.pack(pady = (30,0))
radio_default.set(-1)
# This displays the SUBMIT buuton
def press_button(val):
global button_game
# true
if val:
button_game = Button(tk, text = 'SUBMIT', font = ("default", 15, "bold"), bg='orange', fg = 'white', border=2, height = 2, width = 8, command = lambda: cleaner('next'))
button_game.pack(pady = (30,0))
# false
elif not val:
print "Do nothing"
button_game = Button(tk, text = 'SUBMIT', font = ("default", 15, "bold"), bg='orange', fg = 'white', border=2, height = 2, width = 8, command = lambda: cleaner('stay'))
button_game.pack(pady = (30,0))
return True
def game_loop():
global q_count
global x, data
global quest_label, button_game
action = True
data = yaml_loader(filepath)
if q_count <= len(data)-1:
l_ans = display_question(data, q_count)
display_answer(l_ans)
else:
txt_label = Label(tk, text = "CONGRATULATIONS ON COMPLETING CHAPTER", font = ("Comicsans", 24, "bold"), background = offwhite, wraplength = 700)
txt_label.pack(pady = (100,0))
button_end = Button(tk, text = 'THANK YOU !', font = ("default", 15, "bold"), bg='saddle brown', fg = 'white', border=2, height = 3, width = 10, command = tk.destroy)
button_end.pack(pady = (50,0))
game_loop()
tk.mainloop()
chapter-1.yaml
> "What’s the complete name of Sachin Tendulkar ?":
> "Sachin Ramya Tendulkar":
> - False
> "Sachin Ramesh Tendulkar":
> - True
> "Sachin Tendehar":
> - False
> " Sachin 10dulkar":
> - False
> "Hint":
> - "biscuit & cookies"
As things are, each time press_button() is run, a new Button object is generated, and placed in the button_game variable. This does not remove or hide the previous button, which still exists in the packed UI.
A simple solution that would save the machine some work is to initialize the button only once, earlier in the code, but omit placing/displaying/packing it until that block within press_button() is run.
I was able to achieve what I was looking for with the help of config.
I created the SUBMIT button once at the beginning and then instead of calling the whole function again and again; I just replaced press_button with button_game.config(command = lambda: right(chapter, num_ques, topic, val))
Now I should write this code using class in python.

Python Tkinter Grid Checkbox

I was wondering if there is an easy way to create a grid of checkboxes using Tkinter. I am trying to make a grid of 10 rows and columns (so 100 checkboxes) so that only two checkboxes can be selected per row.
Edit: I'm using python 2.7 with spyder
What I have so far:
from Tkinter import*
master = Tk()
master.title("Select Groups")
rows=10
columns=10
for x in range(rows):
for y in range(columns):
Label(master, text= "Group %s"%(y+1)).grid(row=0,column=y+1)
Label(master, text= "Test %s"%(x+1)).grid(row=x+1,column=0)
Checkbutton(master).grid(row=x+1, column=y+1)
mainloop()
I'm trying to use state='Disabled' to grey out a row once two checkboxes have been selected.
Here's a version that puts everything into a class so we don't need to use global variables. It also avoids the import * construction which is generally considered bad style in Python. True, lots of example code uses import * but it's not a good practice because it clutters up the global namespace with all the names from the imported module. So those names can clash with the names of your own variables, and they can also clash with the names of other modules you import using import *.
The program prints lists of the selected Groups for each Test row when the window closes.
#!/usr/bin/env python
''' Create a grid of Tkinter Checkbuttons
Each row permits a maximum of two selected buttons
From http://stackoverflow.com/q/31410640/4014959
Written by PM 2Ring 2015.07.15
'''
import Tkinter as tk
class CheckGrid(object):
''' A grid of Checkbuttons '''
def __init__(self, rows=10, columns=10):
master = tk.Tk()
master.title("Select Groups")
rowrange = range(rows)
colrange = range(columns)
#Create the grid labels
for x in colrange:
w = tk.Label(master, text="Group %s" % (x + 1))
w.grid(row=0, column=x+1)
for y in rowrange:
w = tk.Label(master, text="Test %s" % (y + 1))
w.grid(row=y+1, column=0)
#Create the Checkbuttons & save them for future reference
self.grid = []
for y in rowrange:
row = []
for x in colrange:
b = tk.Checkbutton(master)
#Store the button's position and value as attributes
b.pos = (y, x)
b.var = tk.IntVar()
#Create a callback bound to this button
func = lambda w=b: self.check_cb(w)
b.config(variable=b.var, command=func)
b.grid(row=y+1, column=x+1)
row.append(b)
self.grid.append(row)
#Track the number of on buttons in each row
self.rowstate = rows * [0]
master.mainloop()
def check_cb(self, button):
''' Checkbutton callback '''
state = button.var.get()
y, x = button.pos
#Get the row containing this button
row = self.grid[y]
if state == 1:
self.rowstate[y] += 1
if self.rowstate[y] == 2:
#Disable all currently off buttons in this row
for b in row:
if b.var.get() == 0:
b.config(state=tk.DISABLED)
else:
self.rowstate[y] -= 1
if self.rowstate[y] == 1:
#Enable all currently off buttons in this row
for b in row:
if b.var.get() == 0:
b.config(state=tk.NORMAL)
#print y, x, state, self.rowstate[y]
def get_checked(self):
''' Make a list of the selected Groups in each row'''
data = []
for row in self.grid:
data.append([x + 1 for x, b in enumerate(row) if b.var.get()])
return data
def main():
g = CheckGrid(rows=10, columns=10)
#Print selected Groups in each Test row when the window closes
data = g.get_checked()
for y, row in enumerate(data):
print "Test %2d: %s" % (y + 1, row)
if __name__ == '__main__':
main()
Here's an example using your provided 10x10 grid. It should give you the basic idea of how to implement this.
Just make sure you keep a reference to every Checkbutton (boxes in the example) as well as every IntVar (boxVars in the example).
Here's why:
-Checkbuttons are needed to call config(state = DISABLED/NORMAL).
-IntVars are needed to determine the value of each Checkbutton.
Aside from those crucial elements its basically just some 2D array processing.
Here's my example code (now based off of your provided code).
from Tkinter import *
master = Tk()
master.title("Select Groups")
rows=10
columns=10
boxes = []
boxVars = []
# Create all IntVars, set to 0
for i in range(rows):
boxVars.append([])
for j in range(columns):
boxVars[i].append(IntVar())
boxVars[i][j].set(0)
def checkRow(i):
global boxVars, boxes
row = boxVars[i]
deselected = []
# Loop through row that was changed, check which items were not selected
# (so that we know which indeces to disable in the event that 2 have been selected)
for j in range(len(row)):
if row[j].get() == 0:
deselected.append(j)
# Check if enough buttons have been selected. If so, disable the deselected indeces,
# Otherwise set all of them to active (in case we have previously disabled them).
if len(deselected) == (len(row) - 2):
for j in deselected:
boxes[i][j].config(state = DISABLED)
else:
for item in boxes[i]:
item.config(state = NORMAL)
def getSelected():
selected = {}
for i in range(len(boxVars)):
temp = []
for j in range(len(boxVars[i])):
if boxVars[i][j].get() == 1:
temp.append(j + 1)
if len(temp) > 1:
selected[i + 1] = temp
print selected
for x in range(rows):
boxes.append([])
for y in range(columns):
Label(master, text= "Group %s"%(y+1)).grid(row=0,column=y+1)
Label(master, text= "Test %s"%(x+1)).grid(row=x+1,column=0)
boxes[x].append(Checkbutton(master, variable = boxVars[x][y], command = lambda x = x: checkRow(x)))
boxes[x][y].grid(row=x+1, column=y+1)
b = Button(master, text = "Get", command = getSelected, width = 10)
b.grid(row = 12, column = 11)
mainloop()

Python: Connect 4 with TKinter

Alrighty I'm trying to implement a GUI for a game of Connect Four by using TKinter. Now I have the grid and everything set up what I'm having trouble with is getting the chip to show up on the board.
Here is my output:
What I'm trying to do is make it so when I click one of the bottom column buttons a chip appears (and since this is connect four it should go from bottom to top)
Here is my code:
from Tkinter import *
from connectfour import *
from minimax import *
from player import *
import tkMessageBox
class ConnectFourGUI:
def DrawGrid(self):
for i in range(0,self.cols+1):
self.c.create_line((i+1)*self.mag,self.mag,\
(i+1)*self.mag,(self.rows+1)*self.mag)
for i in range(0,self.rows+1):
self.c.create_line(self.mag,(i+1)*self.mag,\
self.mag*(1+self.cols),(i+1)*self.mag)
def __init__(self,wdw):
wdw.title("Connect Four")
self.mag = 60
self.rows = 6
self.cols = 7
self.c = Canvas(wdw,\
width=self.mag*self.cols+2*self.mag,\
height = self.mag*self.rows+2*self.mag,\
bg='white')
self.c.grid(row=1,column=1,columnspan=2)
rlabel=Label(root, text="Player1:")
rlabel.grid(row=0,column=0)
self.player1_type=StringVar(root)
options= ["Human", "Random", "Minimax"]
self.player1_type.set(options[2])
self.rowbox=OptionMenu(root, self.player1_type, *options)
self.rowbox.grid(row=0, column=1)
rlabel2=Label(root, text="Player2:")
rlabel2.grid(row=0,column=2)
self.player2_type=StringVar(root)
self.player2_type.set(options[0])
self.rowbox=OptionMenu(root, self.player2_type, *options)
self.rowbox.grid(row=0, column=3)
begin=Button(root, text="Start", command=self.game_start)
begin.grid(row=0, column=4)
self.c.grid(row=1, column=0, columnspan=7)
play_col=[]
for i in range(self.cols):
play_col.append(Button(root, text= "Col %d" %i, command=lambda col= i: self.human_play(col)))
play_col[i].grid(row=10,column="%d"%i)
## self.DrawCircle(1,1,1)
## self.DrawCircle(2,2,1)
## self.DrawCircle(5,3,2)
self.DrawGrid()
self.brd = ConnectFour()
def game_start(self):
self.board=ConnectFour()
print self.player1_type.get()
print self.player2_type.get()
if self.player1_type.get()=="Random":
self.player1 = RandomPlayer(playernum=1)
if self.player2_type.get()== "Random" or self.player2_type.get() == "Minimax":
tkMessageBox.showinfo("Bad Choice", "You Have to choose At least 1 Human Player")
else:
self.player
elif self.player1_type.get()=="Minimax":
self.player1=MinimaxPlayer(playernum=2, ply_depth=4, utility=SimpleUtility(5,1))
if self.player2_type.get()== "Random" or self.player2_type.get() == "Minimax":
tkMessageBox.showinfo("Bad Choice", "You Have to choose At least 1 Human Player")
elif self.player1_type.get()=="Human":
self.player1=Human(playernum=1)
if self.player2_type.get()=="Human":
self.player2=Human(playernum=2)
elif self.player2_type.get()=="Random":
self.player2=RandomPlayer(playernum=2)
elif self.player2_type.get()=="Minimax":
self.player2=MinimaxPlayer(playernum=2, ply_depth=4, utility=SimpleUitlity(5,1))
#self.currentplayer==1
#self.draw()
def human_play(self, col):
if self.player1_type.get()=="Human" and self.player2_type.get() =="Human":
while True:
self.DrawCircle(row,col,1)
if self.brd.is_game_over() is None:
self.DrawCircle(row,col,2)
if self.brd.is_game_over() is None:
pass
else:
print "Player 2 wins!"
break
else:
print "Player 1 wins!"
break
def DrawCircle(self,row,col,player_num):
if player_num == 1:
fill_color = 'red'
elif player_num == 2:
fill_color = 'black'
#(startx, starty, endx, endy)
self.c.create_oval(col*self.mag,row*self.mag,(col+1)*self.mag,(row+1)*self.mag,fill=fill_color)
root=Tk()
ConnectFourGUI(root)
root.mainloop()
I know I'm supposed to call the DrawCircle function in the Human Play function, I'm just unsure as to how I'm supposed to set it all up. any advice as to how I could go about this would be greatly appreciated!
Your code is depending on a few packages I don't have, so I can't be more specific, but the way I'd go about doing something like this is to track the X and Y coords of the chip works out the the row and column that it'd go into in the widget.
You'll need to create a location object, a tuple maybe, and then a way to translate the location object into a drawable location. Then it's just a matter of incrementing either X or Y and detecting if there's a chip below it.

Categories

Resources