Path: blob/master/python-igra-morskoy-boy/main_lesson_17.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 = False3940# computer_vs_human - если Истина - то играем против компьютера41computer_vs_human = False42if computer_vs_human:43add_to_label = " (Компьютер)"44add_to_label2 = " (прицеливается)"45hod_igrovomu_polu_1 = False46else:47add_to_label = ""48add_to_label2 = ""49hod_igrovomu_polu_1 = False5051# print(enemy_ships1)5253def on_closing():54global app_running55if messagebox.askokcancel("Выход из игры", "Хотите выйти из игры?"):56app_running = False57tk.destroy()585960tk.protocol("WM_DELETE_WINDOW", on_closing)61tk.title("Игра Морской Бой")62tk.resizable(0, 0)63tk.wm_attributes("-topmost", 1)64canvas = Canvas(tk, width=size_canvas_x + menu_x + size_canvas_x, height=size_canvas_y + menu_y, bd=0,65highlightthickness=0)66canvas.create_rectangle(0, 0, size_canvas_x, size_canvas_y, fill="white")67canvas.create_rectangle(size_canvas_x + menu_x, 0, size_canvas_x + menu_x + size_canvas_x, size_canvas_y,68fill="lightyellow")69canvas.pack()70tk.update()717273def draw_table(offset_x=0):74for i in range(0, s_x + 1):75canvas.create_line(offset_x + step_x * i, 0, offset_x + step_x * i, size_canvas_y)76for i in range(0, s_y + 1):77canvas.create_line(offset_x, step_y * i, offset_x + size_canvas_x, step_y * i)787980draw_table()81draw_table(size_canvas_x + menu_x)8283t0 = Label(tk, text="Игрок №1", font=("Helvetica", 16))84t0.place(x=size_canvas_x // 2 - t0.winfo_reqwidth() // 2, y=size_canvas_y + 3)85t1 = Label(tk, text="Игрок №2"+add_to_label, font=("Helvetica", 16))86t1.place(x=size_canvas_x + menu_x + size_canvas_x // 2 - t1.winfo_reqwidth() // 2, y=size_canvas_y + 3)8788t0.configure(bg="red")89t0.configure(bg="#f0f0f0")9091t3 = Label(tk, text="@@@@@@@", font=("Helvetica", 16))92t3.place(x=size_canvas_x + menu_x//2 - t3.winfo_reqwidth() // 2, y= size_canvas_y)939495def change_rb():96global computer_vs_human, add_to_label, add_to_label297print(rb_var.get())98if rb_var.get():99computer_vs_human = True100add_to_label = " (Компьютер)"101add_to_label2 = " (прицеливается)"102else:103computer_vs_human = False104add_to_label = ""105add_to_label2 = ""106107rb_var = BooleanVar()108rb1 = Radiobutton(tk, text="Human vs Computer", variable = rb_var, value=1, command=change_rb)109rb2 = Radiobutton(tk, text="Human vs Human", variable = rb_var, value=0, command=change_rb)110rb1.place(x=size_canvas_x + 20, y=140)111rb2.place(x=size_canvas_x + 20, y=160)112if computer_vs_human:113rb1.select()114115116def mark_igrok(igrok_mark_1):117if igrok_mark_1:118t0.configure(bg="red")119t0.configure(text="Игрок №1"+add_to_label2)120t0.place(x=size_canvas_x // 2 - t0.winfo_reqwidth() // 2, y=size_canvas_y + 3)121t1.configure(text="Игрок №2" + add_to_label)122t1.place(x=size_canvas_x + menu_x + size_canvas_x // 2 - t1.winfo_reqwidth() // 2, y=size_canvas_y + 3)123t1.configure(bg="#f0f0f0")124t3.configure(text="Ход Игрока №2"+add_to_label)125t3.place(x=size_canvas_x + menu_x // 2 - t3.winfo_reqwidth() // 2, y=size_canvas_y)126else:127t1.configure(bg="red")128t0.configure(bg="#f0f0f0")129t0.configure(text="Игрок №1")130t0.place(x=size_canvas_x // 2 - t0.winfo_reqwidth() // 2, y=size_canvas_y + 3)131t1.configure(text="Игрок №2" + add_to_label)132t1.place(x=size_canvas_x + menu_x + size_canvas_x // 2 - t1.winfo_reqwidth() // 2, y=size_canvas_y + 3)133t3.configure(text="Ход Игрока №1")134t3.place(x=size_canvas_x + menu_x // 2 - t3.winfo_reqwidth() // 2, y=size_canvas_y)135mark_igrok(hod_igrovomu_polu_1)136137138def button_show_enemy1():139for i in range(0, s_x):140for j in range(0, s_y):141if enemy_ships1[j][i] > 0:142color = "red"143if points1[j][i] != -1:144color = "green"145_id = canvas.create_rectangle(i * step_x, j * step_y, i * step_x + step_x, j * step_y + step_y,146fill=color)147list_ids.append(_id)148149150def button_show_enemy2():151for i in range(0, s_x):152for j in range(0, s_y):153if enemy_ships2[j][i] > 0:154color = "red"155if points2[j][i] != -1:156color = "green"157_id = canvas.create_rectangle(size_canvas_x + menu_x + i * step_x, j * step_y,158size_canvas_x + menu_x + i * step_x + step_x, j * step_y + step_y,159fill=color)160list_ids.append(_id)161162163def button_begin_again():164global list_ids165global points1, points2166global boom167global enemy_ships1, enemy_ships2168for el in list_ids:169canvas.delete(el)170list_ids = []171generate_ships_list()172# print(ships_list)173enemy_ships1 = generate_enemy_ships()174enemy_ships2 = generate_enemy_ships()175points1 = [[-1 for i in range(s_x)] for i in range(s_y)]176points2 = [[-1 for i in range(s_x)] for i in range(s_y)]177boom = [[0 for i in range(s_x)] for i in range(s_y)]178179180b0 = Button(tk, text="Показать корабли Игрока №1", command=button_show_enemy1)181b0.place(x=size_canvas_x + 20, y=30)182183b1 = Button(tk, text="Показать корабли Игрока №2", command=button_show_enemy2)184b1.place(x=size_canvas_x + 20, y=70)185186b2 = Button(tk, text="Начать заново!", command=button_begin_again)187b2.place(x=size_canvas_x + 20, y=110)188189190def draw_point(x, y):191# print(enemy_ships1[y][x])192if enemy_ships1[y][x] == 0:193color = "red"194id1 = canvas.create_oval(x * step_x, y * step_y, x * step_x + step_x, y * step_y + step_y, fill=color)195id2 = canvas.create_oval(x * step_x + step_x // 3, y * step_y + step_y // 3, x * step_x + step_x - step_x // 3,196y * step_y + step_y - step_y // 3, fill="white")197list_ids.append(id1)198list_ids.append(id2)199if enemy_ships1[y][x] > 0:200color = "blue"201id1 = canvas.create_rectangle(x * step_x, y * step_y + step_y // 2 - step_y // 10, x * step_x + step_x,202y * step_y + step_y // 2 + step_y // 10, fill=color)203id2 = canvas.create_rectangle(x * step_x + step_x // 2 - step_x // 10, y * step_y,204x * step_x + step_x // 2 + step_x // 10, y * step_y + step_y, fill=color)205list_ids.append(id1)206list_ids.append(id2)207208209def draw_point2(x, y, offset_x=size_canvas_x + menu_x):210# print(enemy_ships1[y][x])211if enemy_ships2[y][x] == 0:212color = "red"213id1 = canvas.create_oval(offset_x + x * step_x, y * step_y, offset_x + x * step_x + step_x, y * step_y + step_y,214fill=color)215id2 = canvas.create_oval(offset_x + x * step_x + step_x // 3, y * step_y + step_y // 3,216offset_x + x * step_x + step_x - step_x // 3,217y * step_y + step_y - step_y // 3, fill="white")218list_ids.append(id1)219list_ids.append(id2)220if enemy_ships2[y][x] > 0:221color = "blue"222id1 = canvas.create_rectangle(offset_x + x * step_x, y * step_y + step_y // 2 - step_y // 10,223offset_x + x * step_x + step_x,224y * step_y + step_y // 2 + step_y // 10, fill=color)225id2 = canvas.create_rectangle(offset_x + x * step_x + step_x // 2 - step_x // 10, y * step_y,226offset_x + x * step_x + step_x // 2 + step_x // 10, y * step_y + step_y,227fill=color)228list_ids.append(id1)229list_ids.append(id2)230231232def check_winner(x, y):233win = False234if enemy_ships1[y][x] > 0:235boom[y][x] = enemy_ships1[y][x]236sum_enemy_ships1 = sum(sum(i) for i in zip(*enemy_ships1))237sum_boom = sum(sum(i) for i in zip(*boom))238# print(sum_enemy_ships1, sum_boom)239if sum_enemy_ships1 == sum_boom:240win = True241return win242243244def check_winner2():245win = True246for i in range(0, s_x):247for j in range(0, s_y):248if enemy_ships1[j][i] > 0:249if points1[j][i] == -1:250win = False251# print(win)252return win253254255def check_winner2_igrok_2():256win = True257for i in range(0, s_x):258for j in range(0, s_y):259if enemy_ships2[j][i] > 0:260if points2[j][i] == -1:261win = False262# print(win)263return win264265266def hod_computer():267global points1, points2, hod_igrovomu_polu_1268tk.update()269time.sleep(1)270hod_igrovomu_polu_1 = False271ip_x = random.randint(0, s_x-1)272ip_y = random.randint(0, s_y-1)273#print(ip_x, ip_y)274while not points1[ip_y][ip_x] == -1:275ip_x = random.randint(0, s_x-1)276ip_y = random.randint(0, s_y-1)277points1[ip_y][ip_x] = 7278draw_point(ip_x, ip_y)279if check_winner2():280winner = "Победа Игрока №2"+add_to_label281winner_add = "(Все корабли противника Игрока №1 подбиты)!!!!!"282print(winner, winner_add)283points1 = [[10 for i in range(s_x)] for i in range(s_y)]284points2 = [[10 for i in range(s_x)] for i in range(s_y)]285id1 = canvas.create_rectangle(step_x * 3, step_y * 3, size_canvas_x + menu_x + size_canvas_x - step_x * 3,286size_canvas_y - step_y, fill="blue")287list_ids.append(id1)288id2 = canvas.create_rectangle(step_x * 3 + step_x // 2, step_y * 3 + step_y // 2,289size_canvas_x + menu_x + size_canvas_x - step_x * 3 - step_x // 2,290size_canvas_y - step_y - step_y // 2, fill="yellow")291list_ids.append(id2)292id3 = canvas.create_text(step_x * 10, step_y * 5, text=winner, font=("Arial", 50), justify=CENTER)293id4 = canvas.create_text(step_x * 10, step_y * 6, text=winner_add, font=("Arial", 25), justify=CENTER)294list_ids.append(id3)295list_ids.append(id4)296297298def add_to_all(event):299global points1, points2, hod_igrovomu_polu_1300_type = 0 # ЛКМ301if event.num == 3:302_type = 1 # ПКМ303# print(_type)304mouse_x = canvas.winfo_pointerx() - canvas.winfo_rootx()305mouse_y = canvas.winfo_pointery() - canvas.winfo_rooty()306# print(mouse_x, mouse_y)307ip_x = mouse_x // step_x308ip_y = mouse_y // step_y309# print(ip_x, ip_y, "_type:", _type)310311# первое игровое поле312if ip_x < s_x and ip_y < s_y and hod_igrovomu_polu_1:313if points1[ip_y][ip_x] == -1:314points1[ip_y][ip_x] = _type315hod_igrovomu_polu_1 = False316draw_point(ip_x, ip_y)317# if check_winner(ip_x, ip_y):318if check_winner2():319hod_igrovomu_polu_1 = True320winner = "Победа Игрока №2"321winner_add = "(Все корабли противника Игрока №1 подбиты)!!!!!"322print(winner, winner_add)323points1 = [[10 for i in range(s_x)] for i in range(s_y)]324points2 = [[10 for i in range(s_x)] for i in range(s_y)]325id1 = 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")326list_ids.append(id1)327id2 = canvas.create_rectangle(step_x * 3+step_x//2, step_y * 3+step_y//2,328size_canvas_x + menu_x + size_canvas_x - step_x * 3 - step_x//2,329size_canvas_y - step_y - step_y//2, fill="yellow")330list_ids.append(id2)331id3 = canvas.create_text(step_x*10, step_y*5, text=winner, font=("Arial", 50), justify=CENTER)332id4 = canvas.create_text(step_x * 10, step_y * 6, text=winner_add, font=("Arial", 25), justify=CENTER)333list_ids.append(id3)334list_ids.append(id4)335336# print(len(list_ids))337338# второе игровое поле339if 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:340# print("ok")341if points2[ip_y][ip_x - s_x - delta_menu_x] == -1:342points2[ip_y][ip_x - s_x - delta_menu_x] = _type343hod_igrovomu_polu_1 = True344draw_point2(ip_x - s_x - delta_menu_x, ip_y)345# if check_winner(ip_x, ip_y):346if check_winner2_igrok_2():347hod_igrovomu_polu_1 = False348winner = "Победа Игрока №1"349winner_add = "(Все корабли противника Игрока №2 подбиты)!!!!!"350print(winner, winner_add)351points1 = [[10 for i in range(s_x)] for i in range(s_y)]352points2 = [[10 for i in range(s_x)] for i in range(s_y)]353id1 = canvas.create_rectangle(step_x * 3, step_y * 3,354size_canvas_x + menu_x + size_canvas_x - step_x * 3,355size_canvas_y - step_y, fill="blue")356list_ids.append(id1)357id2 = canvas.create_rectangle(step_x * 3 + step_x // 2, step_y * 3 + step_y // 2,358size_canvas_x + menu_x + size_canvas_x - step_x * 3 - step_x // 2,359size_canvas_y - step_y - step_y // 2, fill="yellow")360list_ids.append(id2)361id3 = canvas.create_text(step_x * 10, step_y * 5, text=winner, font=("Arial", 50), justify=CENTER)362id4 = canvas.create_text(step_x * 10, step_y * 6, text=winner_add, font=("Arial", 25), justify=CENTER)363list_ids.append(id3)364list_ids.append(id4)365elif computer_vs_human:366mark_igrok(hod_igrovomu_polu_1)367hod_computer()368mark_igrok(hod_igrovomu_polu_1)369370canvas.bind_all("<Button-1>", add_to_all) # ЛКМ371canvas.bind_all("<Button-3>", add_to_all) # ПКМ372373374def generate_ships_list():375global ships_list376ships_list = []377# генерируем список случайных длин кораблей378for i in range(0, ships):379ships_list.append(random.choice([ship_len1, ship_len2, ship_len3]))380# print(ships_list)381382383def generate_enemy_ships():384global ships_list385enemy_ships = []386387# подсчет суммарной длины кораблей388sum_1_all_ships = sum(ships_list)389sum_1_enemy = 0390391# print("sum: ", sum_1_all_ships)392393while sum_1_enemy != sum_1_all_ships:394# обнуляем массив кораблей врага395enemy_ships = [[0 for i in range(s_x + 1)] for i in396range(s_y + 1)] # +1 для доп. линии справа и снизу, для успешных проверок генерации противника397398for i in range(0, ships):399len = ships_list[i]400horizont_vertikal = random.randrange(1, 3) # 1- горизонтальное 2 - вертикальное401402primerno_x = random.randrange(0, s_x)403if primerno_x + len > s_x:404primerno_x = primerno_x - len405406primerno_y = random.randrange(0, s_y)407if primerno_y + len > s_y:408primerno_y = primerno_y - len409410# print(horizont_vertikal, primerno_x,primerno_y)411if horizont_vertikal == 1:412if primerno_x + len <= s_x:413for j in range(0, len):414try:415check_near_ships = 0416check_near_ships = enemy_ships[primerno_y][primerno_x - 1] + \417enemy_ships[primerno_y][primerno_x + j] + \418enemy_ships[primerno_y][primerno_x + j + 1] + \419enemy_ships[primerno_y + 1][primerno_x + j + 1] + \420enemy_ships[primerno_y - 1][primerno_x + j + 1] + \421enemy_ships[primerno_y + 1][primerno_x + j] + \422enemy_ships[primerno_y - 1][primerno_x + j]423# print(check_near_ships)424if check_near_ships == 0: # записываем в том случае, если нет ничего рядом425enemy_ships[primerno_y][primerno_x + j] = i + 1 # записываем номер корабля426except Exception:427pass428if horizont_vertikal == 2:429if primerno_y + len <= s_y:430for j in range(0, len):431try:432check_near_ships = 0433check_near_ships = enemy_ships[primerno_y - 1][primerno_x] + \434enemy_ships[primerno_y + j][primerno_x] + \435enemy_ships[primerno_y + j + 1][primerno_x] + \436enemy_ships[primerno_y + j + 1][primerno_x + 1] + \437enemy_ships[primerno_y + j + 1][primerno_x - 1] + \438enemy_ships[primerno_y + j][primerno_x + 1] + \439enemy_ships[primerno_y + j][primerno_x - 1]440# print(check_near_ships)441if check_near_ships == 0: # записываем в том случае, если нет ничего рядом442enemy_ships[primerno_y + j][primerno_x] = i + 1 # записываем номер корабля443except Exception:444pass445446# делаем подсчет 1ц447sum_1_enemy = 0448for i in range(0, s_x):449for j in range(0, s_y):450if enemy_ships[j][i] > 0:451sum_1_enemy = sum_1_enemy + 1452453# print(sum_1_enemy)454# print(ships_list)455# print(enemy_ships)456return enemy_ships457458459generate_ships_list()460# print(ships_list)461enemy_ships1 = generate_enemy_ships()462enemy_ships2 = generate_enemy_ships()463# print("****************************")464# print(enemy_ships1)465# print("****************************")466# print(enemy_ships2)467# print("****************************")468469while app_running:470if app_running:471tk.update_idletasks()472tk.update()473time.sleep(0.005)474475476