Решение с тестами
(исправленое, за исключением ситуации с ударом об стену из капкана)