Path: blob/master/python-igra-morskoy-boy/main_lesson_18.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 # размер игрового поля - не меньше 8 и не больше 18 )))11#s_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_y1617txt_len_middle = "* Human vs Computer"18size_font_x = 1019len_txt_x = len(txt_len_middle)*size_font_x20print(len_txt_x)21delta_menu_x = len_txt_x // step_x + 122menu_x = step_x * delta_menu_x # 2502324menu_y = 4025ships = s_x // 2 # определяем максимальное кол-во кораблей26ship_len1 = s_x // 5 # длина первого типа корабля27ship_len2 = s_x // 3 # длина второго типа корабля28ship_len3 = s_x // 2 # длина третьего типа корабля29enemy_ships1 = [[0 for i in range(s_x + 1)] for i in range(s_y + 1)]30enemy_ships2 = [[0 for i in range(s_x + 1)] for i in range(s_y + 1)]31list_ids = [] # список объектов canvas3233# points1 - список куда мы кликнули мышкой34points1 = [[-1 for i in range(s_x)] for i in range(s_y)]35points2 = [[-1 for i in range(s_x)] for i in range(s_y)]3637# boom - список попаданий по кораблям противника38boom = [[0 for i in range(s_x)] for i in range(s_y)]3940# ships_list - список кораблей игрока 1 и игрока 241ships_list = []4243# hod_igrovomu_polu_1 - если Истина - то ходит игрок №2, иначе ходит игрок №144hod_igrovomu_polu_1 = False4546# computer_vs_human - если Истина - то играем против компьютера47computer_vs_human = False48if computer_vs_human:49add_to_label = " (Компьютер)"50add_to_label2 = " (прицеливается)"51hod_igrovomu_polu_1 = False52else:53add_to_label = ""54add_to_label2 = ""55hod_igrovomu_polu_1 = False5657# print(enemy_ships1)5859def on_closing():60global app_running61if messagebox.askokcancel("Выход из игры", "Хотите выйти из игры?"):62app_running = False63tk.destroy()646566tk.protocol("WM_DELETE_WINDOW", on_closing)67tk.title("Игра Морской Бой")68tk.resizable(0, 0)69tk.wm_attributes("-topmost", 1)70canvas = Canvas(tk, width=size_canvas_x + menu_x + size_canvas_x, height=size_canvas_y + menu_y, bd=0,71highlightthickness=0)72canvas.create_rectangle(0, 0, size_canvas_x, size_canvas_y, fill="white")73canvas.create_rectangle(size_canvas_x + menu_x, 0, size_canvas_x + menu_x + size_canvas_x, size_canvas_y,74fill="lightyellow")75canvas.pack()76tk.update()777879def draw_table(offset_x=0):80for i in range(0, s_x + 1):81canvas.create_line(offset_x + step_x * i, 0, offset_x + step_x * i, size_canvas_y)82for i in range(0, s_y + 1):83canvas.create_line(offset_x, step_y * i, offset_x + size_canvas_x, step_y * i)848586draw_table()87draw_table(size_canvas_x + menu_x)8889t0 = Label(tk, text="Игрок №1", font=("Helvetica", 16))90t0.place(x=size_canvas_x // 2 - t0.winfo_reqwidth() // 2, y=size_canvas_y + 3)91t1 = Label(tk, text="Игрок №2"+add_to_label, font=("Helvetica", 16))92t1.place(x=size_canvas_x + menu_x + size_canvas_x // 2 - t1.winfo_reqwidth() // 2, y=size_canvas_y + 3)9394t0.configure(bg="red")95t0.configure(bg="#f0f0f0")9697t3 = Label(tk, text="@@@@@@@", font=("Helvetica", 16))98t3.place(x=size_canvas_x + menu_x//2 - t3.winfo_reqwidth() // 2, y= size_canvas_y)99100101def change_rb():102global computer_vs_human, add_to_label, add_to_label2103print(rb_var.get())104if rb_var.get():105computer_vs_human = True106add_to_label = " (Компьютер)"107add_to_label2 = " (прицеливается)"108else:109computer_vs_human = False110add_to_label = ""111add_to_label2 = ""112113rb_var = BooleanVar()114rb1 = Radiobutton(tk, text="Human vs Computer", variable = rb_var, value=1, command=change_rb)115rb2 = Radiobutton(tk, text="Human vs Human", variable = rb_var, value=0, command=change_rb)116rb1.place(x=size_canvas_x + menu_x // 2 - rb1.winfo_reqwidth() // 2, y=140)117rb2.place(x=size_canvas_x + menu_x // 2 - rb2.winfo_reqwidth() // 2, y=160)118if computer_vs_human:119rb1.select()120121122def mark_igrok(igrok_mark_1):123if igrok_mark_1:124t0.configure(bg="red")125t0.configure(text="Игрок №1"+add_to_label2)126t0.place(x=size_canvas_x // 2 - t0.winfo_reqwidth() // 2, y=size_canvas_y + 3)127t1.configure(text="Игрок №2" + add_to_label)128t1.place(x=size_canvas_x + menu_x + size_canvas_x // 2 - t1.winfo_reqwidth() // 2, y=size_canvas_y + 3)129t1.configure(bg="#f0f0f0")130t3.configure(text="Ход Игрока №2"+add_to_label)131t3.place(x=size_canvas_x + menu_x // 2 - t3.winfo_reqwidth() // 2, y=size_canvas_y)132else:133t1.configure(bg="red")134t0.configure(bg="#f0f0f0")135t0.configure(text="Игрок №1")136t0.place(x=size_canvas_x // 2 - t0.winfo_reqwidth() // 2, y=size_canvas_y + 3)137t1.configure(text="Игрок №2" + add_to_label)138t1.place(x=size_canvas_x + menu_x + size_canvas_x // 2 - t1.winfo_reqwidth() // 2, y=size_canvas_y + 3)139t3.configure(text="Ход Игрока №1")140t3.place(x=size_canvas_x + menu_x // 2 - t3.winfo_reqwidth() // 2, y=size_canvas_y)141mark_igrok(hod_igrovomu_polu_1)142143144def button_show_enemy1():145for i in range(0, s_x):146for j in range(0, s_y):147if enemy_ships1[j][i] > 0:148color = "red"149if points1[j][i] != -1:150color = "green"151_id = canvas.create_rectangle(i * step_x, j * step_y, i * step_x + step_x, j * step_y + step_y,152fill=color)153list_ids.append(_id)154155156def button_show_enemy2():157for i in range(0, s_x):158for j in range(0, s_y):159if enemy_ships2[j][i] > 0:160color = "red"161if points2[j][i] != -1:162color = "green"163_id = canvas.create_rectangle(size_canvas_x + menu_x + i * step_x, j * step_y,164size_canvas_x + menu_x + i * step_x + step_x, j * step_y + step_y,165fill=color)166list_ids.append(_id)167168169def button_begin_again():170global list_ids171global points1, points2172global boom173global enemy_ships1, enemy_ships2174for el in list_ids:175canvas.delete(el)176list_ids = []177generate_ships_list()178# print(ships_list)179enemy_ships1 = generate_enemy_ships()180enemy_ships2 = generate_enemy_ships()181points1 = [[-1 for i in range(s_x)] for i in range(s_y)]182points2 = [[-1 for i in range(s_x)] for i in range(s_y)]183boom = [[0 for i in range(s_x)] for i in range(s_y)]184185186b0 = Button(tk, text="Показать корабли \n Игрока №1", command=button_show_enemy1)187b0.place(x=size_canvas_x + menu_x // 2 - b0.winfo_reqwidth() // 2, y=10)188189b1 = Button(tk, text="Показать корабли \n Игрока №2", command=button_show_enemy2)190b1.place(x=size_canvas_x + menu_x // 2 - b1.winfo_reqwidth() // 2, y=60)191192b2 = Button(tk, text="Начать заново!", command=button_begin_again)193b2.place(x=size_canvas_x + menu_x // 2 - b2.winfo_reqwidth() // 2, y=110)194195196def draw_point(x, y):197# print(enemy_ships1[y][x])198if enemy_ships1[y][x] == 0:199color = "red"200id1 = canvas.create_oval(x * step_x, y * step_y, x * step_x + step_x, y * step_y + step_y, fill=color)201id2 = canvas.create_oval(x * step_x + step_x // 3, y * step_y + step_y // 3, x * step_x + step_x - step_x // 3,202y * step_y + step_y - step_y // 3, fill="white")203list_ids.append(id1)204list_ids.append(id2)205if enemy_ships1[y][x] > 0:206color = "blue"207id1 = canvas.create_rectangle(x * step_x, y * step_y + step_y // 2 - step_y // 10, x * step_x + step_x,208y * step_y + step_y // 2 + step_y // 10, fill=color)209id2 = canvas.create_rectangle(x * step_x + step_x // 2 - step_x // 10, y * step_y,210x * step_x + step_x // 2 + step_x // 10, y * step_y + step_y, fill=color)211list_ids.append(id1)212list_ids.append(id2)213214215def draw_point2(x, y, offset_x=size_canvas_x + menu_x):216# print(enemy_ships1[y][x])217if enemy_ships2[y][x] == 0:218color = "red"219id1 = canvas.create_oval(offset_x + x * step_x, y * step_y, offset_x + x * step_x + step_x, y * step_y + step_y,220fill=color)221id2 = canvas.create_oval(offset_x + x * step_x + step_x // 3, y * step_y + step_y // 3,222offset_x + x * step_x + step_x - step_x // 3,223y * step_y + step_y - step_y // 3, fill="white")224list_ids.append(id1)225list_ids.append(id2)226if enemy_ships2[y][x] > 0:227color = "blue"228id1 = canvas.create_rectangle(offset_x + x * step_x, y * step_y + step_y // 2 - step_y // 10,229offset_x + x * step_x + step_x,230y * step_y + step_y // 2 + step_y // 10, fill=color)231id2 = canvas.create_rectangle(offset_x + x * step_x + step_x // 2 - step_x // 10, y * step_y,232offset_x + x * step_x + step_x // 2 + step_x // 10, y * step_y + step_y,233fill=color)234list_ids.append(id1)235list_ids.append(id2)236237238def check_winner(x, y):239win = False240if enemy_ships1[y][x] > 0:241boom[y][x] = enemy_ships1[y][x]242sum_enemy_ships1 = sum(sum(i) for i in zip(*enemy_ships1))243sum_boom = sum(sum(i) for i in zip(*boom))244# print(sum_enemy_ships1, sum_boom)245if sum_enemy_ships1 == sum_boom:246win = True247return win248249250def check_winner2():251win = True252for i in range(0, s_x):253for j in range(0, s_y):254if enemy_ships1[j][i] > 0:255if points1[j][i] == -1:256win = False257# print(win)258return win259260261def check_winner2_igrok_2():262win = True263for i in range(0, s_x):264for j in range(0, s_y):265if enemy_ships2[j][i] > 0:266if points2[j][i] == -1:267win = False268# print(win)269return win270271272def hod_computer():273global points1, points2, hod_igrovomu_polu_1274tk.update()275time.sleep(1)276hod_igrovomu_polu_1 = False277ip_x = random.randint(0, s_x-1)278ip_y = random.randint(0, s_y-1)279#print(ip_x, ip_y)280while not points1[ip_y][ip_x] == -1:281ip_x = random.randint(0, s_x-1)282ip_y = random.randint(0, s_y-1)283points1[ip_y][ip_x] = 7284draw_point(ip_x, ip_y)285if check_winner2():286winner = "Победа Игрока №2"+add_to_label287winner_add = "(Все корабли противника Игрока №1 подбиты)!!!!!"288print(winner, winner_add)289points1 = [[10 for i in range(s_x)] for i in range(s_y)]290points2 = [[10 for i in range(s_x)] for i in range(s_y)]291id1 = canvas.create_rectangle(step_x * 3, step_y * 3, size_canvas_x + menu_x + size_canvas_x - step_x * 3,292size_canvas_y - step_y, fill="blue")293list_ids.append(id1)294id2 = canvas.create_rectangle(step_x * 3 + step_x // 2, step_y * 3 + step_y // 2,295size_canvas_x + menu_x + size_canvas_x - step_x * 3 - step_x // 2,296size_canvas_y - step_y - step_y // 2, fill="yellow")297list_ids.append(id2)298id3 = canvas.create_text(step_x * 10, step_y * 5, text=winner, font=("Arial", 50), justify=CENTER)299id4 = canvas.create_text(step_x * 10, step_y * 6, text=winner_add, font=("Arial", 25), justify=CENTER)300list_ids.append(id3)301list_ids.append(id4)302303304def add_to_all(event):305global points1, points2, hod_igrovomu_polu_1306_type = 0 # ЛКМ307if event.num == 3:308_type = 1 # ПКМ309# print(_type)310mouse_x = canvas.winfo_pointerx() - canvas.winfo_rootx()311mouse_y = canvas.winfo_pointery() - canvas.winfo_rooty()312# print(mouse_x, mouse_y)313ip_x = mouse_x // step_x314ip_y = mouse_y // step_y315# print(ip_x, ip_y, "_type:", _type)316317# первое игровое поле318if ip_x < s_x and ip_y < s_y and hod_igrovomu_polu_1:319if points1[ip_y][ip_x] == -1:320points1[ip_y][ip_x] = _type321hod_igrovomu_polu_1 = False322draw_point(ip_x, ip_y)323# if check_winner(ip_x, ip_y):324if check_winner2():325hod_igrovomu_polu_1 = True326winner = "Победа Игрока №2"327winner_add = "(Все корабли противника Игрока №1 подбиты)!!!!!"328print(winner, winner_add)329points1 = [[10 for i in range(s_x)] for i in range(s_y)]330points2 = [[10 for i in range(s_x)] for i in range(s_y)]331id1 = canvas.create_rectangle(step_x*3, size_canvas_y // 2, size_canvas_x + menu_x + size_canvas_x-step_x*3, size_canvas_y // 2+step_y+step_y // 2 + 50 + 25 + step_y // 2, fill="blue")332list_ids.append(id1)333id2 = canvas.create_rectangle(step_x * 3+step_x//2, size_canvas_y // 2 +step_y//2,334size_canvas_x + menu_x + size_canvas_x - step_x * 3 - step_x//2,335size_canvas_y // 2+step_y+step_y // 2 + 50 + 25 + step_y // 2 - step_y//2, fill="yellow")336list_ids.append(id2)337id3 = canvas.create_text(size_canvas_x+menu_x//2, size_canvas_y // 2+step_y+step_y // 2, text=winner, font=("Arial", 50), justify=CENTER)338id4 = canvas.create_text(size_canvas_x+menu_x//2, size_canvas_y // 2+step_y+step_y // 2 + 50, text=winner_add, font=("Arial", 25), justify=CENTER)339list_ids.append(id3)340list_ids.append(id4)341342# print(len(list_ids))343344# второе игровое поле345if 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:346# print("ok")347if points2[ip_y][ip_x - s_x - delta_menu_x] == -1:348points2[ip_y][ip_x - s_x - delta_menu_x] = _type349hod_igrovomu_polu_1 = True350draw_point2(ip_x - s_x - delta_menu_x, ip_y)351# if check_winner(ip_x, ip_y):352if check_winner2_igrok_2():353hod_igrovomu_polu_1 = False354winner = "Победа Игрока №1"355winner_add = "(Все корабли противника Игрока №2 подбиты)!!!!!"356print(winner, winner_add)357points1 = [[10 for i in range(s_x)] for i in range(s_y)]358points2 = [[10 for i in range(s_x)] for i in range(s_y)]359id1 = canvas.create_rectangle(step_x * 3, size_canvas_y // 2,360size_canvas_x + menu_x + size_canvas_x - step_x * 3,361size_canvas_y // 2 + step_y + step_y // 2 + 50 + 25 + step_y // 2,362fill="blue")363list_ids.append(id1)364id2 = canvas.create_rectangle(step_x * 3 + step_x // 2, size_canvas_y // 2 + step_y // 2,365size_canvas_x + menu_x + size_canvas_x - step_x * 3 - step_x // 2,366size_canvas_y // 2 + step_y + step_y // 2 + 50 + 25 + step_y // 2 - step_y // 2,367fill="yellow")368list_ids.append(id2)369id3 = canvas.create_text(size_canvas_x + menu_x // 2, size_canvas_y // 2 + step_y + step_y // 2,370text=winner, font=("Arial", 50), justify=CENTER)371id4 = canvas.create_text(size_canvas_x + menu_x // 2, size_canvas_y // 2 + step_y + step_y // 2 + 50,372text=winner_add, font=("Arial", 25), justify=CENTER)373list_ids.append(id3)374list_ids.append(id4)375elif computer_vs_human:376mark_igrok(hod_igrovomu_polu_1)377hod_computer()378mark_igrok(hod_igrovomu_polu_1)379380canvas.bind_all("<Button-1>", add_to_all) # ЛКМ381canvas.bind_all("<Button-3>", add_to_all) # ПКМ382383384def generate_ships_list():385global ships_list386ships_list = []387# генерируем список случайных длин кораблей388for i in range(0, ships):389ships_list.append(random.choice([ship_len1, ship_len2, ship_len3]))390# print(ships_list)391392393def generate_enemy_ships():394global ships_list395enemy_ships = []396397# подсчет суммарной длины кораблей398sum_1_all_ships = sum(ships_list)399sum_1_enemy = 0400401# print("sum: ", sum_1_all_ships)402403while sum_1_enemy != sum_1_all_ships:404# обнуляем массив кораблей врага405enemy_ships = [[0 for i in range(s_x + 1)] for i in406range(s_y + 1)] # +1 для доп. линии справа и снизу, для успешных проверок генерации противника407408for i in range(0, ships):409len = ships_list[i]410horizont_vertikal = random.randrange(1, 3) # 1- горизонтальное 2 - вертикальное411412primerno_x = random.randrange(0, s_x)413if primerno_x + len > s_x:414primerno_x = primerno_x - len415416primerno_y = random.randrange(0, s_y)417if primerno_y + len > s_y:418primerno_y = primerno_y - len419420# print(horizont_vertikal, primerno_x,primerno_y)421if horizont_vertikal == 1:422if primerno_x + len <= s_x:423for j in range(0, len):424try:425check_near_ships = 0426check_near_ships = enemy_ships[primerno_y][primerno_x - 1] + \427enemy_ships[primerno_y][primerno_x + j] + \428enemy_ships[primerno_y][primerno_x + j + 1] + \429enemy_ships[primerno_y + 1][primerno_x + j + 1] + \430enemy_ships[primerno_y - 1][primerno_x + j + 1] + \431enemy_ships[primerno_y + 1][primerno_x + j] + \432enemy_ships[primerno_y - 1][primerno_x + j]433# print(check_near_ships)434if check_near_ships == 0: # записываем в том случае, если нет ничего рядом435enemy_ships[primerno_y][primerno_x + j] = i + 1 # записываем номер корабля436except Exception:437pass438if horizont_vertikal == 2:439if primerno_y + len <= s_y:440for j in range(0, len):441try:442check_near_ships = 0443check_near_ships = enemy_ships[primerno_y - 1][primerno_x] + \444enemy_ships[primerno_y + j][primerno_x] + \445enemy_ships[primerno_y + j + 1][primerno_x] + \446enemy_ships[primerno_y + j + 1][primerno_x + 1] + \447enemy_ships[primerno_y + j + 1][primerno_x - 1] + \448enemy_ships[primerno_y + j][primerno_x + 1] + \449enemy_ships[primerno_y + j][primerno_x - 1]450# print(check_near_ships)451if check_near_ships == 0: # записываем в том случае, если нет ничего рядом452enemy_ships[primerno_y + j][primerno_x] = i + 1 # записываем номер корабля453except Exception:454pass455456# делаем подсчет 1ц457sum_1_enemy = 0458for i in range(0, s_x):459for j in range(0, s_y):460if enemy_ships[j][i] > 0:461sum_1_enemy = sum_1_enemy + 1462463# print(sum_1_enemy)464# print(ships_list)465# print(enemy_ships)466return enemy_ships467468469generate_ships_list()470# print(ships_list)471enemy_ships1 = generate_enemy_ships()472enemy_ships2 = generate_enemy_ships()473# print("****************************")474# print(enemy_ships1)475# print("****************************")476# print(enemy_ships2)477# print("****************************")478479while app_running:480if app_running:481tk.update_idletasks()482tk.update()483time.sleep(0.005)484485486