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