From 08ea1e085f7e019a79065d337576c44315a8bf53 Mon Sep 17 00:00:00 2001 From: Aleksey Lobanov Date: Sun, 14 Mar 2021 22:06:45 +0300 Subject: [PATCH] hw3: initial commit --- 03_ThreeWayAndTkinter/main.py | 119 ++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 03_ThreeWayAndTkinter/main.py diff --git a/03_ThreeWayAndTkinter/main.py b/03_ThreeWayAndTkinter/main.py new file mode 100644 index 0000000..ce0e7d7 --- /dev/null +++ b/03_ThreeWayAndTkinter/main.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python3 + +import random +import time +from functools import partial +import tkinter as tk +from tkinter import messagebox as mb + + +GAME_SIZE = 4 +POSSIBLE_MOVES = [(1, 0), (-1, 0), (0, 1), (0, -1)] +INIT_RANDOM_STEPS = 5 +NEW_GAME_RANDOM_STEPS = 1000 + + +def get_val_pos(state, val): + for i in range(GAME_SIZE): + for j in range(GAME_SIZE): + if state[i][j] == val: + return i, j + + +def swap_cells(state, first, second): + state[first[0]][first[1]], state[second[0]][second[1]] = ( + state[second[0]][second[1]], + state[first[0]][first[1]], + ) + + +def get_game_state(steps=0): + res = [[0 for i in range(GAME_SIZE)] for j in range(GAME_SIZE)] + for i in range(GAME_SIZE): + for j in range(4): + if i == GAME_SIZE - 1 and j == GAME_SIZE - 1: + # empty cell + continue + res[i][j] = i * GAME_SIZE + j + 1 + + empty_pos = get_val_pos(res, 0) + for step_ind in range(steps): + possbile_next_cells = [] + for delta_x, delta_y in POSSIBLE_MOVES: + next_cell = (empty_pos[0] + delta_x, empty_pos[1] + delta_y) + if 0 <= next_cell[0] < GAME_SIZE and 0 <= next_cell[1] < GAME_SIZE: + possbile_next_cells.append(next_cell) + next_cell = random.choice(possbile_next_cells) + # swap == one move + swap_cells(res, empty_pos, next_cell) + empty_pos = next_cell + return res + + +class Application(tk.Frame): + def __init__(self, master=None): + super().__init__(master) + tk.Grid.rowconfigure(self.master, 0, weight=1) + tk.Grid.columnconfigure(self.master, 0, weight=1) + self.grid(sticky="news", column=0, row=0) + self.createWidgets() + + self.rowconfigure(0, weight=1) + for i in range(1, 5): + self.rowconfigure(i, weight=3) + for i in range(4): + self.columnconfigure(i, weight=1) + + def createWidgets(self): + self.new_bt = tk.Button(self, text="New", command=self.process_new_game) + self.exit_bt = tk.Button(self, text="Exit", command=self.quit) + self.new_bt.grid(row=0, column=0, columnspan=2) + self.exit_bt.grid(row=0, column=2, columnspan=2) + self.game_buttons = self.create_game_buttons() + self.game_state = get_game_state(INIT_RANDOM_STEPS) + self.render_current_state() + + def create_game_buttons(self): + res = {} + for i in range(GAME_SIZE * GAME_SIZE): + btn_value = i + 1 + btn = tk.Button( + self, + text=str(btn_value), + command=partial(self.process_number_press, btn_value), + ) + res[btn_value] = btn + return res + + def process_number_press(self, val): + val_pos = get_val_pos(self.game_state, val) + empty_pos = get_val_pos(self.game_state, 0) + print("poses", val_pos, empty_pos) + delta = (empty_pos[0] - val_pos[0], empty_pos[1] - val_pos[1]) + if delta not in POSSIBLE_MOVES: + return + swap_cells(self.game_state, val_pos, empty_pos) + self.render_current_state() + if self.game_state == get_game_state(0): + mb.showinfo(title="Info", message="You win!") + self.game_state = get_game_state(NEW_GAME_RANDOM_STEPS) + self.render_current_state() + + def process_new_game(self): + self.game_state = get_game_state(NEW_GAME_RANDOM_STEPS) + self.render_current_state() + + def render_current_state(self): + for i in range(4): + for j in range(4): + btn_value = self.game_state[i][j] + if btn_value == 0: + continue + btn = self.game_buttons[btn_value] + btn.grid(row=i + 1, column=j, sticky="news") + + +if __name__ == "__main__": + app = Application() + app.master.title("15-шки") + app.mainloop()