Path: blob/master/python-igra-morskoy-boy/main_lesson_15.py
5918 views
from tkinter import *1from tkinter import messagebox2import time3import random45tk = Tk()6app_running = True78size_canvas_x = 5009size_canvas_y = 50010s_x = s_y = 8 # размер игрового поля11s_y = 812step_x = size_canvas_x // s_x # шаг по горизонтали13step_y = size_canvas_y // s_y # шаг по вертикали14size_canvas_x = step_x * s_x15size_canvas_y = step_y * s_y16delta_menu_x = 417menu_x = step_x * delta_menu_x # 25018menu_y = 4019ships = s_x // 2 # определяем максимальное кол-во кораблей20ship_len1 = s_x // 5 # длина первого типа корабля21ship_len2 = s_x // 3 # длина второго типа корабля22ship_len3 = s_x // 2 # длина третьего типа корабля23enemy_ships1 = [[0 for i in range(s_x + 1)] for i in range(s_y + 1)]24enemy_ships2 = [[0 for i in range(s_x + 1)] for i in range(s_y + 1)]25list_ids = [] # список объектов canvas2627# points1 - список куда мы кликнули мышкой28points1 = [[-1 for i in range(s_x)] for i in range(s_y)]29points2 = [[-1 for i in range(s_x)] for i in range(s_y)]3031# boom - список попаданий по кораблям противника32boom = [[0 for i in range(s_x)] for i in range(s_y)]3334# ships_list - список кораблей игрока 1 и игрока 235ships_list = []3637# hod_igrovomu_polu_1 - если Истина - то ходит игрок №2, иначе ходит игрок №138hod_igrovomu_polu_1 = False394041# print(enemy_ships1)4243def on_closing():44global app_running45if messagebox.askokcancel("Выход из игры", "Хотите выйти из игры?"):46app_running = False47tk.destroy()484950tk.protocol("WM_DELETE_WINDOW", on_closing)51tk.title("Игра Морской Бой")52tk.resizable(0, 0)53tk.wm_attributes("-topmost", 1)54canvas = Canvas(tk, width=size_canvas_x + menu_x + size_canvas_x, height=size_canvas_y + menu_y, bd=0,55highlightthickness=0)56canvas.create_rectangle(0, 0, size_canvas_x, size_canvas_y, fill="white")57canvas.create_rectangle(size_canvas_x + menu_x, 0, size_canvas_x + menu_x + size_canvas_x, size_canvas_y,58fill="lightyellow")59canvas.pack()60tk.update()616263def draw_table(offset_x=0):64for i in range(0, s_x + 1):65canvas.create_line(offset_x + step_x * i, 0, offset_x + step_x * i, size_canvas_y)66for i in range(0, s_y + 1):67canvas.create_line(offset_x, step_y * i, offset_x + size_canvas_x, step_y * i)686970draw_table()71draw_table(size_canvas_x + menu_x)7273t0 = Label(tk, text="Игрок №1", font=("Helvetica", 16))74t0.place(x=size_canvas_x // 2 - t0.winfo_reqwidth() // 2, y=size_canvas_y + 3)75t1 = Label(tk, text="Игрок №2", font=("Helvetica", 16))76t1.place(x=size_canvas_x + menu_x + size_canvas_x // 2 - t1.winfo_reqwidth() // 2, y=size_canvas_y + 3)7778t0.configure(bg="red")79t0.configure(bg="#f0f0f0")8081t3 = Label(tk, text="@@@@@@@", font=("Helvetica", 16))82t3.place(x=size_canvas_x + step_x, y= 3 * step_y)8384def mark_igrok(igrok_mark_1):85if igrok_mark_1:86t0.configure(bg="red")87t1.configure(bg="#f0f0f0")88t3.configure(text="Ход Игрока №2")89else:90t1.configure(bg="red")91t0.configure(bg="#f0f0f0")92t3.configure(text="Ход Игрока №1")93mark_igrok(hod_igrovomu_polu_1)949596def button_show_enemy1():97for i in range(0, s_x):98for j in range(0, s_y):99if enemy_ships1[j][i] > 0:100color = "red"101if points1[j][i] != -1:102color = "green"103_id = canvas.create_rectangle(i * step_x, j * step_y, i * step_x + step_x, j * step_y + step_y,104fill=color)105list_ids.append(_id)106107108def button_show_enemy2():109for i in range(0, s_x):110for j in range(0, s_y):111if enemy_ships2[j][i] > 0:112color = "red"113if points2[j][i] != -1:114color = "green"115_id = canvas.create_rectangle(size_canvas_x + menu_x + i * step_x, j * step_y,116size_canvas_x + menu_x + i * step_x + step_x, j * step_y + step_y,117fill=color)118list_ids.append(_id)119120121def button_begin_again():122global list_ids123global points1, points2124global boom125global enemy_ships1, enemy_ships2126for el in list_ids:127canvas.delete(el)128list_ids = []129generate_ships_list()130# print(ships_list)131enemy_ships1 = generate_enemy_ships()132enemy_ships2 = generate_enemy_ships()133points1 = [[-1 for i in range(s_x)] for i in range(s_y)]134points2 = [[-1 for i in range(s_x)] for i in range(s_y)]135boom = [[0 for i in range(s_x)] for i in range(s_y)]136137138b0 = Button(tk, text="Показать корабли Игрока №1", command=button_show_enemy1)139b0.place(x=size_canvas_x + 20, y=30)140141b1 = Button(tk, text="Показать корабли Игрока №2", command=button_show_enemy2)142b1.place(x=size_canvas_x + 20, y=70)143144b2 = Button(tk, text="Начать заново!", command=button_begin_again)145b2.place(x=size_canvas_x + 20, y=110)146147148def draw_point(x, y):149# print(enemy_ships1[y][x])150if enemy_ships1[y][x] == 0:151color = "red"152id1 = canvas.create_oval(x * step_x, y * step_y, x * step_x + step_x, y * step_y + step_y, fill=color)153id2 = canvas.create_oval(x * step_x + step_x // 3, y * step_y + step_y // 3, x * step_x + step_x - step_x // 3,154y * step_y + step_y - step_y // 3, fill="white")155list_ids.append(id1)156list_ids.append(id2)157if enemy_ships1[y][x] > 0:158color = "blue"159id1 = canvas.create_rectangle(x * step_x, y * step_y + step_y // 2 - step_y // 10, x * step_x + step_x,160y * step_y + step_y // 2 + step_y // 10, fill=color)161id2 = canvas.create_rectangle(x * step_x + step_x // 2 - step_x // 10, y * step_y,162x * step_x + step_x // 2 + step_x // 10, y * step_y + step_y, fill=color)163list_ids.append(id1)164list_ids.append(id2)165166167def draw_point2(x, y, offset_x=size_canvas_x + menu_x):168# print(enemy_ships1[y][x])169if enemy_ships2[y][x] == 0:170color = "red"171id1 = canvas.create_oval(offset_x + x * step_x, y * step_y, offset_x + x * step_x + step_x, y * step_y + step_y,172fill=color)173id2 = canvas.create_oval(offset_x + x * step_x + step_x // 3, y * step_y + step_y // 3,174offset_x + x * step_x + step_x - step_x // 3,175y * step_y + step_y - step_y // 3, fill="white")176list_ids.append(id1)177list_ids.append(id2)178if enemy_ships2[y][x] > 0:179color = "blue"180id1 = canvas.create_rectangle(offset_x + x * step_x, y * step_y + step_y // 2 - step_y // 10,181offset_x + x * step_x + step_x,182y * step_y + step_y // 2 + step_y // 10, fill=color)183id2 = canvas.create_rectangle(offset_x + x * step_x + step_x // 2 - step_x // 10, y * step_y,184offset_x + x * step_x + step_x // 2 + step_x // 10, y * step_y + step_y,185fill=color)186list_ids.append(id1)187list_ids.append(id2)188189190def check_winner(x, y):191win = False192if enemy_ships1[y][x] > 0:193boom[y][x] = enemy_ships1[y][x]194sum_enemy_ships1 = sum(sum(i) for i in zip(*enemy_ships1))195sum_boom = sum(sum(i) for i in zip(*boom))196# print(sum_enemy_ships1, sum_boom)197if sum_enemy_ships1 == sum_boom:198win = True199return win200201202def check_winner2():203win = True204for i in range(0, s_x):205for j in range(0, s_y):206if enemy_ships1[j][i] > 0:207if points1[j][i] == -1:208win = False209# print(win)210return win211212213def check_winner2_igrok_2():214win = True215for i in range(0, s_x):216for j in range(0, s_y):217if enemy_ships2[j][i] > 0:218if points2[j][i] == -1:219win = False220# print(win)221return win222223224def add_to_all(event):225global points1, points2, hod_igrovomu_polu_1226_type = 0 # ЛКМ227if event.num == 3:228_type = 1 # ПКМ229# print(_type)230mouse_x = canvas.winfo_pointerx() - canvas.winfo_rootx()231mouse_y = canvas.winfo_pointery() - canvas.winfo_rooty()232# print(mouse_x, mouse_y)233ip_x = mouse_x // step_x234ip_y = mouse_y // step_y235# print(ip_x, ip_y, "_type:", _type)236237# первое игровое поле238if ip_x < s_x and ip_y < s_y and hod_igrovomu_polu_1:239if points1[ip_y][ip_x] == -1:240points1[ip_y][ip_x] = _type241hod_igrovomu_polu_1 = False242draw_point(ip_x, ip_y)243# if check_winner(ip_x, ip_y):244if check_winner2():245hod_igrovomu_polu_1 = True246winner = "Победа Игрока №2"247winner_add = "(Все корабли противника Игрока №1 подбиты)!!!!!"248print(winner, winner_add)249points1 = [[10 for i in range(s_x)] for i in range(s_y)]250points2 = [[10 for i in range(s_x)] for i in range(s_y)]251id1 = canvas.create_rectangle(step_x*3, step_y*3, size_canvas_x + menu_x + size_canvas_x-step_x*3, size_canvas_y-step_y, fill="blue")252list_ids.append(id1)253id2 = canvas.create_rectangle(step_x * 3+step_x//2, step_y * 3+step_y//2,254size_canvas_x + menu_x + size_canvas_x - step_x * 3 - step_x//2,255size_canvas_y - step_y - step_y//2, fill="yellow")256list_ids.append(id2)257id3 = canvas.create_text(step_x*10, step_y*5, text=winner, font=("Arial", 50), justify=CENTER)258id4 = canvas.create_text(step_x * 10, step_y * 6, text=winner_add, font=("Arial", 25), justify=CENTER)259list_ids.append(id3)260list_ids.append(id4)261262# print(len(list_ids))263264# второе игровое поле265if ip_x >= s_x + delta_menu_x and ip_x <= s_x + s_x + delta_menu_x and ip_y < s_y and not hod_igrovomu_polu_1:266# print("ok")267if points2[ip_y][ip_x - s_x - delta_menu_x] == -1:268points2[ip_y][ip_x - s_x - delta_menu_x] = _type269hod_igrovomu_polu_1 = True270draw_point2(ip_x - s_x - delta_menu_x, ip_y)271# if check_winner(ip_x, ip_y):272if check_winner2_igrok_2():273hod_igrovomu_polu_1 = False274winner = "Победа Игрока №1"275winner_add = "(Все корабли противника Игрока №2 подбиты)!!!!!"276print(winner, winner_add)277points1 = [[10 for i in range(s_x)] for i in range(s_y)]278points2 = [[10 for i in range(s_x)] for i in range(s_y)]279id1 = canvas.create_rectangle(step_x * 3, step_y * 3,280size_canvas_x + menu_x + size_canvas_x - step_x * 3,281size_canvas_y - step_y, fill="blue")282list_ids.append(id1)283id2 = canvas.create_rectangle(step_x * 3 + step_x // 2, step_y * 3 + step_y // 2,284size_canvas_x + menu_x + size_canvas_x - step_x * 3 - step_x // 2,285size_canvas_y - step_y - step_y // 2, fill="yellow")286list_ids.append(id2)287id3 = canvas.create_text(step_x * 10, step_y * 5, text=winner, font=("Arial", 50), justify=CENTER)288id4 = canvas.create_text(step_x * 10, step_y * 6, text=winner_add, font=("Arial", 25), justify=CENTER)289list_ids.append(id3)290list_ids.append(id4)291mark_igrok(hod_igrovomu_polu_1)292293canvas.bind_all("<Button-1>", add_to_all) # ЛКМ294canvas.bind_all("<Button-3>", add_to_all) # ПКМ295296297def generate_ships_list():298global ships_list299ships_list = []300# генерируем список случайных длин кораблей301for i in range(0, ships):302ships_list.append(random.choice([ship_len1, ship_len2, ship_len3]))303# print(ships_list)304305306def generate_enemy_ships():307global ships_list308enemy_ships = []309310# подсчет суммарной длины кораблей311sum_1_all_ships = sum(ships_list)312sum_1_enemy = 0313314# print("sum: ", sum_1_all_ships)315316while sum_1_enemy != sum_1_all_ships:317# обнуляем массив кораблей врага318enemy_ships = [[0 for i in range(s_x + 1)] for i in319range(s_y + 1)] # +1 для доп. линии справа и снизу, для успешных проверок генерации противника320321for i in range(0, ships):322len = ships_list[i]323horizont_vertikal = random.randrange(1, 3) # 1- горизонтальное 2 - вертикальное324325primerno_x = random.randrange(0, s_x)326if primerno_x + len > s_x:327primerno_x = primerno_x - len328329primerno_y = random.randrange(0, s_y)330if primerno_y + len > s_y:331primerno_y = primerno_y - len332333# print(horizont_vertikal, primerno_x,primerno_y)334if horizont_vertikal == 1:335if primerno_x + len <= s_x:336for j in range(0, len):337try:338check_near_ships = 0339check_near_ships = enemy_ships[primerno_y][primerno_x - 1] + \340enemy_ships[primerno_y][primerno_x + j] + \341enemy_ships[primerno_y][primerno_x + j + 1] + \342enemy_ships[primerno_y + 1][primerno_x + j + 1] + \343enemy_ships[primerno_y - 1][primerno_x + j + 1] + \344enemy_ships[primerno_y + 1][primerno_x + j] + \345enemy_ships[primerno_y - 1][primerno_x + j]346# print(check_near_ships)347if check_near_ships == 0: # записываем в том случае, если нет ничего рядом348enemy_ships[primerno_y][primerno_x + j] = i + 1 # записываем номер корабля349except Exception:350pass351if horizont_vertikal == 2:352if primerno_y + len <= s_y:353for j in range(0, len):354try:355check_near_ships = 0356check_near_ships = enemy_ships[primerno_y - 1][primerno_x] + \357enemy_ships[primerno_y + j][primerno_x] + \358enemy_ships[primerno_y + j + 1][primerno_x] + \359enemy_ships[primerno_y + j + 1][primerno_x + 1] + \360enemy_ships[primerno_y + j + 1][primerno_x - 1] + \361enemy_ships[primerno_y + j][primerno_x + 1] + \362enemy_ships[primerno_y + j][primerno_x - 1]363# print(check_near_ships)364if check_near_ships == 0: # записываем в том случае, если нет ничего рядом365enemy_ships[primerno_y + j][primerno_x] = i + 1 # записываем номер корабля366except Exception:367pass368369# делаем подсчет 1ц370sum_1_enemy = 0371for i in range(0, s_x):372for j in range(0, s_y):373if enemy_ships[j][i] > 0:374sum_1_enemy = sum_1_enemy + 1375376# print(sum_1_enemy)377# print(ships_list)378# print(enemy_ships)379return enemy_ships380381382generate_ships_list()383# print(ships_list)384enemy_ships1 = generate_enemy_ships()385enemy_ships2 = generate_enemy_ships()386# print("****************************")387# print(enemy_ships1)388# print("****************************")389# print(enemy_ships2)390# print("****************************")391392while app_running:393if app_running:394tk.update_idletasks()395tk.update()396time.sleep(0.005)397398399