sphinx2001

морской бой. 2 группа. часть 5

Dec 1st, 2020
698
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import tkinter as tk
  2. from tkinter import messagebox
  3. import time
  4. import random
  5. '''
  6. battle_map[y][x] == 0 пустое поле
  7. battle_map[y][x] == 1 палуба корабля
  8. battle_map[y][x] == 2 выстрел мимо
  9. battle_map[y][x] == 3 попадание
  10. '''
  11. def check_end():
  12.     global battle_map1, battle_map2
  13.     player1 = 0
  14.     for line in battle_map1:
  15.         player1 += line.count(1)
  16.     player2 = 0
  17.     for line in battle_map2:
  18.         player2 += line.count(1)
  19.     print(player1)
  20.     print(player2)
  21.     if player1 == 0: # выиграл игрок 1
  22.         messagebox.showinfo("Морской бой", "Выиграл игрок №2")
  23.         return True
  24.     if player2 == 0: # выиграл игрок 2
  25.         messagebox.showinfo("Морской бой", "Выиграл игрок №1")
  26.         return True
  27.  
  28.     return False
  29.  
  30.  
  31.  
  32. def generate_battle_map1():
  33.     global battle_map1
  34.     ships = cells_w // 2 # общее количество кораблей
  35.     ships_config = [] # сколько и какого типа кораблей мы будем создавать
  36.     for i in range(ships):
  37.         ships_config.append(random.choice([1, 2, 3]))
  38.  
  39.     sum_all_ships = sum(ships_config) # количество заполненное кораблями
  40.     sum_enemy = 0
  41.     while sum_enemy != sum_all_ships:
  42.         battle_map1 = [[0 for x in range(cells_w)] for y in range(cells_h)]
  43.         for i in range(ships):
  44.             ls = ships_config[i] # длина коробля
  45.             horizontal_vertical = random.randint(0, 2) # 0 горизонтали, 1 по вертикали
  46.             pos_x = random.randint(0, cells_w) # стартовая позиция корабля по оси x
  47.             pos_y = random.randint(0, cells_h) # стартовая позиция корабля по оси y
  48.  
  49.             if horizontal_vertical == 0: # по горизонтали
  50.                 if pos_x + ls < cells_w:
  51.                     for j in range(ls):
  52.                         try:
  53.                             check_near_ships = 0
  54.                             check_near_ships = battle_map1[pos_y][pos_x - 1] + \
  55.                                 battle_map1[pos_y][pos_x + j] + \
  56.                                 battle_map1[pos_y][pos_x + j + 1] + \
  57.                                 battle_map1[pos_y + 1][pos_x + j + 1] + \
  58.                                 battle_map1[pos_y - 1][pos_x + j + 1] + \
  59.                                 battle_map1[pos_y + 1][pos_x + j] + \
  60.                                 battle_map1[pos_y - 1][pos_x + j]
  61.  
  62.                             if check_near_ships == 0:
  63.                                 battle_map1[pos_y][pos_x] = 1
  64.  
  65.                         except Exception:
  66.                             pass
  67.             else: # по вертикали
  68.                 if pos_y + ls < cells_h:
  69.                     for j in range(ls):
  70.                         try:
  71.                             check_near_ships = 0
  72.                             check_near_ships = battle_map1[pos_y - 1][pos_x] + \
  73.                                 battle_map1[pos_y + j][pos_x] + \
  74.                                 battle_map1[pos_y + j + 1][pos_x] + \
  75.                                 battle_map1[pos_y + j + 1][pos_x + 1] + \
  76.                                 battle_map1[pos_y + j + 1][pos_x - 1] + \
  77.                                 battle_map1[pos_y + j][pos_x + 1] + \
  78.                                 battle_map1[pos_y + j][pos_x - 1]
  79.                             if check_near_ships == 0:
  80.                                 battle_map1[pos_y + j][pos_x] = 1
  81.                         except Exception:
  82.                             pass
  83.  
  84.             sum_enemy = 0
  85.             for row in battle_map1:
  86.                 sum_enemy += sum(row)
  87.  
  88. def generate_battle_map2():
  89.     global battle_map2
  90.     ships = cells_w // 2 # общее количество кораблей
  91.     ships_config = [] # сколько и какого типа кораблей мы будем создавать
  92.     for i in range(ships):
  93.         ships_config.append(random.choice([1, 2, 3]))
  94.  
  95.     sum_all_ships = sum(ships_config) # количество заполненное кораблями
  96.     sum_enemy = 0
  97.     while sum_enemy != sum_all_ships:
  98.         battle_map2 = [[0 for x in range(cells_w)] for y in range(cells_h)]
  99.         for i in range(ships):
  100.             ls = ships_config[i] # длина коробля
  101.             horizontal_vertical = random.randint(0, 2) # 0 горизонтали, 1 по вертикали
  102.             pos_x = random.randint(0, cells_w) # стартовая позиция корабля по оси x
  103.             pos_y = random.randint(0, cells_h) # стартовая позиция корабля по оси y
  104.  
  105.             if horizontal_vertical == 0: # по горизонтали
  106.                 if pos_x + ls < cells_w:
  107.                     for j in range(ls):
  108.                         try:
  109.                             check_near_ships = 0
  110.                             check_near_ships = battle_map2[pos_y][pos_x - 1] + \
  111.                                 battle_map2[pos_y][pos_x + j] + \
  112.                                 battle_map2[pos_y][pos_x + j + 1] + \
  113.                                 battle_map2[pos_y + 1][pos_x + j + 1] + \
  114.                                 battle_map2[pos_y - 1][pos_x + j + 1] + \
  115.                                 battle_map2[pos_y + 1][pos_x + j] + \
  116.                                 battle_map2[pos_y - 1][pos_x + j]
  117.  
  118.                             if check_near_ships == 0:
  119.                                 battle_map2[pos_y][pos_x] = 1
  120.  
  121.                         except Exception:
  122.                             pass
  123.             else: # по вертикали
  124.                 if pos_y + ls < cells_h:
  125.                     for j in range(ls):
  126.                         try:
  127.                             check_near_ships = 0
  128.                             check_near_ships = battle_map2[pos_y - 1][pos_x] + \
  129.                                 battle_map2[pos_y + j][pos_x] + \
  130.                                 battle_map2[pos_y + j + 1][pos_x] + \
  131.                                 battle_map2[pos_y + j + 1][pos_x + 1] + \
  132.                                 battle_map2[pos_y + j + 1][pos_x - 1] + \
  133.                                 battle_map2[pos_y + j][pos_x + 1] + \
  134.                                 battle_map2[pos_y + j][pos_x - 1]
  135.                             if check_near_ships == 0:
  136.                                 battle_map2[pos_y + j][pos_x] = 1
  137.                         except Exception:
  138.                             pass
  139.  
  140.             sum_enemy = 0
  141.             for row in battle_map2:
  142.                 sum_enemy += sum(row)
  143.  
  144.  
  145. def hit(x, y):
  146.     global turn, end_game
  147.     if turn: # battle_map2 - 2 игрок
  148.         cel = battle_map2[y][x]
  149.         if cel == 0:
  150.             battle_map2[y][x] = 2
  151.             turn = 0
  152.             #cid = canvas.create_rectangle(i * cell_size_w, j * cell_size_h, (i + 1) * cell_size_w, (j + 1) * cell_size_h, fill="red")
  153.             cid = canvas.create_oval(size_w + menu_x + cell_size_w * x, y * cell_size_h, size_w + menu_x + cell_size_w * (x + 1), (y + 1) * cell_size_h, fill='red')
  154.             canvas_elements.append(cid)
  155.             cid = canvas.create_oval(size_w + menu_x + cell_size_w * x + cell_size_w // 4, y * cell_size_h + cell_size_h // 4,
  156.                                      size_w + menu_x + cell_size_w * (x + 1) - cell_size_w // 4, (y + 1) * cell_size_h - cell_size_h // 4, fill='white')
  157.             canvas_elements.append(cid)
  158.         elif cel == 1:
  159.             battle_map2[y][x] = 3
  160.             cid = canvas.create_rectangle(size_w + menu_x + cell_size_w * x + cell_size_w // 3, y * cell_size_h,
  161.                                      size_w + menu_x + cell_size_w * (x + 1) - cell_size_w // 3, (y + 1) * cell_size_h, fill='blue')
  162.             canvas_elements.append(cid)
  163.             cid = canvas.create_rectangle(size_w + menu_x + cell_size_w * x,
  164.                                      y * cell_size_h + cell_size_h // 3,
  165.                                      size_w + menu_x + cell_size_w * (x + 1),
  166.                                      (y + 1) * cell_size_h - cell_size_h // 3, fill='blue')
  167.             canvas_elements.append(cid)
  168.             turn = 0
  169.     else:
  170.         cel = battle_map1[y][x]
  171.         if cel == 0:
  172.             battle_map1[y][x] = 2
  173.             turn = 1
  174.             cid = canvas.create_oval(cell_size_w * x, y * cell_size_h,
  175.                                      cell_size_w * (x + 1), (y + 1) * cell_size_h, fill='red')
  176.             canvas_elements.append(cid)
  177.             cid = canvas.create_oval(cell_size_w * x + cell_size_w // 4,
  178.                                      y * cell_size_h + cell_size_h // 4,
  179.                                      cell_size_w * (x + 1) - cell_size_w // 4,
  180.                                      (y + 1) * cell_size_h - cell_size_h // 4, fill='white')
  181.             canvas_elements.append(cid)
  182.         elif cel == 1:
  183.             battle_map1[y][x] = 3
  184.             cid = canvas.create_rectangle(cell_size_w * x + cell_size_w // 3, y * cell_size_h,
  185.                                           cell_size_w * (x + 1) - cell_size_w // 3,
  186.                                           (y + 1) * cell_size_h, fill='blue')
  187.             canvas_elements.append(cid)
  188.             cid = canvas.create_rectangle(cell_size_w * x,
  189.                                           y * cell_size_h + cell_size_h // 3,
  190.                                           cell_size_w * (x + 1),
  191.                                           (y + 1) * cell_size_h - cell_size_h // 3, fill='blue')
  192.             canvas_elements.append(cid)
  193.             turn = 1
  194.     # проверка окончания игры
  195.     end_game = check_end()
  196.  
  197.  
  198.  
  199. def on_click_canvas(event):
  200.     global turn
  201.     _button = 0
  202.     if event.num == 3:
  203.         _button = 1
  204.     mouse_x = canvas.winfo_pointerx() - canvas.winfo_rootx()
  205.     mouse_y = canvas.winfo_pointery() - canvas.winfo_rooty()
  206.     if end_game:
  207.         return
  208.     if turn:
  209.         offset = size_w + menu_x
  210.         if offset <= mouse_x <= size_w + offset and 0 <= mouse_y <= size_h:
  211.             map_x = (mouse_x - offset) // cell_size_w
  212.             map_y = mouse_y // cell_size_h
  213.             hit(map_x, map_y)
  214.             print(f"Click button {_button} x:{mouse_x}, y:{mouse_y} cell({map_x},{map_y})")
  215.  
  216.     else:
  217.         if 0 <= mouse_x <= size_w and 0 <= mouse_y <= size_h:
  218.             map_x = mouse_x // cell_size_w
  219.             map_y = mouse_y // cell_size_h
  220.             hit(map_x, map_y)
  221.             print(f"Click button {_button} x:{mouse_x}, y:{mouse_y} cell({map_x},{map_y})")
  222.  
  223.     if turn: # в зависимости от хода меняем фон у игроков
  224.         lb_player2.config(bg="yellow")
  225.         lb_player1.config(bg="grey")
  226.     else:
  227.         lb_player1.config(bg="yellow")
  228.         lb_player2.config(bg="grey")
  229.  
  230.  
  231.  
  232.  
  233. def command_new_game():
  234.     global end_game
  235.     end_game = False
  236.     for el in canvas_elements:
  237.         canvas.delete(el)   # очистка холста
  238.  
  239.     draw_game_map() # перерисуем разметку
  240.     generate_battle_map1()
  241.     generate_battle_map2()
  242.  
  243.  
  244. def command_debug_show_ships():
  245.     # battle_map[0][1] = 1
  246.     # battle_map[cells_h - 1][cells_w - 1] = 1
  247.     for i in range(cells_w):
  248.         for j in range(cells_h):
  249.             if battle_map1[j][i] != 0:
  250.                 cid = canvas.create_rectangle(i * cell_size_w, j * cell_size_h, (i + 1) * cell_size_w, (j + 1) * cell_size_h, fill="red")
  251.                 canvas_elements.append(cid)
  252.  
  253. def on_close_window():
  254.     global run_app
  255.     if messagebox.askokcancel("Морской бой", "Завершить работу программы?"):
  256.         run_app = False
  257.         game.destroy()
  258.  
  259. def draw_game_map():
  260.     cid = canvas.create_rectangle(0, 0, size_w, size_h, fill="white")
  261.     canvas_elements.append(cid)
  262.  
  263.     cid = canvas.create_rectangle(size_w + menu_x, 0, size_w*2+menu_x, size_h, fill="white")
  264.     canvas_elements.append(cid)
  265.  
  266.     for i in range(cells_w + 1):
  267.         cid = canvas.create_line(cell_size_w * i, 0, cell_size_w * i, size_h)
  268.         canvas_elements.append(cid)
  269.  
  270.     for i in range(cells_h + 1):
  271.         cid = canvas.create_line(0, cell_size_h * i, size_w, cell_size_h * i)
  272.         canvas_elements.append(cid)
  273.  
  274.     o = size_w + menu_x # смещение по оси x для второго игорового поля
  275.  
  276.     for i in range(cells_w + 1):
  277.         cid = canvas.create_line(o + cell_size_w * i, 0, o+cell_size_w * i, size_h)
  278.         canvas_elements.append(cid)
  279.  
  280.     for i in range(cells_h + 1):
  281.         cid = canvas.create_line(o, cell_size_h * i, o + size_w, cell_size_h * i)
  282.         canvas_elements.append(cid)
  283.  
  284. size_w = 400
  285. size_h = 400
  286. cells_w = 5
  287. cells_h = 5
  288. cell_size_w = size_w // cells_w
  289. cell_size_h = size_h // cells_h
  290. size_w = cells_w * cell_size_w
  291. size_h = cells_h * cell_size_h
  292. menu_x = 200
  293. menu_y = 50
  294. battle_map1 = [[0 for _ in range(cells_w)] for _ in range(cells_h)]
  295. battle_map2 = [[0 for _ in range(cells_w)] for _ in range(cells_h)]
  296. # 0 - пустая ячейка
  297. # 1 - корабль (палуба)
  298. # 2 - промах
  299. # 3 - попадание
  300. turn = 1 # 0 - игрок №1, 1 - игрок №2
  301. end_game = False
  302.  
  303. canvas_elements = [] # отрисованные элементы.
  304.  
  305. _version = "0.1"
  306. run_app = True
  307. game = tk.Tk()
  308. game.protocol("WM_DELETE_WINDOW", on_close_window)
  309. game.resizable(0, 0) # Запрет изменения размеров окна
  310. game.wm_attributes("-topmost", 1) # окно приложение всегда на первом плане.
  311. game.title(f"Игра морской бой. Версия {_version}")
  312. canvas = tk.Canvas(game, width=2*size_w+menu_x, height=size_h+menu_y, bd=0, highlightthickness=0)
  313. canvas.pack()
  314.  
  315. button1 = tk.Button(game, text="Начать новую игру", command=command_new_game)
  316. button2 = tk.Button(game, text="Показать корабли (отладка)", command=command_debug_show_ships)
  317. button1.place(x=size_w+10, y=10, width=menu_x-20, height=30)
  318. button2.place(x=size_w+10, y=50, width=menu_x-20, height=30)
  319.  
  320. lb_player1 = tk.Label(game, text="Игрок №1", font=("Arial", 18))
  321. lb_player2 = tk.Label(game, text="Игрок №2", font=("Arial", 18))
  322. lb_player1.place(x=size_w//3, y=size_h+10, width=150, height=30)
  323. lb_player2.place(x=size_w+menu_x+size_w//3, y=size_h+10, width=150, height=30)
  324.  
  325. if turn: # в зависимости от хода меняем фон у игроков
  326.     lb_player2.config(bg="yellow")
  327.     lb_player1.config(bg="grey")
  328. else:
  329.     lb_player1.config(bg="yellow")
  330.     lb_player2.config(bg="grey")
  331.  
  332. canvas.bind_all("<Button-1>", func=on_click_canvas) # обработка нажатия левой кнопки мыши
  333. canvas.bind_all("<Button-3>", func=on_click_canvas) # обработка нажатия правой кнопки мыши
  334.  
  335. draw_game_map()
  336. generate_battle_map1()
  337. generate_battle_map2()
  338. while run_app:
  339.     if run_app:
  340.         game.update_idletasks()
  341.         game.update()
RAW Paste Data