Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # 5x5_Circle_Sliding_Puzzle.py
- # a really fun attempt at creating a game
- import tkinter as tk
- import random
- import itertools
- from PIL import Image, ImageTk, ImageDraw
- ww = 500
- hh = 500
- sz = int(min(ww, hh)/5)
- colors = ['red', 'lime', '#0077DB', 'yellow'] # , '#CC84E3'
- char_map = {colors[i]: 'RGBYP'[i] for i in range(len(colors)) }
- PERMUTATIONS__ = list(itertools.permutations(colors, 4))
- root = tk.Tk()
- root.title('5x5 Circle Sliding Puzzle')
- root.geometry(f"{ww}x{hh}+10+10")
- canvas = tk.Canvas(root)
- canvas.place(width=ww, height=hh)
- trues = [0]
- raw = {}
- def load_images():
- image_dict = {}
- for color_pattern in PERMUTATIONS__:
- base_image = Image.new('RGB', (sz, sz), 'white')
- draw = ImageDraw.Draw(base_image)
- r = sz + 5
- x1, y1 = sz / 2, sz / 2
- draw.ellipse((x1 - r, y1 - r, x1, y1), fill=color_pattern[0], outline='black')
- draw.ellipse((x1, y1 - r, x1 + r, y1), fill=color_pattern[1], outline='black')
- draw.ellipse((x1 - r, y1, x1, y1 + r), fill=color_pattern[2], outline='black')
- draw.ellipse((x1, y1, x1 + r, y1 + r), fill=color_pattern[3], outline='black')
- image_dict[len(image_dict)] = ImageTk.PhotoImage(base_image)
- raw[color_pattern] = base_image
- return image_dict
- images = load_images()
- images[len(images)] = None
- def b1_press(x, y):
- x0, y0 = empty_square[0]
- for dx, dy in [(x, y+1), (x, y-1), (x+1, y), (x-1, y)]:
- if (x0, y0) == (dx, dy):
- tile_colors[(x0, y0)], tile_colors[(x, y)] = tile_colors[(x, y)], tile_colors[(x0, y0)]
- button[(x0, y0)].delete('all')
- button[(x0, y0)].create_image(0, 0, anchor='nw', image=tile_colors[(x0, y0)])
- button[(x0, y0)].config(relief='flat', bd=0)
- button[(x, y)].delete('all')
- button[(x, y)].create_image(0, 0, anchor='nw', image=empty_photo)
- button[(x, y)].config(relief='sunken', bg='darkgrey', bd=6)
- empty_square[0] = (x, y)
- check_win()
- return
- def update_tile(row, col):
- tile = button[(row, col)]
- tile.delete('all')
- tile.create_image(0, 0, anchor='nw', image=tile_colors[(row, col)])
- def check_win(): # ZZZ
- global current_board_index
- text_layout()
- txtA, txtB = txt_map[0]
- count_trues = 0
- for t in 'RGBYP':
- count_trues += txtA.count(t*2)
- count_trues += txtB.count(t*2)
- if count_trues > trues[0]:
- trues[0] = count_trues
- print(count_trues)
- best_boards.clear()
- best_boards.append(capture_canvas_image())
- current_board_index = 0
- elif count_trues == trues[0]:
- canvas_image = capture_canvas_image()
- if canvas_image not in best_boards:
- best_boards.append(canvas_image)
- print(count_trues, len(best_boards))
- def get_tile_colors(row, col):
- img = tile_colors[(row, col)]
- if img is None:
- return (None, None, None, None)
- idx = [i for i, v in images.items() if v == img][0]
- return PERMUTATIONS__[idx]
- paused = False
- current_board_index = 0
- def toggle_pause(event):
- global paused
- paused = not paused
- if paused:
- # Bind arrow keys
- root.bind("<Left>", lambda event: view_previous_board())
- root.bind("<Right>", lambda event: view_next_board())
- show_capture(best_boards[0])
- else:
- # Unbind arrow keys
- root.unbind("<Left>")
- root.unbind("<Right>")
- def view_previous_board():
- global current_board_index
- if current_board_index > 0:
- current_board_index -= 1
- show_capture(best_boards[current_board_index])
- def view_next_board():
- global current_board_index
- current_board_index += 1
- try:
- show_capture(best_boards[current_board_index])
- except:
- current_board_index -= 1
- def update_board(board_config):
- for row in range(5):
- for col in range(5):
- i = (row, col)
- button[i].delete('all')
- if board_config[i]:
- button[i].create_image(0, 0, anchor='nw', image=board_config[i])
- button[i].config(relief='flat', bd=0)
- else:
- button[i].create_image(0, 0, anchor='nw', image=empty_photo)
- button[i].config(relief='sunken', bg='darkgrey', bd=4)
- capture_image = 0
- top_window = 0
- def show_capture(capture):
- global capture_image, top_window
- try:
- top_window.destroy()
- except:
- 0
- top_window = tk.Toplevel(root)
- top_window.title("Boards")
- top_window.geometry(f"{ww}x{hh}+10+10")
- top_canvas = tk.Canvas(top_window)
- top_canvas.pack(expand=True, fill=tk.BOTH)
- top_window.bind("<Left>", lambda event: view_previous_board())
- top_window.bind("<Right>", lambda event: view_next_board())
- print(current_board_index)
- capture_image = ImageTk.PhotoImage(capture)
- top_canvas.create_image(0, 0, anchor="nw", image=capture_image)
- top_canvas.update()
- def capture_canvas_image():
- full_image = Image.new('RGB', (ww, hh), 'white')
- for (row, col), img in tile_colors.items():
- if img is None:
- continue
- color_pattern = PERMUTATIONS__[[v for v, k in images.items() if k == img][0]]
- base_image = raw[color_pattern]
- position = (row*sz, col*sz, (row+1)*sz, (col+1)*sz)
- full_image.paste(base_image, position)
- return full_image
- def rotate_clockwise(matrix):
- transposed = list(zip(*matrix))
- rotated = [list(row[::-1]) for row in transposed]
- return rotated
- txt_map = [0]
- def text_layout():
- layout = [['' for _ in range(5 * 2)] for _ in range(5 * 2)] # 2x2 for each tile
- for col in range(5):
- for row in range(5):
- colors = get_tile_colors(row, col)
- if colors == (None, None, None, None):
- chars = list('....')
- else:
- chars = [char_map[color] for color in colors]
- layout[col * 2][row * 2] = chars[0]
- layout[col * 2][row * 2 + 1] = chars[1]
- layout[col * 2 + 1][row * 2] = chars[2]
- layout[col * 2 + 1][row * 2 + 1] = chars[3]
- txtA = []
- for line in layout:
- txtA += [''.join(line)]
- txtA = '\n'.join(txtA)
- layout2 = rotate_clockwise(layout)
- txtB = []
- for line in layout2:
- txtB += [''.join(line)]
- txtB = '\n'.join(txtB)
- txt_map[0] = [txtA, txtB]
- def print_color_layout(event=None):
- txtA, txtB = txt_map[0]
- print('')
- print(txtA)
- print('')
- print(txtB)
- button = {}
- tile_colors = {}
- color_patterns = PERMUTATIONS__[:]
- random.shuffle(color_patterns)
- best_boards = []
- for col in range(5):
- for row in range(5):
- i = (row, col)
- button[i] = tk.Canvas(canvas, relief='raised', name=str(i))
- button[i].place(x=row*sz, y=col*sz, width=sz, height=sz)
- button[i].bind("<Button-1>", lambda event, x=row, y=col: b1_press(x, y))
- tile_colors[(row, col)] = images[len(tile_colors)]
- update_tile(row, col)
- empty_img = Image.new('RGB', (sz, sz), 'darkgray')
- empty_photo = ImageTk.PhotoImage(empty_img)
- empty_square = [i]
- button[i].create_image(0, 0, anchor='nw', image=empty_photo)
- button[i].config(relief='sunken', bg='darkgrey', bd=4)
- root.bind("p", print_color_layout)
- root.bind("P", print_color_layout)
- root.bind("<space>", toggle_pause)
- counter = 0
- positions = list(tile_colors.keys())
- while 1:
- if not paused:
- positions[counter], positions[0] = positions[0], positions[counter],
- counter = (counter - 1) % 24
- tile_colors = {pos: tile_colors[positions[i]] for i, pos in enumerate(tile_colors.keys())}
- update_board(tile_colors)
- check_win()
- root.lift()
- root.update()
- root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement