Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import tkinter as tk
- from tkinter import messagebox
- import time
- import random
- '''
- battle_map[y][x] == 0 пустое поле
- battle_map[y][x] == 1 палуба корабля
- battle_map[y][x] == 2 выстрел мимо
- battle_map[y][x] == 3 попадание
- '''
- def check_end():
- global battle_map1, battle_map2
- player1 = 0
- for line in battle_map1:
- player1 += line.count(1)
- player2 = 0
- for line in battle_map2:
- player2 += line.count(1)
- print(player1)
- print(player2)
- if player1 == 0: # выиграл игрок 1
- messagebox.showinfo("Морской бой", "Выиграл игрок №2")
- return True
- if player2 == 0: # выиграл игрок 2
- messagebox.showinfo("Морской бой", "Выиграл игрок №1")
- return True
- return False
- def generate_battle_map1():
- global battle_map1
- ships = cells_w // 2 # общее количество кораблей
- ships_config = [] # сколько и какого типа кораблей мы будем создавать
- for i in range(ships):
- ships_config.append(random.choice([1, 2, 3]))
- sum_all_ships = sum(ships_config) # количество заполненное кораблями
- sum_enemy = 0
- while sum_enemy != sum_all_ships:
- battle_map1 = [[0 for x in range(cells_w)] for y in range(cells_h)]
- for i in range(ships):
- ls = ships_config[i] # длина коробля
- horizontal_vertical = random.randint(0, 2) # 0 горизонтали, 1 по вертикали
- pos_x = random.randint(0, cells_w) # стартовая позиция корабля по оси x
- pos_y = random.randint(0, cells_h) # стартовая позиция корабля по оси y
- if horizontal_vertical == 0: # по горизонтали
- if pos_x + ls < cells_w:
- for j in range(ls):
- try:
- check_near_ships = 0
- check_near_ships = battle_map1[pos_y][pos_x - 1] + \
- battle_map1[pos_y][pos_x + j] + \
- battle_map1[pos_y][pos_x + j + 1] + \
- battle_map1[pos_y + 1][pos_x + j + 1] + \
- battle_map1[pos_y - 1][pos_x + j + 1] + \
- battle_map1[pos_y + 1][pos_x + j] + \
- battle_map1[pos_y - 1][pos_x + j]
- if check_near_ships == 0:
- battle_map1[pos_y][pos_x] = 1
- except Exception:
- pass
- else: # по вертикали
- if pos_y + ls < cells_h:
- for j in range(ls):
- try:
- check_near_ships = 0
- check_near_ships = battle_map1[pos_y - 1][pos_x] + \
- battle_map1[pos_y + j][pos_x] + \
- battle_map1[pos_y + j + 1][pos_x] + \
- battle_map1[pos_y + j + 1][pos_x + 1] + \
- battle_map1[pos_y + j + 1][pos_x - 1] + \
- battle_map1[pos_y + j][pos_x + 1] + \
- battle_map1[pos_y + j][pos_x - 1]
- if check_near_ships == 0:
- battle_map1[pos_y + j][pos_x] = 1
- except Exception:
- pass
- sum_enemy = 0
- for row in battle_map1:
- sum_enemy += sum(row)
- def generate_battle_map2():
- global battle_map2
- ships = cells_w // 2 # общее количество кораблей
- ships_config = [] # сколько и какого типа кораблей мы будем создавать
- for i in range(ships):
- ships_config.append(random.choice([1, 2, 3]))
- sum_all_ships = sum(ships_config) # количество заполненное кораблями
- sum_enemy = 0
- while sum_enemy != sum_all_ships:
- battle_map2 = [[0 for x in range(cells_w)] for y in range(cells_h)]
- for i in range(ships):
- ls = ships_config[i] # длина коробля
- horizontal_vertical = random.randint(0, 2) # 0 горизонтали, 1 по вертикали
- pos_x = random.randint(0, cells_w) # стартовая позиция корабля по оси x
- pos_y = random.randint(0, cells_h) # стартовая позиция корабля по оси y
- if horizontal_vertical == 0: # по горизонтали
- if pos_x + ls < cells_w:
- for j in range(ls):
- try:
- check_near_ships = 0
- check_near_ships = battle_map2[pos_y][pos_x - 1] + \
- battle_map2[pos_y][pos_x + j] + \
- battle_map2[pos_y][pos_x + j + 1] + \
- battle_map2[pos_y + 1][pos_x + j + 1] + \
- battle_map2[pos_y - 1][pos_x + j + 1] + \
- battle_map2[pos_y + 1][pos_x + j] + \
- battle_map2[pos_y - 1][pos_x + j]
- if check_near_ships == 0:
- battle_map2[pos_y][pos_x] = 1
- except Exception:
- pass
- else: # по вертикали
- if pos_y + ls < cells_h:
- for j in range(ls):
- try:
- check_near_ships = 0
- check_near_ships = battle_map2[pos_y - 1][pos_x] + \
- battle_map2[pos_y + j][pos_x] + \
- battle_map2[pos_y + j + 1][pos_x] + \
- battle_map2[pos_y + j + 1][pos_x + 1] + \
- battle_map2[pos_y + j + 1][pos_x - 1] + \
- battle_map2[pos_y + j][pos_x + 1] + \
- battle_map2[pos_y + j][pos_x - 1]
- if check_near_ships == 0:
- battle_map2[pos_y + j][pos_x] = 1
- except Exception:
- pass
- sum_enemy = 0
- for row in battle_map2:
- sum_enemy += sum(row)
- def hit(x, y):
- global turn, end_game
- if turn: # battle_map2 - 2 игрок
- cel = battle_map2[y][x]
- if cel == 0:
- battle_map2[y][x] = 2
- turn = 0
- #cid = canvas.create_rectangle(i * cell_size_w, j * cell_size_h, (i + 1) * cell_size_w, (j + 1) * cell_size_h, fill="red")
- 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')
- canvas_elements.append(cid)
- cid = canvas.create_oval(size_w + menu_x + cell_size_w * x + cell_size_w // 4, y * cell_size_h + cell_size_h // 4,
- size_w + menu_x + cell_size_w * (x + 1) - cell_size_w // 4, (y + 1) * cell_size_h - cell_size_h // 4, fill='white')
- canvas_elements.append(cid)
- elif cel == 1:
- battle_map2[y][x] = 3
- cid = canvas.create_rectangle(size_w + menu_x + cell_size_w * x + cell_size_w // 3, y * cell_size_h,
- size_w + menu_x + cell_size_w * (x + 1) - cell_size_w // 3, (y + 1) * cell_size_h, fill='blue')
- canvas_elements.append(cid)
- cid = canvas.create_rectangle(size_w + menu_x + cell_size_w * x,
- y * cell_size_h + cell_size_h // 3,
- size_w + menu_x + cell_size_w * (x + 1),
- (y + 1) * cell_size_h - cell_size_h // 3, fill='blue')
- canvas_elements.append(cid)
- turn = 0
- else:
- cel = battle_map1[y][x]
- if cel == 0:
- battle_map1[y][x] = 2
- turn = 1
- cid = canvas.create_oval(cell_size_w * x, y * cell_size_h,
- cell_size_w * (x + 1), (y + 1) * cell_size_h, fill='red')
- canvas_elements.append(cid)
- cid = canvas.create_oval(cell_size_w * x + cell_size_w // 4,
- y * cell_size_h + cell_size_h // 4,
- cell_size_w * (x + 1) - cell_size_w // 4,
- (y + 1) * cell_size_h - cell_size_h // 4, fill='white')
- canvas_elements.append(cid)
- elif cel == 1:
- battle_map1[y][x] = 3
- cid = canvas.create_rectangle(cell_size_w * x + cell_size_w // 3, y * cell_size_h,
- cell_size_w * (x + 1) - cell_size_w // 3,
- (y + 1) * cell_size_h, fill='blue')
- canvas_elements.append(cid)
- cid = canvas.create_rectangle(cell_size_w * x,
- y * cell_size_h + cell_size_h // 3,
- cell_size_w * (x + 1),
- (y + 1) * cell_size_h - cell_size_h // 3, fill='blue')
- canvas_elements.append(cid)
- turn = 1
- # проверка окончания игры
- end_game = check_end()
- def on_click_canvas(event):
- global turn
- _button = 0
- if event.num == 3:
- _button = 1
- mouse_x = canvas.winfo_pointerx() - canvas.winfo_rootx()
- mouse_y = canvas.winfo_pointery() - canvas.winfo_rooty()
- if end_game:
- return
- if turn:
- offset = size_w + menu_x
- if offset <= mouse_x <= size_w + offset and 0 <= mouse_y <= size_h:
- map_x = (mouse_x - offset) // cell_size_w
- map_y = mouse_y // cell_size_h
- hit(map_x, map_y)
- print(f"Click button {_button} x:{mouse_x}, y:{mouse_y} cell({map_x},{map_y})")
- else:
- if 0 <= mouse_x <= size_w and 0 <= mouse_y <= size_h:
- map_x = mouse_x // cell_size_w
- map_y = mouse_y // cell_size_h
- hit(map_x, map_y)
- print(f"Click button {_button} x:{mouse_x}, y:{mouse_y} cell({map_x},{map_y})")
- if turn: # в зависимости от хода меняем фон у игроков
- lb_player2.config(bg="yellow")
- lb_player1.config(bg="grey")
- else:
- lb_player1.config(bg="yellow")
- lb_player2.config(bg="grey")
- def command_new_game():
- global end_game
- end_game = False
- for el in canvas_elements:
- canvas.delete(el) # очистка холста
- draw_game_map() # перерисуем разметку
- generate_battle_map1()
- generate_battle_map2()
- def command_debug_show_ships():
- # battle_map[0][1] = 1
- # battle_map[cells_h - 1][cells_w - 1] = 1
- for i in range(cells_w):
- for j in range(cells_h):
- if battle_map1[j][i] != 0:
- cid = canvas.create_rectangle(i * cell_size_w, j * cell_size_h, (i + 1) * cell_size_w, (j + 1) * cell_size_h, fill="red")
- canvas_elements.append(cid)
- def on_close_window():
- global run_app
- if messagebox.askokcancel("Морской бой", "Завершить работу программы?"):
- run_app = False
- game.destroy()
- def draw_game_map():
- cid = canvas.create_rectangle(0, 0, size_w, size_h, fill="white")
- canvas_elements.append(cid)
- cid = canvas.create_rectangle(size_w + menu_x, 0, size_w*2+menu_x, size_h, fill="white")
- canvas_elements.append(cid)
- for i in range(cells_w + 1):
- cid = canvas.create_line(cell_size_w * i, 0, cell_size_w * i, size_h)
- canvas_elements.append(cid)
- for i in range(cells_h + 1):
- cid = canvas.create_line(0, cell_size_h * i, size_w, cell_size_h * i)
- canvas_elements.append(cid)
- o = size_w + menu_x # смещение по оси x для второго игорового поля
- for i in range(cells_w + 1):
- cid = canvas.create_line(o + cell_size_w * i, 0, o+cell_size_w * i, size_h)
- canvas_elements.append(cid)
- for i in range(cells_h + 1):
- cid = canvas.create_line(o, cell_size_h * i, o + size_w, cell_size_h * i)
- canvas_elements.append(cid)
- size_w = 400
- size_h = 400
- cells_w = 5
- cells_h = 5
- cell_size_w = size_w // cells_w
- cell_size_h = size_h // cells_h
- size_w = cells_w * cell_size_w
- size_h = cells_h * cell_size_h
- menu_x = 200
- menu_y = 50
- battle_map1 = [[0 for _ in range(cells_w)] for _ in range(cells_h)]
- battle_map2 = [[0 for _ in range(cells_w)] for _ in range(cells_h)]
- # 0 - пустая ячейка
- # 1 - корабль (палуба)
- # 2 - промах
- # 3 - попадание
- turn = 1 # 0 - игрок №1, 1 - игрок №2
- end_game = False
- canvas_elements = [] # отрисованные элементы.
- _version = "0.1"
- run_app = True
- game = tk.Tk()
- game.protocol("WM_DELETE_WINDOW", on_close_window)
- game.resizable(0, 0) # Запрет изменения размеров окна
- game.wm_attributes("-topmost", 1) # окно приложение всегда на первом плане.
- game.title(f"Игра морской бой. Версия {_version}")
- canvas = tk.Canvas(game, width=2*size_w+menu_x, height=size_h+menu_y, bd=0, highlightthickness=0)
- canvas.pack()
- button1 = tk.Button(game, text="Начать новую игру", command=command_new_game)
- button2 = tk.Button(game, text="Показать корабли (отладка)", command=command_debug_show_ships)
- button1.place(x=size_w+10, y=10, width=menu_x-20, height=30)
- button2.place(x=size_w+10, y=50, width=menu_x-20, height=30)
- lb_player1 = tk.Label(game, text="Игрок №1", font=("Arial", 18))
- lb_player2 = tk.Label(game, text="Игрок №2", font=("Arial", 18))
- lb_player1.place(x=size_w//3, y=size_h+10, width=150, height=30)
- lb_player2.place(x=size_w+menu_x+size_w//3, y=size_h+10, width=150, height=30)
- if turn: # в зависимости от хода меняем фон у игроков
- lb_player2.config(bg="yellow")
- lb_player1.config(bg="grey")
- else:
- lb_player1.config(bg="yellow")
- lb_player2.config(bg="grey")
- canvas.bind_all("<Button-1>", func=on_click_canvas) # обработка нажатия левой кнопки мыши
- canvas.bind_all("<Button-3>", func=on_click_canvas) # обработка нажатия правой кнопки мыши
- draw_game_map()
- generate_battle_map1()
- generate_battle_map2()
- while run_app:
- if run_app:
- game.update_idletasks()
- game.update()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement