Я создаю игрового бота для линкора для сервера Discord. Я еще не выполнил часть разногласий, но я закончил вводную часть человека здесь .
Теперь я делаю бота, который поместит каждый корабль на воду, который представляет собой массив кусков. ,
Это код для бота.
import re
import numpy as np
import random
water_text = 'WW'
waters = np.full((10, 10), water_text, 'U2')
headers = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']
ship_type = [
["CV", "Carrier", 5],
["BB", "Battleship", 4],
["CA", "Cruiser", 3],
["SS", "Submarine", 3],
["DD", "Destroyer", 2],
]
board_x_coord = {
"a": 0,
"b": 1,
"c": 2,
"d": 3,
"e": 4,
"f": 5,
"g": 6,
"h": 7,
"i": 8,
"j": 9
}
possible_neighbor_count = 1
def printBoard():
for i, header in enumerate(headers):
if i == 0:
print(' ', end='')
print(header + ' ', end='')
if i == len(headers)-1:
print()
for x, line in enumerate(waters):
print('%2d' % (x), end='')
[print(' '+pos, end='') for pos in line]
print()
def collision_detect(selected_waters):
if any(water != water_text for water in selected_waters):
return True
return False
def neighbor_counter(a, b):
dist = 1
return sum([y != water_text for w in [row[max(0, a-dist):a+dist+1] for row in waters[max(0, b-1):b+dist+1]] for y in w])-1
def neighbor_test(x, y, size, orientation):
if orientation == 'H':
neighbor_count = 0
for i in range(size):
x += i
neighbor_count += neighbor_counter(x, y)
return neighbor_count
elif orientation == 'V':
neighbor_count = 0
for i in range(size):
y += i
neighbor_count += neighbor_counter(x, y)
return neighbor_count
def no_neighbors(possible, size, orientation):
neighbor_grades = []
for nx,ny in possible:
grade = neighbor_test(nx, ny, size, orientation)
neighbor_grades.append((grade, (nx,ny)))
return [y for x, y in neighbor_grades if x < possible_neighbor_count]
def get_available_waters():
availables = []
for y_pos, row in enumerate(waters):
for x_pos, water in enumerate(row):
if water == water_text:
availables.append((x_pos, y_pos))
return availables
def place_ship(ship):
size = ship[2]
orientation = random.choice(['H', 'V'])
if orientation == 'H':
possible = []
for x, y in get_available_waters():
selected_waters = waters[y, x:size+x]
if len(selected_waters) == size:
if not collision_detect(selected_waters):
possible.append((x, y))
result = random.choice(no_neighbors(possible, size, orientation))
px, py = result
waters[py, px:size+px] = ship[0]
elif orientation == 'V':
possible = []
for x, y in get_available_waters():
selected_waters = waters[y:size+y:, x]
if len(selected_waters) == size:
if not collision_detect(selected_waters):
possible.append((x, y))
result = random.choice(no_neighbors(possible, size, orientation))
px, py = result
waters[py:size+py:, px] = ship[0]
for ship in ship_type:
place_ship(ship)
printBoard()
#print(waters)
Пример вывода:
A B C D E F G H I J
0 WW WW WW WW WW WW WW WW WW WW
1 WW WW CA CA CA WW WW WW WW WW
2 WW WW WW WW WW WW WW WW WW WW
3 WW WW WW WW WW WW WW WW WW WW
4 WW WW WW CV WW WW WW SS WW WW
5 WW WW BB CV WW WW WW SS WW WW
6 WW WW BB CV WW WW WW SS WW WW
7 WW WW BB CV WW WW WW WW WW WW
8 WW WW BB CV WW DD DD WW WW WW
9 WW WW WW WW WW WW WW WW WW WW
Приведенный выше код будет:
- Получить корабль из списка.
- Выбрать ориентацию
- Получить неиспользуемые позиции.
- Проверьте, возможна ли каждая неиспользованная позиция для размещения корабля.
- Разместите корабль.
Расположение кажется хорошим, но иногда корабли подходят слишком близко друг к другу, и это приводит к легкой игре. Как я могу проверить, есть ли соседний корабль? Если есть, выберите другую позицию. Кроме того, есть ли лучший способ разместить каждый корабль?
Редактировать: Добавлена сырая проверка соседей.
Теперь я проверяю каждую возможную позицию для соседей