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