Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wiseplat
GitHub Repository: wiseplat/python-code
Path: blob/master/python-igra-morskoy-boy/main_lesson_14.py
5918 views
1
from tkinter import *
2
from tkinter import messagebox
3
import time
4
import random
5
6
tk = Tk()
7
app_running = True
8
9
size_canvas_x = 500
10
size_canvas_y = 500
11
s_x = s_y = 8 # размер игрового поля
12
s_y = 8
13
step_x = size_canvas_x // s_x # шаг по горизонтали
14
step_y = size_canvas_y // s_y # шаг по вертикали
15
size_canvas_x = step_x * s_x
16
size_canvas_y = step_y * s_y
17
delta_menu_x = 4
18
menu_x = step_x * delta_menu_x # 250
19
menu_y = 40
20
ships = s_x // 2 # определяем максимальное кол-во кораблей
21
ship_len1 = s_x // 5 # длина первого типа корабля
22
ship_len2 = s_x // 3 # длина второго типа корабля
23
ship_len3 = s_x // 2 # длина третьего типа корабля
24
enemy_ships1 = [[0 for i in range(s_x + 1)] for i in range(s_y + 1)]
25
enemy_ships2 = [[0 for i in range(s_x + 1)] for i in range(s_y + 1)]
26
list_ids = [] # список объектов canvas
27
28
# points1 - список куда мы кликнули мышкой
29
points1 = [[-1 for i in range(s_x)] for i in range(s_y)]
30
points2 = [[-1 for i in range(s_x)] for i in range(s_y)]
31
32
# boom - список попаданий по кораблям противника
33
boom = [[0 for i in range(s_x)] for i in range(s_y)]
34
35
# ships_list - список кораблей игрока 1 и игрока 2
36
ships_list = []
37
38
39
# print(enemy_ships1)
40
41
def on_closing():
42
global app_running
43
if messagebox.askokcancel("Выход из игры", "Хотите выйти из игры?"):
44
app_running = False
45
tk.destroy()
46
47
48
tk.protocol("WM_DELETE_WINDOW", on_closing)
49
tk.title("Игра Морской Бой")
50
tk.resizable(0, 0)
51
tk.wm_attributes("-topmost", 1)
52
canvas = Canvas(tk, width=size_canvas_x + menu_x + size_canvas_x, height=size_canvas_y + menu_y, bd=0,
53
highlightthickness=0)
54
canvas.create_rectangle(0, 0, size_canvas_x, size_canvas_y, fill="white")
55
canvas.create_rectangle(size_canvas_x + menu_x, 0, size_canvas_x + menu_x + size_canvas_x, size_canvas_y,
56
fill="lightyellow")
57
canvas.pack()
58
tk.update()
59
60
61
def draw_table(offset_x=0):
62
for i in range(0, s_x + 1):
63
canvas.create_line(offset_x + step_x * i, 0, offset_x + step_x * i, size_canvas_y)
64
for i in range(0, s_y + 1):
65
canvas.create_line(offset_x, step_y * i, offset_x + size_canvas_x, step_y * i)
66
67
68
draw_table()
69
draw_table(size_canvas_x + menu_x)
70
71
t0 = Label(tk, text="Игрок №1", font=("Helvetica", 16))
72
t0.place(x=size_canvas_x // 2 - t0.winfo_reqwidth() // 2, y=size_canvas_y + 3)
73
t1 = Label(tk, text="Игрок №2", font=("Helvetica", 16))
74
t1.place(x=size_canvas_x + menu_x + size_canvas_x // 2 - t1.winfo_reqwidth() // 2, y=size_canvas_y + 3)
75
76
t0.configure(bg="red")
77
t0.configure(bg="#f0f0f0")
78
79
80
def button_show_enemy1():
81
for i in range(0, s_x):
82
for j in range(0, s_y):
83
if enemy_ships1[j][i] > 0:
84
color = "red"
85
if points1[j][i] != -1:
86
color = "green"
87
_id = canvas.create_rectangle(i * step_x, j * step_y, i * step_x + step_x, j * step_y + step_y,
88
fill=color)
89
list_ids.append(_id)
90
91
92
def button_show_enemy2():
93
for i in range(0, s_x):
94
for j in range(0, s_y):
95
if enemy_ships2[j][i] > 0:
96
color = "red"
97
if points2[j][i] != -1:
98
color = "green"
99
_id = canvas.create_rectangle(size_canvas_x + menu_x + i * step_x, j * step_y,
100
size_canvas_x + menu_x + i * step_x + step_x, j * step_y + step_y,
101
fill=color)
102
list_ids.append(_id)
103
104
105
def button_begin_again():
106
global list_ids
107
global points1, points2
108
global boom
109
global enemy_ships1, enemy_ships2
110
for el in list_ids:
111
canvas.delete(el)
112
list_ids = []
113
generate_ships_list()
114
# print(ships_list)
115
enemy_ships1 = generate_enemy_ships()
116
enemy_ships2 = generate_enemy_ships()
117
points1 = [[-1 for i in range(s_x)] for i in range(s_y)]
118
points2 = [[-1 for i in range(s_x)] for i in range(s_y)]
119
boom = [[0 for i in range(s_x)] for i in range(s_y)]
120
121
122
b0 = Button(tk, text="Показать корабли Игрока №1", command=button_show_enemy1)
123
b0.place(x=size_canvas_x + 20, y=30)
124
125
b1 = Button(tk, text="Показать корабли Игрока №2", command=button_show_enemy2)
126
b1.place(x=size_canvas_x + 20, y=70)
127
128
b2 = Button(tk, text="Начать заново!", command=button_begin_again)
129
b2.place(x=size_canvas_x + 20, y=110)
130
131
132
def draw_point(x, y):
133
# print(enemy_ships1[y][x])
134
if enemy_ships1[y][x] == 0:
135
color = "red"
136
id1 = canvas.create_oval(x * step_x, y * step_y, x * step_x + step_x, y * step_y + step_y, fill=color)
137
id2 = canvas.create_oval(x * step_x + step_x // 3, y * step_y + step_y // 3, x * step_x + step_x - step_x // 3,
138
y * step_y + step_y - step_y // 3, fill="white")
139
list_ids.append(id1)
140
list_ids.append(id2)
141
if enemy_ships1[y][x] > 0:
142
color = "blue"
143
id1 = canvas.create_rectangle(x * step_x, y * step_y + step_y // 2 - step_y // 10, x * step_x + step_x,
144
y * step_y + step_y // 2 + step_y // 10, fill=color)
145
id2 = canvas.create_rectangle(x * step_x + step_x // 2 - step_x // 10, y * step_y,
146
x * step_x + step_x // 2 + step_x // 10, y * step_y + step_y, fill=color)
147
list_ids.append(id1)
148
list_ids.append(id2)
149
150
151
def draw_point2(x, y, offset_x=size_canvas_x + menu_x):
152
# print(enemy_ships1[y][x])
153
if enemy_ships2[y][x] == 0:
154
color = "red"
155
id1 = canvas.create_oval(offset_x + x * step_x, y * step_y, offset_x + x * step_x + step_x, y * step_y + step_y,
156
fill=color)
157
id2 = canvas.create_oval(offset_x + x * step_x + step_x // 3, y * step_y + step_y // 3,
158
offset_x + x * step_x + step_x - step_x // 3,
159
y * step_y + step_y - step_y // 3, fill="white")
160
list_ids.append(id1)
161
list_ids.append(id2)
162
if enemy_ships2[y][x] > 0:
163
color = "blue"
164
id1 = canvas.create_rectangle(offset_x + x * step_x, y * step_y + step_y // 2 - step_y // 10,
165
offset_x + x * step_x + step_x,
166
y * step_y + step_y // 2 + step_y // 10, fill=color)
167
id2 = canvas.create_rectangle(offset_x + x * step_x + step_x // 2 - step_x // 10, y * step_y,
168
offset_x + x * step_x + step_x // 2 + step_x // 10, y * step_y + step_y,
169
fill=color)
170
list_ids.append(id1)
171
list_ids.append(id2)
172
173
174
def check_winner(x, y):
175
win = False
176
if enemy_ships1[y][x] > 0:
177
boom[y][x] = enemy_ships1[y][x]
178
sum_enemy_ships1 = sum(sum(i) for i in zip(*enemy_ships1))
179
sum_boom = sum(sum(i) for i in zip(*boom))
180
# print(sum_enemy_ships1, sum_boom)
181
if sum_enemy_ships1 == sum_boom:
182
win = True
183
return win
184
185
186
def check_winner2():
187
win = True
188
for i in range(0, s_x):
189
for j in range(0, s_y):
190
if enemy_ships1[j][i] > 0:
191
if points1[j][i] == -1:
192
win = False
193
# print(win)
194
return win
195
196
197
def check_winner2_igrok_2():
198
win = True
199
for i in range(0, s_x):
200
for j in range(0, s_y):
201
if enemy_ships2[j][i] > 0:
202
if points2[j][i] == -1:
203
win = False
204
# print(win)
205
return win
206
207
208
def add_to_all(event):
209
global points1, points2
210
_type = 0 # ЛКМ
211
if event.num == 3:
212
_type = 1 # ПКМ
213
# print(_type)
214
mouse_x = canvas.winfo_pointerx() - canvas.winfo_rootx()
215
mouse_y = canvas.winfo_pointery() - canvas.winfo_rooty()
216
# print(mouse_x, mouse_y)
217
ip_x = mouse_x // step_x
218
ip_y = mouse_y // step_y
219
# print(ip_x, ip_y, "_type:", _type)
220
221
# первое игровое поле
222
if ip_x < s_x and ip_y < s_y:
223
if points1[ip_y][ip_x] == -1:
224
points1[ip_y][ip_x] = _type
225
draw_point(ip_x, ip_y)
226
# if check_winner(ip_x, ip_y):
227
if check_winner2():
228
winner = "Победа Игрока №2"
229
winner_add = "(Все корабли противника Игрока №1 подбиты)!!!!!"
230
print(winner, winner_add)
231
points1 = [[10 for i in range(s_x)] for i in range(s_y)]
232
points2 = [[10 for i in range(s_x)] for i in range(s_y)]
233
id1 = 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")
234
list_ids.append(id1)
235
id2 = canvas.create_rectangle(step_x * 3+step_x//2, step_y * 3+step_y//2,
236
size_canvas_x + menu_x + size_canvas_x - step_x * 3 - step_x//2,
237
size_canvas_y - step_y - step_y//2, fill="yellow")
238
list_ids.append(id2)
239
id3 = canvas.create_text(step_x*10, step_y*5, text=winner, font=("Arial", 50), justify=CENTER)
240
id4 = canvas.create_text(step_x * 10, step_y * 6, text=winner_add, font=("Arial", 25), justify=CENTER)
241
list_ids.append(id3)
242
list_ids.append(id4)
243
244
# print(len(list_ids))
245
246
# второе игровое поле
247
if ip_x >= s_x + delta_menu_x and ip_x <= s_x + s_x + delta_menu_x and ip_y < s_y:
248
# print("ok")
249
if points2[ip_y][ip_x - s_x - delta_menu_x] == -1:
250
points2[ip_y][ip_x - s_x - delta_menu_x] = _type
251
draw_point2(ip_x - s_x - delta_menu_x, ip_y)
252
# if check_winner(ip_x, ip_y):
253
if check_winner2_igrok_2():
254
winner = "Победа Игрока №1"
255
winner_add = "(Все корабли противника Игрока №2 подбиты)!!!!!"
256
print(winner, winner_add)
257
points1 = [[10 for i in range(s_x)] for i in range(s_y)]
258
points2 = [[10 for i in range(s_x)] for i in range(s_y)]
259
id1 = canvas.create_rectangle(step_x * 3, step_y * 3,
260
size_canvas_x + menu_x + size_canvas_x - step_x * 3,
261
size_canvas_y - step_y, fill="blue")
262
list_ids.append(id1)
263
id2 = canvas.create_rectangle(step_x * 3 + step_x // 2, step_y * 3 + step_y // 2,
264
size_canvas_x + menu_x + size_canvas_x - step_x * 3 - step_x // 2,
265
size_canvas_y - step_y - step_y // 2, fill="yellow")
266
list_ids.append(id2)
267
id3 = canvas.create_text(step_x * 10, step_y * 5, text=winner, font=("Arial", 50), justify=CENTER)
268
id4 = canvas.create_text(step_x * 10, step_y * 6, text=winner_add, font=("Arial", 25), justify=CENTER)
269
list_ids.append(id3)
270
list_ids.append(id4)
271
272
canvas.bind_all("<Button-1>", add_to_all) # ЛКМ
273
canvas.bind_all("<Button-3>", add_to_all) # ПКМ
274
275
276
def generate_ships_list():
277
global ships_list
278
ships_list = []
279
# генерируем список случайных длин кораблей
280
for i in range(0, ships):
281
ships_list.append(random.choice([ship_len1, ship_len2, ship_len3]))
282
# print(ships_list)
283
284
285
def generate_enemy_ships():
286
global ships_list
287
enemy_ships = []
288
289
# подсчет суммарной длины кораблей
290
sum_1_all_ships = sum(ships_list)
291
sum_1_enemy = 0
292
293
# print("sum: ", sum_1_all_ships)
294
295
while sum_1_enemy != sum_1_all_ships:
296
# обнуляем массив кораблей врага
297
enemy_ships = [[0 for i in range(s_x + 1)] for i in
298
range(s_y + 1)] # +1 для доп. линии справа и снизу, для успешных проверок генерации противника
299
300
for i in range(0, ships):
301
len = ships_list[i]
302
horizont_vertikal = random.randrange(1, 3) # 1- горизонтальное 2 - вертикальное
303
304
primerno_x = random.randrange(0, s_x)
305
if primerno_x + len > s_x:
306
primerno_x = primerno_x - len
307
308
primerno_y = random.randrange(0, s_y)
309
if primerno_y + len > s_y:
310
primerno_y = primerno_y - len
311
312
# print(horizont_vertikal, primerno_x,primerno_y)
313
if horizont_vertikal == 1:
314
if primerno_x + len <= s_x:
315
for j in range(0, len):
316
try:
317
check_near_ships = 0
318
check_near_ships = enemy_ships[primerno_y][primerno_x - 1] + \
319
enemy_ships[primerno_y][primerno_x + j] + \
320
enemy_ships[primerno_y][primerno_x + j + 1] + \
321
enemy_ships[primerno_y + 1][primerno_x + j + 1] + \
322
enemy_ships[primerno_y - 1][primerno_x + j + 1] + \
323
enemy_ships[primerno_y + 1][primerno_x + j] + \
324
enemy_ships[primerno_y - 1][primerno_x + j]
325
# print(check_near_ships)
326
if check_near_ships == 0: # записываем в том случае, если нет ничего рядом
327
enemy_ships[primerno_y][primerno_x + j] = i + 1 # записываем номер корабля
328
except Exception:
329
pass
330
if horizont_vertikal == 2:
331
if primerno_y + len <= s_y:
332
for j in range(0, len):
333
try:
334
check_near_ships = 0
335
check_near_ships = enemy_ships[primerno_y - 1][primerno_x] + \
336
enemy_ships[primerno_y + j][primerno_x] + \
337
enemy_ships[primerno_y + j + 1][primerno_x] + \
338
enemy_ships[primerno_y + j + 1][primerno_x + 1] + \
339
enemy_ships[primerno_y + j + 1][primerno_x - 1] + \
340
enemy_ships[primerno_y + j][primerno_x + 1] + \
341
enemy_ships[primerno_y + j][primerno_x - 1]
342
# print(check_near_ships)
343
if check_near_ships == 0: # записываем в том случае, если нет ничего рядом
344
enemy_ships[primerno_y + j][primerno_x] = i + 1 # записываем номер корабля
345
except Exception:
346
pass
347
348
# делаем подсчет 1ц
349
sum_1_enemy = 0
350
for i in range(0, s_x):
351
for j in range(0, s_y):
352
if enemy_ships[j][i] > 0:
353
sum_1_enemy = sum_1_enemy + 1
354
355
# print(sum_1_enemy)
356
# print(ships_list)
357
# print(enemy_ships)
358
return enemy_ships
359
360
361
generate_ships_list()
362
# print(ships_list)
363
enemy_ships1 = generate_enemy_ships()
364
enemy_ships2 = generate_enemy_ships()
365
# print("****************************")
366
# print(enemy_ships1)
367
# print("****************************")
368
# print(enemy_ships2)
369
# print("****************************")
370
371
while app_running:
372
if app_running:
373
tk.update_idletasks()
374
tk.update()
375
time.sleep(0.005)
376
377