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