Amazing-Python-Scripts
190 строк · 6.3 Кб
1from tkinter import *2from tkinter import font3
4# Constants
5TOLERANCE = 86CELL_SIZE = 407OFFSET = 108CIRCLE_RADIUS = 59DOT_OFFSET = OFFSET + CIRCLE_RADIUS10GAME_HEIGHT = 40011GAME_WIDTH = 40012
13# Player Class
14
15
16class Player:17def __init__(self, name, color="#00BFFF"): # Blue color18self.score = 019self.text_var = StringVar()20self.name = name21self.color = color22
23def update(self):24self.text_var.set(f"{self.name}: {self.score}")25
26
27# Main Frame Class
28class DotConnectFrame(Frame):29def __init__(self, master):30Frame.__init__(self, master)31
32# Fonts33self.title_font = font.Font(34self, name="TitleFont", family="Arial", weight="bold", size=36)35
36# Info Frame37self.info_frame = Frame(self, bg="#333333") # Dark gray background38self.players = [Player("Player A", "#00BFFF"), Player(39"Player B", "#00FF00")] # Blue and Green colors40self.info_frame.players = [Label(self.info_frame, textvariable=i.text_var, bg="#FFFFFF", fg="#333333",41font="Arial 20 bold") for i in self.players] # White text on dark gray background42for i in self.info_frame.players:43i.grid()44self.info_frame.grid(row=0, column=0, columnspan=2, pady=10)45
46# Canvas47# Dark gray background48self.canvas = Canvas(self, height=GAME_HEIGHT,49width=GAME_WIDTH, bg="#333333")50self.canvas.bind("<Button-1>", lambda e: self.click(e))51self.canvas.grid(row=1, column=0, padx=10)52
53# Dots54self.dots = [[self.canvas.create_oval(CELL_SIZE*i+OFFSET, CELL_SIZE*j+OFFSET, CELL_SIZE*i+OFFSET+2*CIRCLE_RADIUS,55CELL_SIZE*j+OFFSET+2*CIRCLE_RADIUS, fill="#000000") for j in range(10)] for i in range(10)] # Black dots56self.lines = []57
58# Reset Game Button59self.reset_button = Button(self, text="Reset Game", command=self.reset_game,60font="Arial 14 bold", bg="#FF0000", fg="#000000") # Red button with white text61self.reset_button.grid(row=2, column=0, pady=10)62
63self.turn = self.players[0]64self.update_players()65
66self.grid()67
68def update_players(self):69for player in self.players:70player.update()71
72def click(self, event):73x, y = event.x, event.y74orientation = self.check_proximity(x, y)75
76if orientation:77if self.line_exists(x, y, orientation):78return79line = self.create_line(x, y, orientation)80score = self.update_score(line)81if score:82self.turn.score += score83self.turn.update()84self.check_game_over()85else:86index = self.players.index(self.turn)87self.turn = self.players[1 - index]88self.lines.append(line)89
90def create_line(self, x, y, orientation):91start_x = CELL_SIZE * ((x - OFFSET) // CELL_SIZE) + DOT_OFFSET92start_y = CELL_SIZE * ((y - OFFSET) // CELL_SIZE) + DOT_OFFSET93tmp_x = (x - OFFSET) // CELL_SIZE94tmp_y = (y - OFFSET) // CELL_SIZE95
96if orientation == "horizontal":97end_x = start_x + CELL_SIZE98end_y = start_y99else:100end_x = start_x101end_y = start_y + CELL_SIZE102
103return self.canvas.create_line(start_x, start_y, end_x, end_y, width=2, fill=self.turn.color)104
105def update_score(self, line):106score = 0107x0, y0, x1, y1 = self.canvas.coords(line)108if x0 == x1: # Vertical line109mid_x = x0110mid_y = (y0 + y1) / 2111pre = (x0 - CELL_SIZE / 2, mid_y)112post = (x0 + CELL_SIZE / 2, mid_y)113elif y0 == y1: # Horizontal line114mid_x = (x0 + x1) / 2115mid_y = y0116pre = (mid_x, y0 - CELL_SIZE / 2)117post = (mid_x, y0 + CELL_SIZE / 2)118
119if len(self.find_lines(pre)) == 3:120self.fill_box(pre)121score += 1122if len(self.find_lines(post)) == 3:123self.fill_box(post)124score += 1125return score126
127def find_lines(self, coords):128x, y = coords129if x < 0 or x > GAME_WIDTH:130return []131if y < 0 or y > GAME_WIDTH:132return []133
134lines = [x for x in self.canvas.find_enclosed(135x - CELL_SIZE, y - CELL_SIZE, x + CELL_SIZE, y + CELL_SIZE) if x in self.lines]136return lines137
138def fill_box(self, coords):139x, y = coords140self.canvas.create_text(x, y, text=self.turn.name,141fill=self.turn.color, font="Arial 5 bold")142
143def check_proximity(self, x, y):144x -= OFFSET145y -= OFFSET146dx = x - (x // CELL_SIZE) * CELL_SIZE147dy = y - (y // CELL_SIZE) * CELL_SIZE148
149if abs(dx) < TOLERANCE:150if abs(dy) < TOLERANCE:151return None152else:153return "vertical"154elif abs(dy) < TOLERANCE:155return "horizontal"156else:157return None158
159def line_exists(self, x, y, orientation):160id_ = self.canvas.find_closest(x, y, halo=TOLERANCE)[0]161if id_ in self.lines:162return True163else:164return False165
166def check_game_over(self):167total = sum([player.score for player in self.players])168if total == 81:169self.canvas.create_text(GAME_WIDTH / 2, GAME_HEIGHT / 2, text="GAME OVER", font=self.title_font, fill="#888888",170justify=CENTER)171
172def reset_game(self):173self.canvas.delete("all")174self.lines = []175for i in range(10):176for j in range(10):177self.dots[i][j] = self.canvas.create_oval(CELL_SIZE * i + OFFSET, CELL_SIZE * j + OFFSET, CELL_SIZE * i + OFFSET + 2 * CIRCLE_RADIUS,178CELL_SIZE * j + OFFSET + 2 * CIRCLE_RADIUS, fill="#000000")179for player in self.players:180player.score = 0181player.update()182self.turn = self.players[0]183
184
185# Main Tkinter Window
186main_window = Tk()187main_window.title("Dot Connect")188main_window.config(bg="#000000")189main_window.frame = DotConnectFrame(main_window)190main_window.mainloop()191