Path: blob/master/python-igra-morskoy-boy/main_lesson_16.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 = True42if computer_vs_human:43add_to_label = " (Компьютер)"44hod_igrovomu_polu_1 = False45else:46add_to_label = ""47hod_igrovomu_polu_1 = False4849# print(enemy_ships1)5051def on_closing():52global app_running53if messagebox.askokcancel("Выход из игры", "Хотите выйти из игры?"):54app_running = False55tk.destroy()565758tk.protocol("WM_DELETE_WINDOW", on_closing)59tk.title("Игра Морской Бой")60tk.resizable(0, 0)61tk.wm_attributes("-topmost", 1)62canvas = Canvas(tk, width=size_canvas_x + menu_x + size_canvas_x, height=size_canvas_y + menu_y, bd=0,63highlightthickness=0)64canvas.create_rectangle(0, 0, size_canvas_x, size_canvas_y, fill="white")65canvas.create_rectangle(size_canvas_x + menu_x, 0, size_canvas_x + menu_x + size_canvas_x, size_canvas_y,66fill="lightyellow")67canvas.pack()68tk.update()697071def draw_table(offset_x=0):72for i in range(0, s_x + 1):73canvas.create_line(offset_x + step_x * i, 0, offset_x + step_x * i, size_canvas_y)74for i in range(0, s_y + 1):75canvas.create_line(offset_x, step_y * i, offset_x + size_canvas_x, step_y * i)767778draw_table()79draw_table(size_canvas_x + menu_x)8081t0 = Label(tk, text="Игрок №1", font=("Helvetica", 16))82t0.place(x=size_canvas_x // 2 - t0.winfo_reqwidth() // 2, y=size_canvas_y + 3)83t1 = Label(tk, text="Игрок №2"+add_to_label, font=("Helvetica", 16))84t1.place(x=size_canvas_x + menu_x + size_canvas_x // 2 - t1.winfo_reqwidth() // 2, y=size_canvas_y + 3)8586t0.configure(bg="red")87t0.configure(bg="#f0f0f0")8889t3 = Label(tk, text="@@@@@@@", font=("Helvetica", 16))90t3.place(x=size_canvas_x + menu_x//2 - t3.winfo_reqwidth() // 2, y= size_canvas_y)919293def mark_igrok(igrok_mark_1):94if igrok_mark_1:95t0.configure(bg="red")96t1.configure(bg="#f0f0f0")97t3.configure(text="Ход Игрока №2"+add_to_label)98t3.place(x=size_canvas_x + menu_x // 2 - t3.winfo_reqwidth() // 2, y=size_canvas_y)99else:100t1.configure(bg="red")101t0.configure(bg="#f0f0f0")102t3.configure(text="Ход Игрока №1")103t3.place(x=size_canvas_x + menu_x // 2 - t3.winfo_reqwidth() // 2, y=size_canvas_y)104mark_igrok(hod_igrovomu_polu_1)105106107def button_show_enemy1():108for i in range(0, s_x):109for j in range(0, s_y):110if enemy_ships1[j][i] > 0:111color = "red"112if points1[j][i] != -1:113color = "green"114_id = canvas.create_rectangle(i * step_x, j * step_y, i * step_x + step_x, j * step_y + step_y,115fill=color)116list_ids.append(_id)117118119def button_show_enemy2():120for i in range(0, s_x):121for j in range(0, s_y):122if enemy_ships2[j][i] > 0:123color = "red"124if points2[j][i] != -1:125color = "green"126_id = canvas.create_rectangle(size_canvas_x + menu_x + i * step_x, j * step_y,127size_canvas_x + menu_x + i * step_x + step_x, j * step_y + step_y,128fill=color)129list_ids.append(_id)130131132def button_begin_again():133global list_ids134global points1, points2135global boom136global enemy_ships1, enemy_ships2137for el in list_ids:138canvas.delete(el)139list_ids = []140generate_ships_list()141# print(ships_list)142enemy_ships1 = generate_enemy_ships()143enemy_ships2 = generate_enemy_ships()144points1 = [[-1 for i in range(s_x)] for i in range(s_y)]145points2 = [[-1 for i in range(s_x)] for i in range(s_y)]146boom = [[0 for i in range(s_x)] for i in range(s_y)]147148149b0 = Button(tk, text="Показать корабли Игрока №1", command=button_show_enemy1)150b0.place(x=size_canvas_x + 20, y=30)151152b1 = Button(tk, text="Показать корабли Игрока №2", command=button_show_enemy2)153b1.place(x=size_canvas_x + 20, y=70)154155b2 = Button(tk, text="Начать заново!", command=button_begin_again)156b2.place(x=size_canvas_x + 20, y=110)157158159def draw_point(x, y):160# print(enemy_ships1[y][x])161if enemy_ships1[y][x] == 0:162color = "red"163id1 = canvas.create_oval(x * step_x, y * step_y, x * step_x + step_x, y * step_y + step_y, fill=color)164id2 = canvas.create_oval(x * step_x + step_x // 3, y * step_y + step_y // 3, x * step_x + step_x - step_x // 3,165y * step_y + step_y - step_y // 3, fill="white")166list_ids.append(id1)167list_ids.append(id2)168if enemy_ships1[y][x] > 0:169color = "blue"170id1 = canvas.create_rectangle(x * step_x, y * step_y + step_y // 2 - step_y // 10, x * step_x + step_x,171y * step_y + step_y // 2 + step_y // 10, fill=color)172id2 = canvas.create_rectangle(x * step_x + step_x // 2 - step_x // 10, y * step_y,173x * step_x + step_x // 2 + step_x // 10, y * step_y + step_y, fill=color)174list_ids.append(id1)175list_ids.append(id2)176177178def draw_point2(x, y, offset_x=size_canvas_x + menu_x):179# print(enemy_ships1[y][x])180if enemy_ships2[y][x] == 0:181color = "red"182id1 = canvas.create_oval(offset_x + x * step_x, y * step_y, offset_x + x * step_x + step_x, y * step_y + step_y,183fill=color)184id2 = canvas.create_oval(offset_x + x * step_x + step_x // 3, y * step_y + step_y // 3,185offset_x + x * step_x + step_x - step_x // 3,186y * step_y + step_y - step_y // 3, fill="white")187list_ids.append(id1)188list_ids.append(id2)189if enemy_ships2[y][x] > 0:190color = "blue"191id1 = canvas.create_rectangle(offset_x + x * step_x, y * step_y + step_y // 2 - step_y // 10,192offset_x + x * step_x + step_x,193y * step_y + step_y // 2 + step_y // 10, fill=color)194id2 = canvas.create_rectangle(offset_x + x * step_x + step_x // 2 - step_x // 10, y * step_y,195offset_x + x * step_x + step_x // 2 + step_x // 10, y * step_y + step_y,196fill=color)197list_ids.append(id1)198list_ids.append(id2)199200201def check_winner(x, y):202win = False203if enemy_ships1[y][x] > 0:204boom[y][x] = enemy_ships1[y][x]205sum_enemy_ships1 = sum(sum(i) for i in zip(*enemy_ships1))206sum_boom = sum(sum(i) for i in zip(*boom))207# print(sum_enemy_ships1, sum_boom)208if sum_enemy_ships1 == sum_boom:209win = True210return win211212213def check_winner2():214win = True215for i in range(0, s_x):216for j in range(0, s_y):217if enemy_ships1[j][i] > 0:218if points1[j][i] == -1:219win = False220# print(win)221return win222223224def check_winner2_igrok_2():225win = True226for i in range(0, s_x):227for j in range(0, s_y):228if enemy_ships2[j][i] > 0:229if points2[j][i] == -1:230win = False231# print(win)232return win233234235def hod_computer():236global points1, points2, hod_igrovomu_polu_1237tk.update()238time.sleep(1)239hod_igrovomu_polu_1 = False240ip_x = random.randint(0, s_x-1)241ip_y = random.randint(0, s_y-1)242#print(ip_x, ip_y)243while not points1[ip_y][ip_x] == -1:244ip_x = random.randint(0, s_x-1)245ip_y = random.randint(0, s_y-1)246points1[ip_y][ip_x] = 7247draw_point(ip_x, ip_y)248if check_winner2():249winner = "Победа Игрока №2"+add_to_label250winner_add = "(Все корабли противника Игрока №1 подбиты)!!!!!"251print(winner, winner_add)252points1 = [[10 for i in range(s_x)] for i in range(s_y)]253points2 = [[10 for i in range(s_x)] for i in range(s_y)]254id1 = canvas.create_rectangle(step_x * 3, step_y * 3, size_canvas_x + menu_x + size_canvas_x - step_x * 3,255size_canvas_y - step_y, fill="blue")256list_ids.append(id1)257id2 = canvas.create_rectangle(step_x * 3 + step_x // 2, step_y * 3 + step_y // 2,258size_canvas_x + menu_x + size_canvas_x - step_x * 3 - step_x // 2,259size_canvas_y - step_y - step_y // 2, fill="yellow")260list_ids.append(id2)261id3 = canvas.create_text(step_x * 10, step_y * 5, text=winner, font=("Arial", 50), justify=CENTER)262id4 = canvas.create_text(step_x * 10, step_y * 6, text=winner_add, font=("Arial", 25), justify=CENTER)263list_ids.append(id3)264list_ids.append(id4)265266267def add_to_all(event):268global points1, points2, hod_igrovomu_polu_1269_type = 0 # ЛКМ270if event.num == 3:271_type = 1 # ПКМ272# print(_type)273mouse_x = canvas.winfo_pointerx() - canvas.winfo_rootx()274mouse_y = canvas.winfo_pointery() - canvas.winfo_rooty()275# print(mouse_x, mouse_y)276ip_x = mouse_x // step_x277ip_y = mouse_y // step_y278# print(ip_x, ip_y, "_type:", _type)279280# первое игровое поле281if ip_x < s_x and ip_y < s_y and hod_igrovomu_polu_1:282if points1[ip_y][ip_x] == -1:283points1[ip_y][ip_x] = _type284hod_igrovomu_polu_1 = False285draw_point(ip_x, ip_y)286# if check_winner(ip_x, ip_y):287if check_winner2():288hod_igrovomu_polu_1 = True289winner = "Победа Игрока №2"290winner_add = "(Все корабли противника Игрока №1 подбиты)!!!!!"291print(winner, winner_add)292points1 = [[10 for i in range(s_x)] for i in range(s_y)]293points2 = [[10 for i in range(s_x)] for i in range(s_y)]294id1 = 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")295list_ids.append(id1)296id2 = canvas.create_rectangle(step_x * 3+step_x//2, step_y * 3+step_y//2,297size_canvas_x + menu_x + size_canvas_x - step_x * 3 - step_x//2,298size_canvas_y - step_y - step_y//2, fill="yellow")299list_ids.append(id2)300id3 = canvas.create_text(step_x*10, step_y*5, text=winner, font=("Arial", 50), justify=CENTER)301id4 = canvas.create_text(step_x * 10, step_y * 6, text=winner_add, font=("Arial", 25), justify=CENTER)302list_ids.append(id3)303list_ids.append(id4)304305# print(len(list_ids))306307# второе игровое поле308if 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:309# print("ok")310if points2[ip_y][ip_x - s_x - delta_menu_x] == -1:311points2[ip_y][ip_x - s_x - delta_menu_x] = _type312hod_igrovomu_polu_1 = True313draw_point2(ip_x - s_x - delta_menu_x, ip_y)314# if check_winner(ip_x, ip_y):315if check_winner2_igrok_2():316hod_igrovomu_polu_1 = False317winner = "Победа Игрока №1"318winner_add = "(Все корабли противника Игрока №2 подбиты)!!!!!"319print(winner, winner_add)320points1 = [[10 for i in range(s_x)] for i in range(s_y)]321points2 = [[10 for i in range(s_x)] for i in range(s_y)]322id1 = canvas.create_rectangle(step_x * 3, step_y * 3,323size_canvas_x + menu_x + size_canvas_x - step_x * 3,324size_canvas_y - step_y, fill="blue")325list_ids.append(id1)326id2 = canvas.create_rectangle(step_x * 3 + step_x // 2, step_y * 3 + step_y // 2,327size_canvas_x + menu_x + size_canvas_x - step_x * 3 - step_x // 2,328size_canvas_y - step_y - step_y // 2, fill="yellow")329list_ids.append(id2)330id3 = canvas.create_text(step_x * 10, step_y * 5, text=winner, font=("Arial", 50), justify=CENTER)331id4 = canvas.create_text(step_x * 10, step_y * 6, text=winner_add, font=("Arial", 25), justify=CENTER)332list_ids.append(id3)333list_ids.append(id4)334elif computer_vs_human:335mark_igrok(hod_igrovomu_polu_1)336hod_computer()337mark_igrok(hod_igrovomu_polu_1)338339canvas.bind_all("<Button-1>", add_to_all) # ЛКМ340canvas.bind_all("<Button-3>", add_to_all) # ПКМ341342343def generate_ships_list():344global ships_list345ships_list = []346# генерируем список случайных длин кораблей347for i in range(0, ships):348ships_list.append(random.choice([ship_len1, ship_len2, ship_len3]))349# print(ships_list)350351352def generate_enemy_ships():353global ships_list354enemy_ships = []355356# подсчет суммарной длины кораблей357sum_1_all_ships = sum(ships_list)358sum_1_enemy = 0359360# print("sum: ", sum_1_all_ships)361362while sum_1_enemy != sum_1_all_ships:363# обнуляем массив кораблей врага364enemy_ships = [[0 for i in range(s_x + 1)] for i in365range(s_y + 1)] # +1 для доп. линии справа и снизу, для успешных проверок генерации противника366367for i in range(0, ships):368len = ships_list[i]369horizont_vertikal = random.randrange(1, 3) # 1- горизонтальное 2 - вертикальное370371primerno_x = random.randrange(0, s_x)372if primerno_x + len > s_x:373primerno_x = primerno_x - len374375primerno_y = random.randrange(0, s_y)376if primerno_y + len > s_y:377primerno_y = primerno_y - len378379# print(horizont_vertikal, primerno_x,primerno_y)380if horizont_vertikal == 1:381if primerno_x + len <= s_x:382for j in range(0, len):383try:384check_near_ships = 0385check_near_ships = enemy_ships[primerno_y][primerno_x - 1] + \386enemy_ships[primerno_y][primerno_x + j] + \387enemy_ships[primerno_y][primerno_x + j + 1] + \388enemy_ships[primerno_y + 1][primerno_x + j + 1] + \389enemy_ships[primerno_y - 1][primerno_x + j + 1] + \390enemy_ships[primerno_y + 1][primerno_x + j] + \391enemy_ships[primerno_y - 1][primerno_x + j]392# print(check_near_ships)393if check_near_ships == 0: # записываем в том случае, если нет ничего рядом394enemy_ships[primerno_y][primerno_x + j] = i + 1 # записываем номер корабля395except Exception:396pass397if horizont_vertikal == 2:398if primerno_y + len <= s_y:399for j in range(0, len):400try:401check_near_ships = 0402check_near_ships = enemy_ships[primerno_y - 1][primerno_x] + \403enemy_ships[primerno_y + j][primerno_x] + \404enemy_ships[primerno_y + j + 1][primerno_x] + \405enemy_ships[primerno_y + j + 1][primerno_x + 1] + \406enemy_ships[primerno_y + j + 1][primerno_x - 1] + \407enemy_ships[primerno_y + j][primerno_x + 1] + \408enemy_ships[primerno_y + j][primerno_x - 1]409# print(check_near_ships)410if check_near_ships == 0: # записываем в том случае, если нет ничего рядом411enemy_ships[primerno_y + j][primerno_x] = i + 1 # записываем номер корабля412except Exception:413pass414415# делаем подсчет 1ц416sum_1_enemy = 0417for i in range(0, s_x):418for j in range(0, s_y):419if enemy_ships[j][i] > 0:420sum_1_enemy = sum_1_enemy + 1421422# print(sum_1_enemy)423# print(ships_list)424# print(enemy_ships)425return enemy_ships426427428generate_ships_list()429# print(ships_list)430enemy_ships1 = generate_enemy_ships()431enemy_ships2 = generate_enemy_ships()432# print("****************************")433# print(enemy_ships1)434# print("****************************")435# print(enemy_ships2)436# print("****************************")437438while app_running:439if app_running:440tk.update_idletasks()441tk.update()442time.sleep(0.005)443444445