Вариант 1: грубая сила
Решением грубой силы может быть поиск всех игроков и поиск ближайшего:
# I renamed x-cor to x, and y-cor to y since these were not valid python names
def nearest_player(grid, x, y):
best_distance = float('inf')
best_player = None
for pos, player in grid.items():
# I actually use squared distance since this is
# equivalent to the "real" distance
distance = (pos - x) ** 2 + (pos - y) ** 2
if distance < best_distance:
best_distance = distance
best_player = player
return best_player
Вариант 2
Более элегантный способ будет следующим:
def nearest_player(grid, x, y):
distances = [(pos - x) ** 2 + (pos - y) ** 2 for pos in grid]
return grid.values()[distances.index(min(distances))]
Что я здесь делаю?
Сначала вы вычисляете все расстояния:
distances = [(pos - x) ** 2 + (pos - y) ** 2 for pos in grid]
Это дает массив со всеми расстояниями.Затем я вычисляю индекс его минимума:
distances.index(min(distances))
, который для списка значений вашего grid
дает игроку:
grid.values()[distances.index(min(distances))]
и вуаля:)
Примечание: Еще один шаг вперед
Просто для того, чтобы использовать мозг (я не знаю, правильный ли это английский).Давайте представим, что ваши настоящие ключи - это не координаты, а что-то другое (str
, и вам нужно вычислить расстояние Левенштейна ).Вы можете сделать следующее:
def nearest(data, item, d):
distances = [d(item, i) for i in data]
return data.values()[distances.index(min(distances))]
, и вам действительно нужно предоставить функцию d
(для расстояния), которая вычисляет расстояние между двумя элементами.И это все.
В вашем текущем случае d
будет:
def euclidean_distance(x, y):
return sum((x[i] - y[i]) ** 2 for i in range(0, len(x)))
, если вы предоставите x
и y
как tuple
или list
.