Last active
May 8, 2023 14:15
-
-
Save ssaurel/67a0a56167d7ba8f7c237ab0e83b7492 to your computer and use it in GitHub Desktop.
Flipping Bits Game in Python with Tkinter - Tutorial for the SSaurel's Blog
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import tkinter as tk | |
import random | |
from copy import deepcopy | |
class FlippingBitsGame: | |
def __init__(self, level): | |
self.level = level # Level = size of the square | |
self.target = [[0] * level for _ in range(level)] # the board to obtain when you play | |
self.board = [[0] * level for _ in range(level)] # the current board played by the user | |
self.solved = True | |
self.newgame() # new game method to define later | |
# method to flip a column | |
def flipcol(self, r): | |
for i in range(len(self.board[r])): | |
self.board[r][i] ^= 1 # 0 -> 1, 1 -> 0 | |
# method to flip a row | |
def fliprow(self, c): | |
for row in self.board: | |
row[c] ^= 1 | |
# method to shuffle the board | |
def shuffle(self): | |
for _ in range(self.level * self.level): | |
if random.random() > 0.5: | |
self.flipcol(random.randint(0, self.level - 1)) | |
else: | |
self.fliprow(random.randint(0, self.level - 1)) | |
# new game | |
def newgame(self): | |
if self.solved: | |
# generate a new game | |
while True: | |
self.shuffle() | |
self.target = deepcopy(self.board) # we make a deep copy of board into the target | |
self.shuffle() # then we shuffle the board | |
if self.issolved() == False: | |
break | |
self.solved = False | |
# is solved method. We check if board == target | |
def issolved(self): | |
for i in range(self.level): | |
for j in range(self.level): | |
if self.board[i][j] != self.target[i][j]: | |
return False | |
self.solved = True | |
return True | |
# Now we need to write the code for the GUI | |
class FlippingBitsGUI: | |
def __init__(self, root, level): | |
self.game = FlippingBitsGame(level) | |
self.root = root | |
self.root.title("Flipping Bits Game - SSaurel") | |
self.root.geometry("700x800") | |
self.canvas = tk.Canvas(self.root, width = 700, height = 800) | |
self.canvas.pack() | |
self.drawboard() # method to define letting us to draw the board for the user | |
def drawboard(self): | |
# we clean the canvas | |
self.canvas.delete("all") | |
squaresize = 500 / self.game.level | |
targetsize = squaresize / 10 | |
for i in range(self.game.level): | |
x = 100 + i * squaresize | |
for j in range(self.game.level): | |
y = 100 + j * squaresize | |
value = self.game.board[i][j] | |
self.canvas.create_rectangle(x, y, x + squaresize, y + squaresize, fill = ("blue", "yellow")[value == 0]) | |
# draw the target on the top left | |
target = self.game.target[i][j] | |
self.canvas.create_rectangle(x + 10, y + 10, x + 10 + targetsize, y + 10 + targetsize, fill = ("blue", "yellow")[target == 0]) | |
if self.game.issolved(): | |
self.canvas.create_text(200, 750, text = "Solved. Click to start a new game", font = ("Helvetica", "20", "bold")) | |
def onclick(self, event): | |
if self.game.solved: | |
self.game.newgame() | |
self.drawboard() | |
return | |
# we get coordinates of the user's click | |
idx = int(event.x) | |
idy = int(event.y) | |
# check if you must flip a column or a row | |
if (idx > 0 and idx < 100 and idy > 100 and idy < 600) or (idx > 600 and idx < 700 and idy > 100 and idy < 600): | |
# we need to flip a row | |
squaresize = 500 / self.game.level | |
row = int((idy - 100) / squaresize) | |
self.game.fliprow(row) | |
elif (idy > 0 and idy < 100 and idx > 100 and idx < 600) or (idy > 600 and idy < 800 and idx > 100 and idx < 600): | |
# we need to flip a col | |
squaresize = 500 / self.game.level | |
col = int((idx - 100) / squaresize) | |
self.game.flipcol(col) | |
self.drawboard() | |
root = tk.Tk() | |
gui = FlippingBitsGUI(root, 6) # we will use a 5x5 board | |
gui.canvas.bind("<Button-1>", gui.onclick) | |
root.mainloop() | |
# Time to put our game in action :P | |
# Watch the tutorial on YouTube => https://www.youtube.com/watch?v=mPZOLy9wui0 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment