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