Advertisement
sphinx2001

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

Dec 1st, 2020
857
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 14.97 KB | None | 0 0
  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()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement