mirror of
https://github.com/AlekseyLobanov/PythonDevelopment2021.git
synced 2026-01-11 12:42:01 +03:00
hw3: initial commit
This commit is contained in:
119
03_ThreeWayAndTkinter/main.py
Normal file
119
03_ThreeWayAndTkinter/main.py
Normal file
@@ -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()
|
||||
Reference in New Issue
Block a user