{"id":463012,"date":"2025-06-12T03:07:33","date_gmt":"2025-06-12T03:07:33","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=463012"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=463012","title":{"rendered":"<span>\u0428\u0435\u0441\u0442\u0438\u0434\u0435\u0441\u044f\u0442\u0438\u043b\u0435\u0442\u043d\u0438\u0439 \u0437\u0430\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u044b\u0439 \u0438 \u043b\u0430\u0431\u043e\u0440\u0430\u0442\u043e\u0440\u043d\u0430\u044f \u043a\u0440\u044b\u0441\u0430. F# \u043d\u0430 Godot. \u0427\u0430\u0441\u0442\u044c 6. \u041a\u0430\u043a \u0434\u043e\u0431\u044b\u0442\u044c \u043d\u0435\u0447\u0442\u043e<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/u9\/jn\/hk\/u9jnhkr7zrzjpvmxir077jkidve.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/u9\/jn\/hk\/u9jnhkr7zrzjpvmxir077jkidve.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/u9\/jn\/hk\/u9jnhkr7zrzjpvmxir077jkidve.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u043b\u0430\u0441\u044c \u0441 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0430 <a href=\"https:\/\/habr.com\/ru\/articles\/554960\/\" rel=\"noopener noreferrer nofollow\">\u0442\u0430\u0439\u043b\u043e\u0432\u044b\u0445 \u043c\u0438\u0440\u043e\u0432<\/a> \u043d\u0430 F#. \u041e\u0434\u043d\u0430\u043a\u043e \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0435\u0433\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u044f \u043e\u0441\u043d\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0441\u0442\u0451\u043a\u0441\u044f \u043f\u043e \u0434\u0440\u0435\u0432\u0443, \u0437\u0430 \u0441\u0447\u0451\u0442 \u0447\u0435\u0433\u043e \u0443 \u043d\u0430\u0441 \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u044d\u0442\u0430\u043f \u0438\u0437 \u043f\u044f\u0442\u0438 \u0433\u043b\u0430\u0432 \u043f\u0440\u043e \u044f\u0437\u044b\u043a\u043e\u0432\u044b\u0435 \u0444\u0438\u0447\u0438 \u0438 \u043f\u0440\u043e\u0447\u0443\u044e \u00ab\u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442\u0430\u043b\u043e\u0447\u043a\u0443\u00bb. \u0414\u0443\u043c\u0430\u044e, \u0447\u0442\u043e \u0441 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u043e\u0439 <a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/909536\/\" rel=\"noopener noreferrer nofollow\">\u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043e<\/a>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b \u043e\u0431\u0440\u0430\u0442\u0438\u043c\u0441\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043a \u0442\u0430\u0439\u043b\u043e\u0432\u044b\u043c \u043c\u0438\u0440\u0430\u043c.<\/p>\n<p>\u041d\u043e \u043d\u0430\u0447\u043d\u0451\u043c \u043c\u044b \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441 \u043a\u043e\u043d\u0446\u0430 \u2014 \u0441 \u0430\u0434\u0430\u043f\u0442\u0430\u0446\u0438\u0438 \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438. \u042d\u0442\u043e \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u043a\u0430, \u043d\u043e \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0435\u0451 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043c\u044b \u0443\u0441\u043f\u0435\u0435\u043c \u0437\u0430\u043a\u0440\u0435\u043f\u0438\u0442\u044c \u043f\u0440\u043e\u0439\u0434\u0435\u043d\u043d\u044b\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u0438 \u043f\u043e \u0438\u043d\u0435\u0440\u0446\u0438\u0438 \u0437\u0430\u0441\u043a\u043e\u0447\u0438\u0442\u044c \u0432 \u043d\u043e\u0432\u044b\u0439.<\/p>\n<p>\u042d\u0442\u0430 \u0433\u043b\u0430\u0432\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u00ab\u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043d\u044b\u043c \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u043c\u00bb. \u0415\u0451 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043e\u0431\u0440\u0443\u0431\u0438\u0442\u044c \u0438\u0437-\u0437\u0430 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u0438\u044f \u0443\u0434\u043e\u0431\u043e\u0432\u0430\u0440\u0438\u043c\u044b\u0445 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432. \u041e\u0447\u0435\u0440\u0447\u0438\u0432\u0430\u0442\u044c \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u0442\u0435\u043c\u044b \u0432 \u0442\u0430\u043a\u0438\u0445 \u0442\u0435\u043a\u0441\u0442\u0430\u0445 \u0441\u043b\u043e\u0436\u043d\u043e, \u043d\u043e \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0434\u043e\u043b\u0435\u0439 \u0443\u0441\u043b\u043e\u0432\u043d\u043e\u0441\u0442\u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u043f\u043e \u0438\u0442\u043e\u0433\u0443 \u0432 \u044d\u0442\u043e\u0439 \u0433\u043b\u0430\u0432\u0435 \u043c\u044b \u043d\u0430\u0443\u0447\u0438\u043c\u0441\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043b\u044e\u0431\u0443\u044e \u0445\u0442\u043e\u043d\u044c. \u0417\u0430\u0447\u0435\u043c \u043e\u043d\u0430 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u043b\u0430\u0441\u044c, \u043d\u0430\u0447\u043d\u0451\u043c \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u0442\u044c \u0432 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437, \u0430 \u0447\u0442\u043e \u0441 \u043d\u0435\u0439 \u0434\u0435\u043b\u0430\u0442\u044c \u0434\u0430\u043b\u044c\u0448\u0435, \u0432\u044b\u044f\u0441\u043d\u0438\u043c \u043f\u043e\u0437\u0434\u043d\u0435\u0435.<\/p>\n<h3>\u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0435\u0440\u0435\u043d\u043e\u0441 \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438<\/h3>\n<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 <a href=\"https:\/\/habr.com\/ru\/articles\/554960\/\" rel=\"noopener noreferrer nofollow\">\u041f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u044b\u0435 \u0442\u0430\u0439\u043b\u043e\u0432\u044b\u0435 \u043c\u0438\u0440\u044b<\/a> \u0434\u0430\u043d \u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438 \u0447\u0435\u0440\u0435\u0437 <code>A*<\/code> (\u043f\u043e-\u0440\u0443\u0441\u0441\u043a\u0438 \u00ab\u0430\u0441\u0442\u0430\u0440\u00bb). \u042d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c, \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043c\u0435\u043d\u044f \u0443\u0447\u0438\u043b\u0438 \u0435\u0449\u0451 \u0432 \u0448\u043a\u043e\u043b\u0435, \u043d\u043e \u0435\u0433\u043e \u043b\u0435\u0433\u043a\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u0443\u0441\u043b\u043e\u0436\u043d\u0438\u0442\u044c \u043f\u043e\u0434 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438. \u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0434\u0430\u0451\u0442\u0441\u044f \u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0435\u0433\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u043b \u0441 GDScript \u043d\u0430 F#, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u043b \u043f\u043e\u0434 \u0441\u0432\u043e\u0438 \u0438\u0433\u0440\u043e\u0432\u044b\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0438.<\/p>\n<p>\u041c\u044b \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u0435\u043c \u043f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0442\u043e\u0442 \u0436\u0435 \u043f\u0443\u0442\u044c, \u043d\u043e \u0432\u043c\u0435\u0441\u0442\u043e \u043c\u0435\u0445\u0430\u043d\u0438\u043a \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0438\u043c\u0441\u044f \u043d\u0430 \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u0412 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0435 3 \u0431\u043b\u043e\u043a\u0430: \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u043b\u043a\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 <code>PriorityStack<\/code> \u0438, \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0441\u0430\u043c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043f\u043e\u0438\u0441\u043a\u0430. \u041f\u0440\u0438\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b \u0435\u0441\u0442\u044c \u0432\u043e \u0432\u0441\u0435\u0445 \u0431\u043b\u043e\u043a\u0430\u0445, \u043d\u043e \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044f \u0441\u044e\u0436\u0435\u0442\u0430 \u0432\u0430\u0436\u043d\u0435\u0435 \u0432\u0441\u0435\u0445 \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u0438\u0441\u043a. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u0443\u0442 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0434\u0438\u0442\u044c, \u0447\u0442\u043e \u043c\u044b \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0441\u043c\u044b\u0441\u043b\u0435 \u0431\u0443\u0434\u0435\u043c \u0438\u0437\u043e\u0431\u0440\u0435\u0442\u0430\u0442\u044c \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434, \u0438\u0431\u043e \u0432 Godot \u0435\u0441\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0435 <code>AStar2D<\/code>, <code>AStarGrid2D<\/code> \u0438 \u0447\u0442\u043e-\u0442\u043e \u0435\u0449\u0451 \u0434\u043b\u044f 3D. \u042f \u0438\u043c\u0438 \u0442\u0430\u043a \u0438 \u043d\u0435 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f, \u043d\u043e \u043e\u043d\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0441 \u043e\u0431\u044b\u0447\u043d\u044b\u043c\u0438 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f\u043c\u0438. \u0427\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 (\u043a\u0430\u043a \u0443 \u043c\u0435\u043d\u044f), \u0442\u043e \u044f \u0441\u0447\u0451\u043b \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c<s>\u0441\u044f<\/s> \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u043f\u043e\u0434 \u043d\u0438\u0445.<\/p>\n<h4>\u0412\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/h4>\n<p>\u0411\u043e\u043b\u044c\u0448\u0435 \u0432\u0441\u0435\u0433\u043e \u043d\u0430 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445 \u0441\u043a\u0430\u0437\u0430\u043b\u0430\u0441\u044c \u0437\u0430\u043c\u0435\u043d\u0430 \u0441\u0430\u043c\u043e\u043b\u0435\u043f\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u0447\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u0442\u0438\u043f\u044b. \u041f\u0435\u0440\u0435\u043d\u043e\u0441 \u043d\u0430 F# \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b, \u043d\u043e \u044f \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u0438\u043c \u043a\u0430\u043a \u043f\u043e\u0432\u043e\u0434\u043e\u043c. \u0423 \u043c\u0435\u043d\u044f \u0438\u0441\u0447\u0435\u0437\u0430\u044e\u0449\u0435 \u0440\u0435\u0434\u043a\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0432\u0435\u0440\u0448\u0430\u0442\u044c \u00ab\u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438\u00bb. \u0415\u0441\u043b\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0447\u0443\u0436\u0438\u0435 \u0431\u0430\u0433\u0438, \u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0443 \u043c\u0435\u043d\u044f \u043e\u0442\u043d\u0438\u043c\u0430\u0435\u0442 \u043a\u0430\u043a\u0430\u044f-\u043d\u0438\u0431\u0443\u0434\u044c \u0444\u0438\u0433\u043d\u044f, \u0442\u0438\u043f\u0430 \u0438\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e <code>bool<\/code>, \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u043e\u0433\u043e <code>&gt;<\/code> \u0432\u043c\u0435\u0441\u0442\u043e <code>&gt;=<\/code> \u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0447\u0451\u0442\u0430 \u043d\u0430 1. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043f\u043e\u0431\u0430\u0438\u0432\u0430\u044e\u0441\u044c \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434 \u0442\u0430\u043a:<\/p>\n<pre><code>func in_map(grid_pos:Vector2, map_size:Vector2) -&gt; bool: return grid_pos.x &lt; map_size.x and grid_pos.x &gt;= 0 and grid_pos.y &gt;= 0 and grid_pos.y &lt; map_size.y <\/code><\/pre>\n<p>\u0410 \u043d\u0435 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"fsharp\">let inMap mapSize pos =     Rect2I(Vector2I.Zero, mapSize).HasPoint pos <\/code><\/pre>\n<p>\u0421\u0443\u0434\u044f \u043f\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0443 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u043e\u0432, \u0432 Godot-\u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0435 \u043d\u0438\u043a\u0442\u043e \u0442\u0430\u043a\u0438\u0445 \u0441\u0442\u0440\u0430\u0445\u043e\u0432 \u043d\u0435 \u0438\u0441\u043f\u044b\u0442\u044b\u0432\u0430\u0435\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u0430\u043c \u043f\u0440\u043e\u0446\u0432\u0435\u0442\u0430\u0435\u0442 \u044d\u0442\u0430\u043a\u0438\u0439 BCL-\u043d\u0438\u0433\u0438\u043b\u0438\u0437\u043c. \u0421 \u044d\u0442\u0438\u043c \u043d\u0430\u0434\u043e \u0447\u0442\u043e-\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u0438\u0431\u043e \u044f \u0443\u0436\u0435 <s>\u0431\u043e\u043b\u044c\u0448\u0435 \u0433\u043e\u0434\u0430<\/s> \u043f\u043e\u0447\u0442\u0438 \u043f\u043e\u043b\u0442\u043e\u0440\u0430 \u0433\u043e\u0434\u0430 \u043a\u043e\u0432\u044b\u0440\u044f\u044e\u0441\u044c \u0432 \u0434\u0432\u0438\u0436\u043a\u0435, \u043d\u043e \u0442\u0430\u043a \u0438 \u043d\u0435 \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u043b \u0430\u0432\u0442\u043e\u0440\u0430, \u043a\u043e\u0434 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0431\u043b\u0438\u0437\u043a\u0438\u043c \u043a \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u0447\u043d\u043e\u043c\u0443 \u043f\u0440\u0435\u0434\u0435\u043b\u0443. \u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u044f \u0447\u0443\u0432\u0441\u0442\u0432\u0443\u044e \u0441\u0435\u0431\u044f \u0434\u0438\u0441\u043a\u043e\u043c\u0444\u043e\u0440\u0442\u043d\u043e, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u0435\u0434\u044a\u044f\u0432\u043b\u044f\u044e \u043f\u0440\u0435\u0442\u0435\u043d\u0437\u0438\u0438 \u043a \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434\u0430\u043c \u0432\u043d\u0443\u0442\u0440\u0438 \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434\u0430.<\/p>\n<hr\/>\n<p>\u042f \u043f\u043e\u043c\u0435\u043d\u044f\u043b \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u044b\u0439 <code>Vector2<\/code> \u043d\u0430 \u0434\u0438\u0441\u043a\u0440\u0435\u0442\u043d\u044b\u0439 <code>Vector2I<\/code> \u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u043b \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u0414\u043b\u044f \u0443\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u043a\u0430\u0440\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u043b\u0441\u044f \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0440\u0430\u043d\u044c\u0448\u0435 \u0432\u0441\u0435\u0445. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u043e\u043b\u044f \u0438\u0434\u0451\u0442 \u043f\u0435\u0440\u0432\u044b\u043c, \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u043e\u043b\u044f (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f) \u2014 \u0432\u0442\u043e\u0440\u044b\u043c, \u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 (\u043a\u043b\u0435\u0442\u043a\u0430 \u043f\u043e\u043b\u044f) \u2014 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c.<\/p>\n<pre><code>func can_stand(grid_pos:Vector2, obsts:PoolVector2Array, map_size:Vector2) -&gt; bool: return not (grid_pos in obsts) and in_map(grid_pos, map_size) <\/code><\/pre>\n<pre><code class=\"fsharp\">let canStand mapSize isObstacle pos =     inMap mapSize pos     &amp;&amp; not ^ isObstacle pos <\/code><\/pre>\n<p>\u041a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f <code>obsts<\/code> \u0432 F# \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043b\u0430 \u0431\u044b\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c \u0438 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b\u0430\u0441\u044c \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e-\u043f\u0440\u0435\u0434\u0438\u043a\u0430\u0442. \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043e \u0434\u0430\u043d\u043d\u044b\u0445 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043c\u0435\u043d\u044c\u0448\u0435, \u0447\u0435\u043c \u00ab\u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439\u00bb \u0442\u0438\u043f, \u043d\u043e \u0442\u0430\u043a\u0443\u044e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043f\u0440\u043e\u0449\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c. \u0427\u0438\u0441\u0442\u043e \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0432\u0437\u044f\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>IReadOnlySet<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u0438 \u0434\u043e\u0442\u043d\u0435\u0442\u043e\u0432\u0441\u043a\u0438\u043c <code>HashSet<\/code>, \u0438 F#-\u0441\u043a\u0438\u043c <code>Set<\/code>, \u0447\u0442\u043e \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b\u043e \u0431\u044b \u043d\u0430\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u0435, \u0442\u0430\u043a \u0438 \u0438\u043c\u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438. \u041e\u0434\u043d\u0430\u043a\u043e \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u043c\u0441\u044f \u0441 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f\u043c\u0438 <code>Set&lt;'a when 'a : comparion&gt;<\/code>. \u042d\u0442\u0430 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f \u0442\u0440\u0435\u0431\u0443\u0435\u0442, \u0447\u0442\u043e\u0431\u044b \u0442\u0438\u043f <code>'a<\/code> \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u043b \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 (\u0431\u043e\u043b\u044c\u0448\u0435, \u043c\u0435\u043d\u044c\u0448\u0435 \u0438 \u0442. \u0434.), \u0432 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a <code>Vector2I<\/code> \u0432 Godot \u044d\u0442\u0438\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e\u043c \u043d\u0435 \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442.<\/p>\n<p>\u041d\u0430\u0434\u043e \u043b\u0438\u0431\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0443\u044e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e (\u0438\u0437 <code>System.Collections.Immutable<\/code> \u0438\u043b\u0438 <code>FSharpx.Collections<\/code>), \u043b\u0438\u0431\u043e \u0432\u0437\u044f\u0442\u044c <code>Set&lt;int * int&gt;<\/code> \u0438 \u0441\u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 <code>Vector2I IReadOnlySet<\/code>. \u0417\u0430\u0434\u0430\u0447\u0430 \u0440\u0435\u0448\u0430\u0435\u043c\u0430, \u043d\u043e \u0432\u043e\u043e\u0431\u0449\u0435-\u0442\u043e \u0432 \u043d\u0435\u0434\u0440\u0430\u0445 <code>canStand<\/code> \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u043c\u0435\u0442\u043e\u0434 (<code>Contains<\/code>), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 <code>Set<\/code> \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c:<\/p>\n<pre><code class=\"fsharp\">interface IReadOnlySet&lt;Vector2I&gt; with     override this.Contains pos =          (obstacles : _ Set).Contains(pos.X, pos.Y)     ...     \/\/ \u0415\u0449\u0451 6 override \u0432 \u044d\u0442\u043e\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 \u0438 3 \u0432 \u043f\u0440\u0435\u0434\u043a\u0430\u0445 <\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 9 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c (\u0438\u043b\u0438 \u0438\u043c\u0438\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c) \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0437-\u0437\u0430 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043a\u043e\u043c\u0443-\u0442\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u044d\u0441\u0442\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u043c \u0432\u044b\u0440\u0430\u0437\u0438\u0442\u044c <code>obsts<\/code> \u0447\u0435\u0440\u0435\u0437 \u00ab\u043e\u0431\u0449\u0435\u043f\u0440\u0438\u043d\u044f\u0442\u044b\u0439\u00bb \u0442\u0438\u043f.<\/p>\n<hr\/>\n<p>\u0412\u0441\u0435 \u0448\u0430\u0433\u0438 \u043d\u0430 \u0435\u0434\u0438\u043d\u0438\u0446\u0443 \u0432\u043f\u0440\u0430\u0432\u043e, \u0432\u043b\u0435\u0432\u043e \u0438 \u0442. \u0434. \u0438\u043c\u0435\u044e\u0442 \u043e\u0434\u043d\u043e\u0438\u043c\u0451\u043d\u043d\u044b\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0432 \u043a\u043b\u0430\u0441\u0441\u0430\u0445, \u043d\u043e \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u043e \u043d\u0438\u0445 \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442:<\/p>\n<pre><code>func neighbors(grid_pos:Vector2,  obsts:PoolVector2Array, map_size:Vector2) -&gt; PoolVector2Array: var res:PoolVector2Array = [] var _neighbors = PoolVector2Array([grid_pos+Vector2(-1, 0), grid_pos+Vector2(1, 0),  grid_pos+Vector2(0, -1), grid_pos+Vector2(0, 1)]) for neigh in _neighbors: if can_stand(neigh, obsts, map_size): res.append(neigh) return res <\/code><\/pre>\n<pre><code class=\"fsharp\">let neighbours mapSize isObstacle pos =     [         Vector2I.Left         Vector2I.Right         Vector2I.Up         Vector2I.Down     ]     |&gt; Seq.map ^ fun p -&gt; p + pos     |&gt; Seq.filter ^ canStand mapSize isObstacle <\/code><\/pre>\n<hr\/>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043d\u0435 \u043d\u0430\u0434\u043e \u0437\u0430\u0431\u044b\u0432\u0430\u0442\u044c, \u043f\u0440\u043e \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438:<\/p>\n<pre><code>func heuristic(a:Vector2, b:Vector2) -&gt; int: return int(abs(a.x-b.x)+abs(a.y-b.y)) <\/code><\/pre>\n<pre><code class=\"fsharp\">let heuristic (a : Vector2I) b =     let xy = (a - b).Abs()     xy.X + xy.Y <\/code><\/pre>\n<h4>PriorityStack<\/h4>\n<p>\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a:<\/p>\n<pre><code>class PriorityStack:  var items:Array  func _init(): items = Array()  func empty() -&gt; bool: return items.size() == 0  func put(item, priority:int) -&gt; void: if empty(): items.append([item, priority]) elif priority &lt;= items[0][1]: items.insert(0, [item, priority]) elif priority &gt; items[-1][1]: items.append([item, priority]) else: for i in range(len(items)): if priority &lt;= items[i][1]: items.insert(i, [item, priority]) break  func take(): # \"get\" name already taken by Variant return items.pop_front()[0] <\/code><\/pre>\n<p>\u0412 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 <code>PriorityStack<\/code> \u2014 \u044d\u0442\u043e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f \u0442\u043e\u0447\u0435\u043a (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 <code>Vector2I<\/code>), \u0443\u043f\u043e\u0440\u044f\u0434\u043e\u0447\u0435\u043d\u043d\u044b\u0445 \u043f\u043e \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0443 (<code>int<\/code>). \u0412\u0430\u0436\u043d\u043e, \u0447\u0442\u043e \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u044b \u0442\u043e\u0447\u0435\u043a \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0442\u044c \u0438 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043a\u043b\u044e\u0447\u0430\u043c\u0438. \u0422\u0430\u043a\u0436\u0435 \u0432\u0430\u0436\u043d\u043e, \u0447\u0442\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438 \u043d\u0435 \u043d\u0443\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u043a \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438. \u041e\u043d \u0432\u0441\u0435\u0433\u0434\u0430 \u0437\u0430\u0431\u0438\u0440\u0430\u0435\u0442 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0441 \u0441\u0430\u043c\u044b\u043c \u043d\u0438\u0437\u043a\u0438\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u043e\u043c (\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0433\u043e\u043b\u043e\u0432\u0435 \u0441\u043f\u0438\u0441\u043a\u0430).<\/p>\n<p>\u0412 dotnet \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0445\u043e\u0436\u0438\u043c \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u043c \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 <code>PriorityQueue&lt;Vector2I, int&gt;<\/code>, \u043d\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u043d\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u0435\u043d \u0441\u0442\u0435\u043a\u0443. \u0417\u0430\u0442\u044b\u043a \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u0443\u043a\u043b\u0430\u0434\u043a\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0441 \u043e\u0434\u043d\u0438\u043c \u0438 \u0442\u0435\u043c \u0436\u0435 \u0443\u0440\u043e\u0432\u043d\u0435\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0430. <code>PriorityStack<\/code> \u043f\u0440\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u0432\u044b\u0434\u0430\u0441\u0442 \u0441\u0430\u043c\u043e\u0433\u043e \u0441\u0432\u0435\u0436\u0435\u0433\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u0430, \u0430 <code>PriorityQueue<\/code> \u043a\u043e\u0433\u043e-\u0442\u043e \u00ab\u0438\u0437\u00bb. \u041a\u043e\u0433\u043e \u0442\u043e\u0447\u043d\u043e \u043d\u0435 \u0437\u043d\u0430\u044e, \u043d\u043e \u0442\u0430\u043c \u043d\u0435 \u0440\u0430\u043d\u0434\u043e\u043c, \u043d\u0435 <code>FIFO<\/code> \u0438 \u043d\u0435 <code>LIFO<\/code>.<\/p>\n<details class=\"spoiler\">\n<summary>\u0427\u0443\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u0438\u043a\u0438 \u043f\u043e `PriorityQueue`<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0426\u0438\u0442\u0430\u0442\u0430 \u0438\u0437 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438:<\/p>\n<blockquote>\n<p><code>Note that the type does not guarantee first-in-first-out semantics for elements of equal priority.<\/code><\/p>\n<\/blockquote>\n<pre><code class=\"fsharp\">property {     let! items =         Range.constant 1 10         |&gt; Gen.int32         |&gt; Gen.list ^ Range.constant 2 10         |&gt; Gen.map ^ List.mapi ^ fun index priority -&gt; priority, index     let trueQueue = TruePriorityQueue()     let dotnetQueue = PriorityQueue()     do  for priority, value in items do             trueQueue.Put priority value             dotnetQueue.Put priority value     let actual, expected =         let f factory =             items             |&gt; Seq.choose ^ fun _ -&gt; factory ()             |&gt; List.ofSeq         f dotnetQueue.TryTake         , f trueQueue.TryTake     counterexample $\"Dotnet PriorityQueue: {actual}\"     counterexample $\"True PriorityQueue: {expected}\"     return actual = expected } <\/code><\/pre>\n<pre><code>*** Failed! Falsifiable (after 1 test and 4 shrinks): [(7, 0); (1, 1); (7, 2)] Dotnet PriorityQueue: [1; 2; 0] True PriorityQueue: [1; 0; 2] <\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0421\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c \u043f\u0443\u0442\u0438 \u0443 \u0432\u0441\u0435\u0445 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u0430\u044f, \u043d\u043e \u0441\u0430\u043c \u043f\u0443\u0442\u044c \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432 \u043c\u043e\u0436\u0435\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u0434\u0440\u0443\u0433\u0438\u043c. \u041d\u0430 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 \u0432\u043c\u0435\u0441\u0442\u043e \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0431\u0443\u043a\u0432\u044b <code>\u0413<\/code> \u0443 <code>PriorityQueue<\/code> \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u043f\u044c\u044f\u043d\u044b\u0439 \u0411\u0440\u0435\u0437\u0435\u043d\u0445\u0435\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a \u0442\u043e\u043c\u0443 \u0436\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a, \u0447\u0435\u043c <code>PriorityStack<\/code>:<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/lu\/op\/vl\/luopvlxbd1u01238tdufrmeredi.gif\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/webt\/lu\/op\/vl\/luopvlxbd1u01238tdufrmeredi.gif 780w,&#10;       https:\/\/habrastorage.org\/webt\/lu\/op\/vl\/luopvlxbd1u01238tdufrmeredi.gif 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c, \u043d\u0435 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0435\u0433\u043e \u0431\u044b\u043b\u043e \u043d\u0435\u043b\u044c\u0437\u044f:<\/p>\n<pre><code class=\"fsharp\">type PriorityStack&lt;'priority, 'value when 'priority : comparison&gt; () =     let items = ResizeArray()          member _.Put (priority : 'priority) (item : 'value) =         items         \/\/ \u0415\u0441\u043b\u0438 `priority &lt;= p`, \u0442\u043e \u0443 LIFO         \/\/ \u0435\u0441\u043b\u0438 `priority &lt; p`, \u0442\u043e \u0443 FIFO         |&gt; Seq.tryFindIndex ^ fun (p, _) -&gt; priority &lt;= p         |&gt; function             | Some index -&gt; items.Insert(index, (priority, item))             | None -&gt; items.Add (priority, item)      member _.TryTake () =         if items.Count = 0 then None else         let _, res = items.[0]         items.RemoveAt 0         Some res <\/code><\/pre>\n<p>\u0422\u0443\u0442 \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>option<\/code>, \u0447\u0442\u043e \u0440\u0430\u0434\u0438\u043a\u0430\u043b\u044c\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0430\u0435\u0442 \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0441\u0442\u044c \u0438 \u043e\u0431\u0435\u0441\u0441\u043c\u044b\u0441\u043b\u0438\u0432\u0430\u0435\u0442 \u0443\u0434\u0430\u043b\u0451\u043d\u043d\u044b\u0439 \u043c\u043d\u043e\u044e <code>IsEmpty<\/code>.<\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u043e\u043f\u044f\u0442\u044c \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0435\u043c\u0441\u044f \u0441 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435\u043c <code>when 'priority : comparison<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0442\u0438\u043f \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0430 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435. \u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0443 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442 \u0432\u043e\u043f\u0440\u043e\u0441\u044b \u043a \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044e <code>priority &lt;= p<\/code>. \u0415\u0441\u043b\u0438 \u0431\u044b \u0440\u0435\u0447\u044c \u0448\u043b\u0430 \u043d\u0435 \u043e \u0442\u0438\u043f\u0435, \u0430 \u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0442\u043e \u044d\u0442\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0431\u044b\u043b\u043e \u0431\u044b \u0432\u044b\u0432\u0435\u0434\u0435\u043d\u043e \u0438\u0437 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438. \u0422\u043e \u0435\u0441\u0442\u044c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043f\u0440\u043e\u0433\u043d\u0443\u043b \u0431\u044b \u043e\u0431\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 \u0443\u0433\u043e\u0434\u0443 \u043b\u043e\u0433\u0438\u043a\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0421 \u0442\u0438\u043f\u0430\u043c\u0438 \u0442\u0430\u043a\u0430\u044f \u043c\u0430\u0433\u0438\u044f \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u0414\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u0438 \u0438 \u0438\u0445 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u043d\u0430\u0434\u043e \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0442\u044c \u044f\u0432\u043d\u043e. \u0412 \u043e\u0431\u0449\u0438\u0445 \u0447\u0435\u0440\u0442\u0430\u0445 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0441 \u0433\u0435\u043d\u0435\u0440\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0441\u0435\u0442\u0442\u0435\u0440\u043e\u0432. \u0422\u0435\u0440\u043f\u0438\u043c\u043e, \u043d\u043e \u0438\u043d\u043e\u0433\u0434\u0430 \u0431\u0435\u0441\u0438\u0442.<\/p>\n<p><code>PriorityStack<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445, \u0438 \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u043d\u043e\u0433\u0434\u0430 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u043d\u0430\u0440\u0443\u0436\u0443, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u043b\u043e\u0433\u0438 \u0443\u043f\u0430\u0432\u0448\u0438\u0445 \u0442\u0435\u0441\u0442\u043e\u0432 \u0438\u043b\u0438 \u0432 \u043c\u0430\u0441\u043a\u0443 \u043a\u0430\u0440\u0442\u044b. \u0414\u0430\u043d\u043d\u044b\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043b\u0438\u043d\u0435\u0439\u043d\u043e, \u0447\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u043e \u043e\u0442\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0432 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 <code>_ IEnumerable<\/code> (\u043e\u043d \u0436\u0435 <code>_ seq<\/code>). \u0418 \u0431\u0443\u0434\u044c \u0437\u0434\u0435\u0441\u044c C#, \u043c\u044b, \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u0442\u0430\u043a \u0431\u044b \u0438 \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u043b\u0438. \u041d\u043e \u043d\u0430 F# \u0432\u043f\u043e\u043b\u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043c\u0435\u0442\u043e\u0434\u0430 <code>AsSeq<\/code> (\u0438\u043b\u0438 <code>ToSeq<\/code>):<\/p>\n<pre><code class=\"fsharp\">    member this.AsSeq () = Seq.readonly items <\/code><\/pre>\n<p>\u041a\u043e\u043c\u0443 \u043d\u0430\u0434\u043e, \u0434\u0451\u0440\u043d\u0435\u0442. \u041a\u043e\u043c\u0443 \u043d\u0435 \u043d\u0430\u0434\u043e, \u043f\u0440\u043e\u0439\u0434\u0451\u0442 \u043c\u0438\u043c\u043e.<\/p>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043d\u0435\u043e\u0431\u044b\u0447\u043d\u043e, \u043d\u043e \u043a \u044d\u0442\u043e\u043c\u0443 \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u0440\u0438\u0432\u044b\u043a\u0430\u0435\u0448\u044c, \u0442\u0430\u043a \u043a\u0430\u043a \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u0434\u0435\u043b\u043e \u0441\u043e \u0441\u0442\u0430\u0440\u044b\u043c \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u043e\u043c \u00ab\u0444\u0430\u0441\u0430\u0434\u00bb. \u0415\u0441\u043b\u0438 \u0432\u0434\u0443\u043c\u0430\u0442\u044c\u0441\u044f, \u0442\u043e <code>AsSeq<\/code> \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u0432\u044b\u0434\u0430\u0451\u0442 \u043e\u0431\u044a\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u043d\u043e\u0432\u0430\u044f \u043e\u0431\u0451\u0440\u0442\u043a\u0430 \u043d\u0430\u0434 <code>items<\/code>. \u0415\u0451, \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435, \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u043d\u043e \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u043d\u0435 \u044d\u0442\u043e, \u0430 \u0442\u043e, \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 <code>seq<\/code> \u043d\u0435 \u0442\u043e\u0436\u0434\u0435\u0441\u0442\u0432\u0435\u043d\u0435\u043d \u0441\u0432\u043e\u0435\u043c\u0443 <code>PriorityStack<\/code>.<\/p>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c\u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044f\u043c. \u041e\u043d\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u0430 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0442\u0438\u043f\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043b\u0435\u0433\u043a\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u043b\u0435\u0442\u0443. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u00ab\u0442\u0438\u043f\u0435-\u043c\u0430\u0442\u043a\u0435\u00bb \u0432\u0438\u0441\u0438\u0442 \u0446\u0435\u043b\u0430\u044f \u0433\u0440\u043e\u0437\u0434\u044c \u0442\u0430\u043a\u0438\u0445 \u0444\u0430\u0441\u0430\u0434\u043e\u0432, \u0438 \u0447\u0435\u0440\u0435\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0433\u043b\u0430\u0432 \u043c\u044b \u043a \u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0434\u0451\u043c.<\/p>\n<h4>\u0410\u043b\u0433\u043e\u0440\u0438\u0442\u043c<\/h4>\n<p>\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a:<\/p>\n<pre><code>func find_path(start:Vector2, goal:Vector2, obsts:PoolVector2Array, map_size:Vector2) -&gt; PoolVector2Array: var frontier = PriorityStack.new() frontier.put(start, 0) var came_from = {} var cost_so_far = {} came_from[start] = start cost_so_far[start] = 0  var current:Vector2 var new_cost:int  if not can_stand(goal, obsts, map_size): return PoolVector2Array()  while not frontier.empty(): current = frontier.take()  if current == goal: break  for next in neighbors(current, obsts, map_size): new_cost = cost_so_far[current] + 1  if not (next in cost_so_far) or new_cost &lt; cost_so_far[next]: cost_so_far[next] = new_cost frontier.put(next, new_cost + heuristic(goal, next)) came_from[next] = current  if frontier.empty() and current != goal: return PoolVector2Array()  current = goal var path:PoolVector2Array = PoolVector2Array([current])  while current != start: current = came_from[current] path.append(current)  path.invert() <\/code><\/pre>\n<p>\u0412 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u043d\u0438\u0447\u0435\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0433\u043e, \u043d\u043e \u043c\u043d\u0435 \u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f, \u0447\u0442\u043e \u043f\u0443\u0441\u0442\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043d\u0435\u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0439 \u043f\u0443\u0442\u044c. \u0422\u0430\u043a\u0436\u0435 \u043c\u043d\u0435 \u0442\u0440\u0443\u0434\u043d\u043e \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0432\u044b\u0445\u043e\u0434\u044b. \u0418\u0445 \u0442\u0443\u0442 3 \u0448\u0442\u0443\u043a\u0438: \u043d\u0435 \u0438\u0441\u043a\u0430\u043b\u0438 (\u0432 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0442\u043e\u0447\u043a\u0435 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435 \u0438\u043b\u0438 \u043e\u043d\u0430 \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 \u043f\u043e\u043b\u044f), \u043d\u0435 \u043d\u0430\u0448\u043b\u0438 \u0438 \u043d\u0430\u0448\u043b\u0438. \u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043c\u0435\u0436\u0434\u0443 \u0432\u0442\u043e\u0440\u044b\u043c \u0438 \u0442\u0440\u0435\u0442\u044c\u0438\u043c <code>return<\/code> \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e <code>break<\/code>. \u0421 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0432\u0437\u0433\u043b\u044f\u0434\u0430 \u044d\u0442\u043e\u0442 \u0444\u0430\u043a\u0442 \u043d\u0435 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u0430 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b.<\/p>\n<p>\u0412 F# \u0441 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u043a\u0430\u043a-\u0442\u043e \u043f\u043e\u043f\u0440\u043e\u0449\u0435:<\/p>\n<pre><code class=\"fsharp\">let tryFindPath mapSize isObstacle start goal =     if not ^ canStand mapSize isObstacle goal then None else     let frontier = PriorityStack()     frontier.Put 0 start     let cameFrom = Dictionary()     cameFrom.[start] &lt;- start     let costSoFar = Dictionary()     costSoFar.[start] &lt;- 0      let rec tryFind () =         match frontier.TryTake () with         | None -&gt; None         | Some current when current = goal -&gt;             let path = Stack()             path.Push goal             let rec buildPath current =                 if current &lt;&gt; start then                     let current = cameFrom.[current]                     path.Push current                     buildPath current             buildPath goal \/\/ \u0421\u0442\u0435\u043a \u0440\u0430\u0441\u043a\u0440\u043e\u0435\u0442\u0441\u044f \u0441\u0432\u0435\u0440\u0445\u0443 \u0432\u043d\u0438\u0437, \u0442\u0430\u043a \u0447\u0442\u043e `rev` \u043d\u0435 \u043d\u0443\u0436\u0435\u043d.             Some ^ List.ofSeq path         | Some current -&gt;             let newCost = costSoFar.[current] + 1             for next in neighbours mapSize isObstacle current do                 match costSoFar.TryGetValue next with                 | true, oldCost when newCost &gt;= oldCost -&gt; ()                 | _ -&gt;                     costSoFar.[next] &lt;- newCost                     frontier.Put (newCost + heuristic goal next) next                     cameFrom.[next] &lt;- current             tryFind ()     tryFind () <\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u0438, \u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c <code>option<\/code>, \u043e\u043d \u0434\u0435\u043b\u0430\u0435\u0442 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0447\u0442\u043e \u0438 GDScript. \u041e\u0434\u043d\u0430\u043a\u043e \u043a \u043d\u0435\u043c\u0443 \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u0441\u043c\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0439.<\/p>\n<p>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0439 \u043d\u0430 \u0431\u0430\u0437\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432 F# \u0438\u043c\u0435\u0435\u0442 \u0443\u0441\u0442\u043e\u044f\u0432\u0448\u0435\u0435\u0441\u044f \u0438\u043c\u044f \u2014 <code>singleton<\/code>. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>List.singleton 42 = [42]<\/code>. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u043f\u0438\u0441\u043a\u043e\u0432 \u043a\u043e\u0434 \u043a\u043e\u0440\u043e\u0447\u0435 \u043d\u0435 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f, \u043d\u043e \u043d\u0435 \u0443 \u0432\u0441\u0435\u0445 \u0442\u0438\u043f\u043e\u0432 \u0435\u0441\u0442\u044c \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441. <code>singleton<\/code> \u0442\u043e\u0436\u0435 \u0435\u0441\u0442\u044c \u043d\u0435 \u0443 \u0432\u0441\u0435\u0445, \u043d\u043e \u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e:<\/p>\n<pre><code class=\"fsharp\">module PriorityStack =     let singleton priority item =         let result = PriorityQueue()         result.Put priority item         result  module Dictionary =     let singleton key value =         let result = Dictionary()         result.[key] &lt;- value         result <\/code><\/pre>\n<p>\u041e\u0434\u043d\u0430 \u0438\u0437 \u0432\u0435\u0442\u043e\u043a <code>tryFind<\/code> \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441:<\/p>\n<pre><code class=\"fsharp\">| Some current when current = goal -&gt; <\/code><\/pre>\n<p>\u0418 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0435\u0451 \u043c\u043e\u0436\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0434\u043e:<\/p>\n<pre><code class=\"fsharp\">| Some goal -&gt; <\/code><\/pre>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u043f\u0440\u0438 \u0442\u0430\u043a\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u0448\u0430\u0434\u043e\u0432\u0438\u043d\u0433 \u0441\u0442\u0430\u0440\u043e\u0433\u043e <code>goal<\/code>, \u0430 \u043d\u0435 \u0444\u0438\u043b\u044c\u0442\u0440. \u041d\u0443\u0436\u043d\u043e\u0433\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0441\u0442\u0438\u0447\u044c, \u0435\u0441\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 <code>Utils<\/code> \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0448\u0430\u0431\u043b\u043e\u043d:<\/p>\n<pre><code class=\"fsharp\">let (|Eq|_|) expected actual =     if expected = actual then Some () else None <\/code><\/pre>\n<p>\u0422\u043e\u0433\u0434\u0430 \u0444\u0438\u043b\u044c\u0442\u0440 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"fsharp\">| Some (Eq goal) -&gt; <\/code><\/pre>\n<p>\u0427\u0443\u0442\u044c \u0434\u043b\u0438\u043d\u043d\u0435\u0435, \u0447\u0435\u043c <code>Some goal<\/code>, \u043d\u043e \u0431\u0435\u0437 \u0440\u0430\u0437\u043d\u043e\u0447\u0442\u0435\u043d\u0438\u0439. \u041a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0430\u0436\u043d\u043e\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e <code>Eq<\/code> \u2014 \u0441\u043a\u043e\u0443\u043f \u043d\u0435 \u0437\u0430\u0441\u043e\u0440\u044f\u0435\u0442\u0441\u044f \u043b\u0438\u0448\u043d\u0438\u043c <code>current<\/code>. \u0410 \u0437\u0434\u0435\u0441\u044c \u043e\u043d \u0442\u043e\u0447\u043d\u043e \u043b\u0438\u0448\u043d\u0438\u0439, \u0442\u0430\u043a \u043a\u0430\u043a \u0432\u043c\u0435\u0441\u0442\u043e \u043d\u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0438 \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 <code>goal<\/code>.<\/p>\n<p>\u041a\u043e\u0434 \u043f\u043e\u0441\u043b\u0435 \u0432\u0441\u0435\u0445 \u043f\u0440\u0430\u0432\u043e\u043a:<\/p>\n<pre><code class=\"fsharp\">let tryFindPath mapSize isObstacle start goal =     if not ^ inMap mapSize goal then Result.Error OutOfBounds     elif isObstacle goal then Result.Error Obstacle else     let frontier = PriorityStack.singleton 0 start     let cameFrom = Dictionary.singleton start start     let costSoFar = Dictionary.singleton start 0      let rec tryFind () =         match frontier.TryTake () with         | None -&gt; None         | Some (Eq goal) -&gt;             let path = Stack()             path.Push goal             let rec buildPath current =                 if current &lt;&gt; start then                     let current = cameFrom.[current]                     path.Push current                     buildPath current             buildPath goal             Some ^ List.ofSeq path         | Some current -&gt;             let newCost = costSoFar.[current] + 1             for next in neighbours mapSize isObstacle current do                 match costSoFar.TryGetValue next with                 | true, oldCost when newCost &gt;= oldCost -&gt; ()                 | _ -&gt;                     costSoFar.[next] &lt;- newCost                     frontier.Put (newCost + heuristic goal next) next                     cameFrom.[next] &lt;- current             tryFind ()     tryFind () <\/code><\/pre>\n<h3>\u041e\u0448\u0438\u0431\u043a\u0438 \u0438 \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0438<\/h3>\n<p>\u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u043d\u0435\u0434\u043e\u0441\u0442\u0438\u0436\u0438\u043c\u043e\u0441\u0442\u0438 \u0446\u0435\u043b\u0438 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0430 \u0432 UI. \u041f\u043e \u0438\u0434\u0435\u0435, \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f \u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0435 \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430\u0440\u0430\u043d\u0435\u0435. \u041d\u043e \u044d\u0442\u0443 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0435\u0449\u0451 \u043d\u0443\u0436\u043d\u043e \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043f\u0443\u0442\u044f\u043c\u0438 \u0434\u043e\u0442\u0430\u0449\u0438\u0442\u044c \u0434\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f, \u0432 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a \u0432 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0435 \u043f\u043e\u0438\u0441\u043a\u0430 \u043d\u0443\u0436\u043d\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c. \u041d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430 \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u0442\u044c \u043b\u043e\u0433\u0438\u0441\u0442\u0438\u043a\u0443, \u043f\u0440\u043e\u0449\u0435 \u0441\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u0444\u0438\u043b\u044c\u0442\u0440 \u0438 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0441 <code>option<\/code> \u043d\u0430 <code>Result&lt;_, Error&gt;<\/code>:<\/p>\n<pre><code class=\"fsharp\">\/\/ \u0412\u043d\u0443\u0442\u0440\u0438 \u043c\u043e\u0434\u0443\u043b\u044f PathFinder. type Error =     | OutOfBounds     | Obstacle     | Unreachable <\/code><\/pre>\n<p>\u0422\u0438\u043f <code>Error<\/code> \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043f\u043e \u043c\u0435\u0440\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438, \u043d\u043e \u043e \u0432\u0435\u0442\u043a\u0435 <code>Ok<\/code> \u0437\u0430\u0431\u044b\u0432\u0430\u0442\u044c \u0442\u043e\u0436\u0435 \u043d\u0435 \u0441\u0442\u043e\u0438\u0442. \u041e\u0447\u0435\u043d\u044c \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u0434\u043b\u044f \u043d\u0435\u0451 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 DU. \u041a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u0432 \u043c\u043e\u0438\u0445 \u043f\u0435\u0442-\u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u044d\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u0435\u0449\u0451 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u043e\u0432. \u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u043e\u0442\u0432\u0435\u0442\u044b \u00ab\u0441\u043e \u0437\u0432\u0451\u0437\u0434\u043e\u0447\u043a\u0430\u043c\u0438\u00bb, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u0443\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0435\u043d \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0442\u0430\u043a, \u043a\u0430\u043a \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043a\u0430\u0440\u0442\u0430\u0445 \u043f\u0440\u0438\u043d\u044f\u0442\u043e \u043b\u0438\u043c\u0438\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u0438\u043d\u0443 \u043f\u0443\u0442\u0438, \u0447\u0442\u043e\u0431\u044b \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e \u043d\u0435 \u043f\u0440\u043e\u043f\u0435\u0441\u043e\u0447\u0438\u0442\u044c \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0443 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u044b (\u044d\u0442\u043e \u0434\u043e\u0440\u043e\u0433\u043e). \u0415\u0441\u043b\u0438 \u0446\u0435\u043b\u0435\u0432\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u0437\u0430 \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u043f\u043e\u0438\u0441\u043a\u0430, \u0442\u043e \u044e\u043d\u0438\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442 \u043a \u0442\u043e\u0447\u043a\u0435 \u0441 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0431\u043b\u0438\u0437\u043a\u0438\u043c \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u043c \u044d\u0432\u0440\u0438\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 (\u0441\u043c. <code>heuristic<\/code>). \u042d\u0432\u0440\u0438\u0441\u0442\u0438\u043a\u0430 \u2014 \u043d\u0430\u0443\u043a\u0430 \u043d\u0435\u0442\u043e\u0447\u043d\u0430\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u044b \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 \u044e\u043d\u0438\u0442 \u0437\u0430\u0431\u0435\u0433\u0430\u0435\u0442 \u0432 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0439 \u0442\u0443\u043f\u0438\u043a, \u043f\u0440\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u0435\u043d\u0438\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0432\u044b\u0431\u0435\u0433\u0430\u0435\u0442, \u043f\u0440\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u043d\u043e\u0432\u0430 \u0437\u0430\u0431\u0435\u0433\u0430\u0435\u0442 \u0438 \u0442\u0430\u043a \u043f\u043e \u043a\u0440\u0443\u0433\u0443. \u0412\u044b\u0439\u0442\u0438 \u0438\u0437 \u0446\u0438\u043a\u043b\u0430 \u043c\u043e\u0436\u043d\u043e, \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0432 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u043f\u043e \u043a\u0443\u0441\u043e\u0447\u043a\u0430\u043c \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e. \u0412 RPG \u0442\u0430\u043a\u043e\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0435\u0440\u043f\u0438\u043c\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u0433\u0435\u0440\u043e\u0439 \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u043e \u0432 \u043f\u043e\u043b\u0435 \u0437\u0440\u0435\u043d\u0438\u044f \u0438\u0433\u0440\u043e\u043a\u0430, \u043d\u043e \u0432 RTS \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u043c\u043e\u0440\u0433\u0430\u0442\u044c \u043d\u0435\u0437\u0430\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0441\u0430\u043c\u043e\u0443\u0431\u0438\u0439\u0441\u0442\u0432\u043e \u043a\u043e\u043d\u043d\u044b\u0445 \u043b\u0443\u0447\u043d\u0438\u043a\u043e\u0432 \u043e \u0432\u0440\u0430\u0436\u0435\u0441\u043a\u0438\u0439 \u0434\u043e\u043d\u0436\u043e\u043d.<\/p>\n<p>\u0421 \u043c\u043e\u0435\u0439 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f, \u0441\u043e\u0433\u043b\u0430\u0441\u0438\u0435 \u043d\u0430 \u044d\u0432\u0440\u0438\u0441\u0442\u0438\u043a\u0443 (\u0438\u043b\u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442) \u0434\u043e\u043b\u0436\u043d\u043e \u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u044f\u0432\u043d\u043e. \u041a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u043d\u0430\u0434\u043e \u043f\u043e\u0434\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u0442\u044c \u0442\u043e\u0447\u043a\u0443 \u0437\u0430\u043c\u0435\u043d\u044b. \u041a\u0430\u043a \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u2014 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f (\u0445\u043e\u0442\u044f \u0431\u044b \u0447\u0435\u0440\u0435\u0437 \u0437\u0430\u0436\u0430\u0442\u044b\u0439 <code>Ctrl<\/code>). \u0422\u0435 \u0436\u0435 \u043f\u0440\u0435\u0442\u0435\u043d\u0437\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u044a\u044f\u0432\u0438\u0442\u044c \u043a \u0433\u0438\u043f\u043e\u0442\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043f\u0443\u0442\u044f\u043c \u0447\u0435\u0440\u0435\u0437 \u0442\u0443\u043c\u0430\u043d \u0432\u043e\u0439\u043d\u044b. \u0415\u0441\u043b\u0438 \u043c\u043e\u044f \u043a\u0430\u0442\u0430\u043f\u0443\u043b\u044c\u0442\u0430 \u0432\u0435\u0440\u0438\u0442, \u0447\u0442\u043e \u0437\u0430 \u043a\u0430\u0436\u0434\u044b\u043c \u00ab\u0447\u0451\u0440\u043d\u044b\u043c\u00bb \u0433\u0435\u043a\u0441\u043e\u043c \u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0443\u0448\u0430, \u0442\u043e \u0432 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u0432\u0434\u0430\u0440\u0438\u0442\u044c \u043f\u043e \u041e\u0441\u0430\u043a\u0435 \u043e\u043d\u0430 \u043c\u043e\u0436\u0435\u0442 \u0434\u043e\u0442\u043e\u043f\u0430\u0442\u044c \u043e\u0442 \u041f\u0443\u0441\u0430\u043d\u0430 \u0434\u043e \u0410\u043d\u0430\u0434\u044b\u0440\u0438. \u042f \u0436\u0434\u0443 \u043d\u0435 \u044d\u0442\u043e\u0433\u043e. \u041f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0438\u0437 \u0442\u043e\u0439 \u0436\u0435 \u043e\u043f\u0435\u0440\u044b \u043f\u043e\u0438\u0441\u043a \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0443\u0442\u0438 \u0432 \u0441\u0440\u0435\u0434\u0430\u0445 \u0441 \u043f\u0430\u0441\u0441\u0438\u0432\u043d\u044b\u043c \u0443\u0440\u043e\u043d\u043e\u043c. \u0412 \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 \u044f \u043d\u0435 \u0445\u043e\u0447\u0443 \u0442\u0430\u0441\u043a\u0430\u0442\u044c \u0430\u0440\u043c\u0438\u044e \u043f\u043e \u043f\u0443\u0441\u0442\u044b\u043d\u044f\u043c \u0413\u0435\u0434\u0440\u043e\u0441\u0438\u0438, \u043d\u043e \u0447\u0442\u043e, \u0435\u0441\u043b\u0438 \u043c\u043d\u0435 \u043d\u0430\u0434\u043e? \u0418 \u0435\u0441\u043b\u0438 \u043d\u0430\u0434\u043e, \u0442\u043e \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0438\u043b\u044c\u043d\u043e?<\/p>\n<p>\u0421\u043b\u043e\u0436\u043d\u044b\u0445 \u043a\u0435\u0439\u0441\u043e\u0432 \u043c\u043d\u043e\u0433\u043e, \u043d\u043e \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 <strong>\u0434\u0430\u043d\u043d\u043e\u0433\u043e<\/strong> \u0446\u0438\u043a\u043b\u0430 \u043c\u044b \u0438\u043c\u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0431\u0443\u0434\u0435\u043c. \u0421\u0435\u0439\u0447\u0430\u0441 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u0432 \u044d\u0442\u043e\u043c \u043c\u0435\u0441\u0442\u0435 \u043c\u043e\u0436\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0447\u0435\u0433\u043e \u043d\u0430\u043a\u0440\u0443\u0442\u0438\u0442\u044c, \u043f\u0440\u0438\u0447\u0451\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e. \u0411\u0435\u0437 \u0443\u0449\u0435\u0440\u0431\u0430 \u0434\u043b\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u043d\u043e \u0441 \u044f\u0432\u043d\u044b\u043c \u0431\u043e\u043d\u0443\u0441\u043e\u043c \u043a \u043e\u0442\u0437\u044b\u0432\u0447\u0438\u0432\u043e\u0441\u0442\u0438.<\/p>\n<h3>\u0412\u044b\u0432\u043e\u0434 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445<\/h3>\n<p>\u0412 \u0442\u0435\u043b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0435\u0441\u0442\u044c \u0442\u0440\u0438 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438: <code>frontier<\/code>, <code>cameFrom<\/code> \u0438 <code>costSoFar<\/code>. \u041f\u043e \u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u043e\u043d\u0438 \u2014 \u043f\u043e\u0431\u043e\u0447\u043d\u044b\u0439 \u043f\u0440\u043e\u0434\u0443\u043a\u0442 \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438. \u0418\u0445 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043f\u0435\u0440\u0435\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u0438\u0441\u043a\u043e\u043c\u044b\u0439 \u043f\u0443\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0439\u0434\u0435\u043d, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0434\u043e\u043b\u0438 \u00ab\u0434\u043e\u0434\u0435\u043b\u0430\u043d\u043d\u044b\u0445\u00bb \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0443\u0442\u044c \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d \u0438 \u0438\u0437\u0432\u043b\u0435\u0447\u0451\u043d \u043d\u0430\u0440\u0443\u0436\u0443.<\/p>\n<p>\u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u00ab\u043d\u0435\u0434\u043e\u0434\u0435\u043b\u0430\u043d\u043d\u044b\u0435\u00bb \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0435\u043b\u044c\u0437\u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u043d\u043e \u0432 \u043d\u0438\u0445 \u0431\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0437\u0430\u0433\u043b\u044f\u0434\u044b\u0432\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u044f\u0442\u044c \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u0440\u0430\u0431\u043e\u0442\u044b \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u0438\u043b\u0438 \u0436\u0435 \u043f\u0440\u0438\u0447\u0438\u043d\u0443 \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f. \u041d\u0435\u0436\u0434\u0430\u043d\u0447\u0438\u043a \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u0432\u044f\u0437\u0430\u043d \u0441 \u0431\u0430\u0433\u043e\u043c, \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0447\u0430\u0449\u0435 \u0438\u043c\u0435\u0435\u0442 \u043c\u0435\u0441\u0442\u043e \u043d\u0435\u0434\u043e\u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438. \u0412\u044b\u0448\u0435, \u043a\u043e\u0433\u0434\u0430 \u044f \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u043b \u0440\u0430\u0437\u043d\u0438\u0446\u0443 \u043c\u0435\u0436\u0434\u0443 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0432\u0435\u0440\u0441\u0438\u044f\u043c\u0438 <code>PriorityStack<\/code>, \u043c\u044b \u0434\u0435\u043b\u0430\u043b\u0438 \u0438\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e. \u0422\u0435 \u0441\u0445\u0435\u043c\u044b \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u043d\u044b \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0435\u0440\u0435\u0434 \u044d\u0442\u0438\u043c \u0442\u0430\u043a\u0438 \u043d\u0430\u0434\u043e \u0431\u044b\u043b\u043e \u0438\u0437\u0432\u043b\u0435\u0447\u044c \u043d\u0430\u0440\u0443\u0436\u0443. \u041f\u0440\u043e\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e \u0431\u044b\u043b\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0435 \u0440\u0435\u043a\u043e\u0440\u0434\u044b:<\/p>\n<pre><code class=\"fsharp\">Ok {|     Path = List.ofSeq path     CostSoFar = costSoFar.AsReadOnly()     CameFrom = cameFrom.AsReadOnly()     Frontier = List.ofSeq ^ frontier.AsSeq()     \/\/ \u0421\u044e\u0434\u0430 \u0441\u0440\u0430\u0437\u0443 \u0441\u0442\u043e\u0438\u0442 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u044f `Start`, `Cost` \u0438 `Goal`, \u043d\u043e \u044f \u044d\u0442\u043e\u0433\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0443, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b. |} <\/code><\/pre>\n<p>\u0410\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0439 \u0440\u0435\u043a\u043e\u0440\u0434 \u043b\u0443\u0447\u0448\u0435 \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u0442\u0435\u043c, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0442\u044c, \u043a\u0430\u043a\u043e\u0439 \u0442\u0438\u043f \u0438\u043c\u0435\u0435\u0442 \u043a\u0430\u0436\u0434\u043e\u0435 \u0438\u0437 \u043f\u043e\u043b\u0435\u0439. \u041e\u043d\u0438 \u0441\u0442\u0440\u043e\u0433\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u0435\u0439 \u0441\u0432\u043e\u0435\u0433\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c. \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0431\u0435\u0437 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0441\u0441\u044b\u043b\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0442\u0438\u043f \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u043e\u0433\u043e \u0440\u0435\u043a\u043e\u0440\u0434\u0430 \u0431\u044b\u0432\u0430\u0435\u0442 \u0442\u0440\u0443\u0434\u043d\u043e. \u041f\u043e\u043a\u0430 \u0440\u0435\u0447\u044c \u0438\u0434\u0451\u0442 \u043e \u0447\u0451\u043c-\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u043c, \u0442\u0438\u043f\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u043a\u0440\u0443\u0442\u0438\u0442\u044c\u0441\u044f:<\/p>\n<pre><code class=\"fsharp\">let mutable path = None  let invalidatePath cellUnderMouse =     ...     \/\/ \u0421 \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0442\u043e\u0447\u043d\u043e \u0437\u043d\u0430\u0435\u0442 \u0442\u0438\u043f `path`     path &lt;- Some ^ PathFinder.tryFindPath ...  match path with | Some (Ok result) -&gt;     \/\/ \u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043f\u043e\u0434\u0441\u043a\u0430\u0436\u0435\u0442 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e `Path` \u0438 \u0435\u0433\u043e \u0442\u0438\u043f ` : Vector2I list`.     for step in result.Path do         ... <\/code><\/pre>\n<p>\u041d\u043e \u0435\u0441\u043b\u0438 \u0440\u0435\u0447\u044c \u0438\u0434\u0451\u0442 \u043d\u0435 \u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u044f\u0447\u0435\u0439\u043a\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u0430 \u043e\u0431\u043e \u0432\u0441\u0435\u0445 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430\u0445 \u0442\u0438\u043f\u0430, \u0442\u043e \u043c\u044b \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u043c \u0432\u043f\u0440\u043e\u0441\u0430\u043a. \u041d\u0430 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0439 \u0440\u0435\u043a\u043e\u0440\u0434 \u043d\u0435\u043b\u044c\u0437\u044f \u043d\u0430\u0432\u0435\u0441\u0438\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f. \u041f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u043f\u043e\u043c\u0438\u043d\u0430\u0442\u044c \u0435\u0433\u043e \u043f\u043e \u00ab\u0438\u043c\u0435\u043d\u0438\u00bb, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0435\u0433\u043e \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0435:<\/p>\n<pre><code class=\"fsharp\">let debugDraw (pathFound : {| CameFrom: IReadOnlyDictionary&lt;Vector2I, Vector2I&gt;; CostSoFar: IReadOnlyDictionary&lt;Vector2I, int&gt;; Frontier: (int, Vector2I) list; Path: Vector2I list |}) ... = ... <\/code><\/pre>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u0438\u043c, \u0432\u0441\u0451 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e \u043e\u0442 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e\u0433\u043e \u0432\u044b\u0432\u043e\u0434\u0430 \u0442\u0438\u043f\u043e\u0432 \u0441\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0443\u043d\u0438\u0442\u0430\u0437. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u0437\u0434\u0451\u0432\u043a\u0438, \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u0440\u0435\u043a\u043e\u0440\u0434\u0430 \u043d\u0430 2 \u0437\u043d\u0430\u043a\u0430 \u043a\u043e\u0440\u043e\u0447\u0435, \u0447\u0435\u043c \u00ab\u0438\u043c\u044f\u00bb \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u043e\u0433\u043e. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043b\u044e\u0431\u043e\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043e\u0431\u0440\u0435\u0442\u0430\u0435\u0442 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0436\u0438\u0437\u043d\u044c \u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u0430\u043d\u043d\u044b\u0445. \u041f\u0440\u0438\u0448\u043b\u044b\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u044b \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u043e \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442 \u0435\u0433\u043e \u043a\u0430\u043a \u0432\u044b\u0441\u0448\u0443\u044e \u0438\u043d\u0441\u0442\u0430\u043d\u0446\u0438\u044e. \u041f\u043e \u0445\u043e\u0434\u0443 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044f \u043a\u043e\u0434\u0430 \u043d\u0430\u043c \u043d\u0430\u0447\u043d\u0451\u0442 \u043f\u0440\u0438\u043b\u0435\u0442\u0430\u0442\u044c \u043e\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u0437\u0430 \u0442\u043e, \u0447\u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0434 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u0430, \u0445\u043e\u0442\u044f \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u044d\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0438\u043f \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0434 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.<\/p>\n<p>\u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u0442\u0438\u043f \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u043f\u0440\u0430\u0432\u0438\u0442\u044c, \u043d\u043e \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u043f\u043e\u043b\u044f \u2014 \u044d\u0442\u043e \u043e\u0449\u0443\u0442\u0438\u043c\u044b\u0439 \u0433\u0435\u043c\u043e\u0440\u0440\u043e\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0441\u0443\u0433\u0443\u0431\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u0435\u043c, \u0447\u0442\u043e \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u044b \u043d\u0430 \u043c\u043e\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445, \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430\u0445. \u041d\u0435 \u0444\u0430\u043a\u0442, \u0447\u0442\u043e \u0432\u0441\u0435 \u043e\u043d\u0438 \u0440\u0430\u0431\u043e\u0447\u0438\u0435, \u043d\u043e \u044f \u0438\u0445 \u043c\u043d\u043e\u0433\u043e\u043a\u0440\u0430\u0442\u043d\u043e \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u044e, \u043f\u043e\u0434\u043a\u0440\u0443\u0447\u0438\u0432\u0430\u044e \u0438 \u043f\u0435\u0440\u0435\u0441\u043e\u0437\u0434\u0430\u044e \u043f\u043e \u043c\u0435\u0440\u0435 \u043d\u0430\u0434\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0438 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043c\u043e\u0438\u0445 \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u043d\u0430\u0432\u044b\u043a\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u043c\u0435\u044e\u0442 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f. \u041a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u0442\u0430\u043a\u0438\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432, \u0438\u043b\u0438 \u0442\u043e\u0447\u043d\u0435\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0441\u0432\u043e\u0439 \u043e\u0441\u043e\u0431\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u0421\u0432\u043e\u0434\u0438\u0442\u044c \u0438\u0445 \u0432\u0441\u0435 \u043a \u043e\u0431\u0449\u0435\u043c\u0443 \u0437\u043d\u0430\u043c\u0435\u043d\u0430\u0442\u0435\u043b\u044e \u2014 \u044d\u0442\u043e \u0435\u0449\u0451 \u0431\u043e\u043b\u044c\u0448\u0438\u0439 \u0433\u0435\u043c\u043e\u0440\u0440\u043e\u0439. \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u043f\u043e \u0440\u0435\u043a\u043e\u0440\u0434\u0443 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u2014 \u0433\u0435\u043c\u043e\u0440\u0440\u043e\u0439 \u0442\u0430\u043a\u0438\u0445 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432, \u0447\u0442\u043e \u043d\u0430 \u043d\u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0435\u0441\u0442\u044c \u0438 \u0441\u0432\u0435\u0441\u0438\u0442\u044c \u043d\u043e\u0436\u043a\u0438.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/lb\/ii\/ub\/lbiiub26okpe0pnodusbitney_k.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/lb\/ii\/ub\/lbiiub26okpe0pnodusbitney_k.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/lb\/ii\/ub\/lbiiub26okpe0pnodusbitney_k.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<h3>\u041e\u0431\u043e\u043b\u043e\u0447\u043a\u0438<\/h3>\n<p>\u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u043e\u0442 \u044d\u0442\u043e\u0439 \u0431\u043e\u043b\u044f\u0447\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u0431\u0430\u0432\u0438\u0442\u044c\u0441\u044f \u0437\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0443\u044e \u043f\u043b\u0430\u0442\u0443. \u0412\u044b\u0448\u0435, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043b\u0438\u0441\u044c \u0441 <code>PriorityStack<\/code>, \u044f \u0433\u043e\u0432\u043e\u0440\u0438\u043b, \u0447\u0442\u043e \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u0438 \u0432 \u0442\u0438\u043f\u0430\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u044f\u0432\u043d\u043e. \u0421\u043b\u0435\u0434\u0443\u0435\u0442 \u0437\u0430\u0434\u0430\u0442\u044c\u0441\u044f \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u043c, \u043a\u0430\u043a\u043e\u0439 \u0442\u0438\u043f \u0431\u0443\u0434\u0435\u0442 \u0443 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 <code>value<\/code> (\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <code>Value<\/code>), \u0435\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u0431\u0443\u0434\u0435\u043c \u0435\u0433\u043e \u044f\u0432\u043d\u043e \u043e\u0431\u043e\u0431\u0449\u0438\u0442\u044c?<\/p>\n<pre><code class=\"fsharp\">type Wrapper (value) =      member this.Value = value <\/code><\/pre>\n<p>\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043f\u043e\u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0438\u0437 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0442\u0438\u043f. \u0415\u0441\u043b\u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442, \u0442\u043e <code>value : obj<\/code>. \u041d\u043e \u0435\u0441\u043b\u0438 \u0433\u0434\u0435-\u0442\u043e \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0444\u0430\u0439\u043b\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c <code>Wrapper 42<\/code>, \u0442\u043e <code>value : int<\/code>. \u0410 \u0435\u0441\u043b\u0438 \u0432\u043c\u0435\u0441\u0442\u043e <code>42<\/code> \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0434\u0438\u043c \u043d\u0430\u0448 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0439 \u0440\u0435\u043a\u043e\u0440\u0434, \u0442\u043e <code>Wrapper<\/code> \u0437\u0430\u043f\u043e\u043c\u043d\u0438\u0442 \u0438\u043c\u0435\u043d\u043d\u043e \u0435\u0433\u043e. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0432\u0440\u0430\u043f\u043f\u0435\u0440 \u043f\u043e\u0434 \u043a\u0430\u0436\u0434\u044b\u0439 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0439 \u0440\u0435\u043a\u043e\u0440\u0434:<\/p>\n<pre><code class=\"fsharp\">type PathFound1 (core) =      member this.Core = core  let tryFindPath1 ... =     ...     Ok ^ PathFound1 {|         Path = List.ofSeq path         CostSoFar = costSoFar.AsReadOnly()         CameFrom = cameFrom.AsReadOnly()         Frontier = List.ofSeq ^ frontier.AsSeq()     |} <\/code><\/pre>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>PathFound1<\/code> \u043a\u0430\u043a \u0437\u0430\u043c\u0435\u043d\u0443 \u0440\u0435\u043a\u043e\u0440\u0434\u0430 \u0432 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0430\u0445. \u0412 \u0442\u0435\u043b\u0430\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>Core<\/code>, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043d\u0435\u044d\u0441\u0442\u0435\u0442\u0438\u0447\u043d\u043e, \u043d\u043e \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0434\u0435\u0440\u043d\u0443\u0442\u044c \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e. \u0428\u0430\u0434\u043e\u0432\u0438\u043d\u0433 \u0432 \u043f\u043e\u043c\u043e\u0449\u044c.<\/p>\n<p>\u0412\u0430\u0436\u043d\u043e, \u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>tryFindPath<\/code> \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0431\u043e\u043b\u043e\u0447\u043a\u0443 \u0432 \u0441\u0432\u043e\u0451\u043c \u0442\u0435\u043b\u0435. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0451 \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0437\u0434\u043d\u0435\u043c \u044d\u0442\u0430\u043f\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0441\u0446\u0435\u043d\u0435:<\/p>\n<pre><code class=\"fsharp\">module MyScene  type PathFound (core) =     member this.Core = core  let tryFindPath ... =     PathFinder.tryFindPath ...     |&gt; Result.map PathFound <\/code><\/pre>\n<p>\u0412 \u044d\u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0441\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u0443\u0436\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b, \u0442\u0430\u043a \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u0438\u0445, \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u0435\u043d\u044f\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b. <code>PathFound<\/code> \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043b\u043e\u0432\u0438\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u0438 \u0434\u0430\u043b\u044c\u0448\u0435 \u043e\u043d\u0438 \u043a\u0430\u0441\u043a\u0430\u0434\u043e\u043c \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043f\u043e \u0432\u0441\u0435\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u043c. \u0415\u0441\u043b\u0438 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0435 \u0440\u0435\u043a\u043e\u0440\u0434\u044b \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445 \u0440\u0430\u0437\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f, \u0442\u043e \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443 \u0432 \u0442\u043e\u0447\u043a\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f, \u0442\u043e \u0435\u0441\u0442\u044c \u0440\u043e\u0432\u043d\u043e \u0442\u0430\u043c, \u0433\u0434\u0435 \u0435\u0451 \u0438 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0432\u0438\u0434\u0435\u0442\u044c.<\/p>\n<p>\u0411\u043e\u044f\u0442\u044c\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0447\u0438\u0441\u043b\u0430 \u043f\u0440\u0430\u0432\u043e\u043a \u043d\u0435 \u043d\u0443\u0436\u043d\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u043c\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0443\u0431\u0440\u0430\u0442\u044c \u0432 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f <code>PathFound<\/code>. \u0422\u0443\u0434\u0430 \u0436\u0435 \u0441\u0442\u043e\u0438\u0442 \u0437\u0430\u043f\u0438\u0445\u0438\u0432\u0430\u0442\u044c \u0438 \u043d\u0435\u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u043c\u044b\u0435, \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c\u044b \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0432\u0435\u0440\u0441\u0438\u0439. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u043c\u043e\u0436\u043d\u043e \u0438\u0442\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u044f\u043c\u043e \u043f\u043e <code>Core.CostSoFar<\/code>, \u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u043e \u043f\u0440\u043e\u0435\u043a\u0446\u0438\u0438 <code>PathFound.Costs : (Vector2I * int) seq<\/code>. \u0412\u0442\u043e\u0440\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0438\u0442\u0435\u043b\u044c\u043d\u0435\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u0432 \u043d\u0451\u043c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044f\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0440\u0435\u043a\u043e\u0440\u0434\u0430 \u043d\u0435 \u043f\u0440\u043e\u0442\u0435\u043a\u0430\u0435\u0442 \u0432 \u043a\u043e\u0434 \u0440\u0435\u043d\u0434\u0435\u0440\u0430.<\/p>\n<p>\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043e\u0431\u043e\u043b\u043e\u0447\u043a\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u0440\u0430\u0449\u0438\u0432\u0430\u0442\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0435\u0431\u044f, \u043d\u043e \u0438 \u044f\u0434\u0440\u043e. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0442\u0443\u0434\u0430 \u043b\u044e\u0431\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0432\u0430\u0436\u043d\u0443\u044e \u0434\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u043a\u043e\u0440\u0430\u0431\u043b\u0435\u0439 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438 \u0443 \u043d\u0438\u0445 \u0440\u0430\u0437\u043d\u044b\u0439 <code>Material<\/code> \u0441\u0442\u0440\u0435\u043b\u043e\u0447\u0435\u043a, \u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043a\u0438\u043d\u0443\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043a\u043e\u0440\u0430\u0431\u043b\u044c \u043f\u0440\u044f\u043c\u043e \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439:<\/p>\n<pre><code class=\"fsharp\">let tryFindPath spaceShip ... =     PathFinder.tryFindPath ...     |&gt; Result.map ^ fun p -&gt;          PathFound {| p with SpaceShip = spaceShip |} <\/code><\/pre>\n<p>\u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u044f \u0432\u0435\u0434\u0443 \u0440\u0435\u0447\u044c \u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043c\u043e\u0436\u0435\u0442 \u044d\u0442\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f. \u041d\u0435 \u043d\u0430\u0434\u043e \u043f\u0438\u0447\u043a\u0430\u0442\u044c \u0430\u043d\u043e\u043d\u0438\u043c\u043a\u0443 \u0432\u0445\u043e\u0434\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 \u0437\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a.<\/p>\n<p>\u041e\u0431\u043e\u043b\u043e\u0447\u043a\u0430, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u0430\u044f \u0431\u043b\u0438\u0437\u043a\u043e \u043a \u0442\u043e\u0447\u043a\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f, \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0451\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0431\u043e\u0447\u043d\u044b\u043c \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u043c \u043a\u043e\u043c\u043c\u0443\u043d\u0438\u043a\u0430\u0446\u0438\u0438 \u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u0440\u043e\u0441\u0442\u0430. \u041e\u043d\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u0442 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439, \u043d\u043e \u0447\u0440\u0435\u0437\u0432\u044b\u0447\u0430\u0439\u043d\u043e <strong>\u043f\u043b\u0430\u0441\u0442\u0438\u0447\u043d\u044b\u0439<\/strong> \u0442\u0438\u043f \u0441 \u043e\u0447\u0435\u043d\u044c \u0441\u0442\u0440\u0430\u043d\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u043e\u0439 \u0440\u0430\u0437\u0432\u0451\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u044f. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043e\u043d\u0430 \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0430\u043c\u043e\u0440\u0444\u043d\u043e\u0441\u0442\u044c, \u0442\u0430\u043a \u043a\u0430\u043a \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 (\u0438\u043b\u0438 \u0441\u043a\u043e\u0443\u043f\u0430) \u0438\u0437 \u043e\u0434\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432 \u0434\u0440\u0443\u0433\u0443\u044e. \u0423\u0432\u0435\u0440\u0435\u043d, \u0447\u0442\u043e \u044d\u0442\u0430 \u0448\u0442\u0443\u043a\u0430 \u043d\u0430 UML-\u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430\u0445 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043a\u0430\u043a \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u043d\u0435\u0434\u043e\u0440\u0430\u0437\u0443\u043c\u0435\u043d\u0438\u0435, \u0442\u0430\u043a \u0447\u0442\u043e \u044f \u0431\u044b \u0432\u0441\u0442\u0440\u044f\u043b, \u0435\u0441\u043b\u0438 \u0431\u044b \u043c\u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0437\u0430\u0449\u0438\u0449\u0430\u0442\u044c \u0435\u0451 \u043f\u0435\u0440\u0435\u0434 \u043a\u0435\u043c-\u0442\u043e, \u043a\u0442\u043e \u0434\u0430\u043b\u0451\u043a \u043e\u0442 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e F#. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0441\u043b\u0438 \u0432\u044b \u043d\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u0443\u0435\u0442\u0435 \u0441\u0432\u043e\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u0431\u0443\u0434\u044c\u0442\u0435 \u0433\u043e\u0442\u043e\u0432\u044b \u043f\u0438\u0441\u0430\u0442\u044c \u0432\u0441\u0451 \u043f\u043e \u0441\u0442\u0430\u0440\u0438\u043d\u043a\u0435. \u0412\u044b \u0441\u0435\u0440\u044c\u0451\u0437\u043d\u043e \u043f\u043e\u0442\u0435\u0440\u044f\u0435\u0442\u0435 \u0432 \u043d\u0430\u0434\u0451\u0436\u043d\u043e\u0441\u0442\u0438 \u0438 \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0435, \u043d\u043e \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0444\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0445 \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u0435\u0432 \u0432\u0441\u0451 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0448\u0438\u0431\u0438\u0441\u044c.<\/p>\n<h3>\u041f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0435 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0412\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0433\u043b\u0430\u0432\u0435 \u044f \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b, \u0447\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0434\u0443 \u043d\u0430\u0441 \u043e\u0442 \u043e\u0431\u044b\u0447\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043e \u0437\u0430\u0440\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u041e\u041e\u041f \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u043f\u0443\u0442\u0451\u043c. \u0415\u0441\u043b\u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u043a \u0442\u043e\u0439 \u043f\u0440\u0438\u0437\u043c\u0435, \u0442\u043e \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u043b\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u043b\u0430 \u0441\u0432\u043e\u0439 \u043f\u0435\u0440\u0432\u044b\u0439 \u0442\u0438\u043f, \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 \u043e\u0442 \u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e. \u042d\u0442\u043e\u0442 \u0442\u0438\u043f \u043d\u0443\u0436\u0435\u043d \u043d\u0430\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u044f\u043a\u043e\u0440\u044f, \u043d\u0443 \u0438\u043b\u0438 \u0447\u0435\u043a\u043f\u043e\u0438\u043d\u0442\u0430, \u0435\u0441\u043b\u0438 \u0432 \u0438\u0433\u0440\u043e\u0432\u044b\u0445 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f\u0445. \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0435\u0433\u043e \u043a\u0430\u043a \u0443\u0434\u043e\u0431\u043d\u0443\u044e \u0442\u043e\u0447\u043a\u0443, \u0437\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0446\u0435\u043f\u0438\u0442\u044c\u0441\u044f \u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u044d\u043a\u0441\u043f\u0430\u043d\u0441\u0438\u044e \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<p>\u041f\u043e\u0434\u043e\u0437\u0440\u0435\u0432\u0430\u044e, \u0447\u0442\u043e \u0438\u0437 \u0432\u0441\u0435\u0445 \u0437\u0430\u0434\u0430\u0447, \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0440\u0430\u0432\u0434\u0430\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043b\u0430\u0441\u0441\u0430, \u044d\u0442\u0430 \u0441\u0430\u043c\u0430\u044f \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0430\u044f. \u0418, \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043d\u0430 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u0432 \u0444\u043e\u043a\u0443\u0441 \u00ab\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f\u00bb. \u041f\u0440\u043e\u043f\u0430\u0433\u0430\u043d\u0434\u0438\u0441\u0442\u0441\u043a\u0438\u0435 \u0443\u0441\u0438\u043b\u0438\u044f F#-\u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430 \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0435\u043d\u044b \u043d\u0430 \u0441\u0430\u043c\u043e\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u044b\u0445 \u0442\u0438\u043f\u0430\u0445, \u0441\u043c\u044b\u0441\u043b \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u043e\u0436\u043d\u043e \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u043c\u0443 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u0435\u043b\u044e. \u041f\u0440\u0438\u0447\u0438\u043d\u044b \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u043f\u043e\u043d\u044f\u0442\u043d\u044b, \u043d\u0430\u0434\u043e \u0440\u0430\u0437\u0433\u043e\u0432\u0430\u0440\u0438\u0432\u0430\u0442\u044c \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u0438. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u0442\u043e\u0436\u0435 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u0430, \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f <a href=\"https:\/\/habr.com\/ru\/articles\/881272\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0447\u0435\u0440\u0435\u0437 \u0442\u0438\u043f\u044b<\/a> \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u043d\u0435\u043e\u0444\u0438\u0442\u043e\u0432 \u0441 \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u044b\u043c (\u0445\u043e\u0442\u044f \u0438 \u043d\u0435 \u0432\u043e \u0432\u0441\u0451\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u043c) \u043d\u0430\u0431\u043e\u0440\u043e\u043c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043e\u043a.<\/p>\n<p>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u0441\u0442\u0430\u0434\u0438\u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0432\u043d\u044f\u0442\u043d\u044b\u0445 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439 \u0435\u0449\u0451 \u043d\u0435\u0442. \u0415\u0441\u0442\u044c \u043b\u0438\u0448\u044c \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 \u0431\u0443\u043b\u044c\u043e\u043d, \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043d\u0430\u0449\u0443\u043f\u0430\u0442\u044c \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u0431\u0443\u0434\u0443\u0449\u0438\u0445 \u0442\u0438\u043f\u043e\u0432. \u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438\u0433\u0440\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u043d\u0435\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0432\u0448\u0438\u0445\u0441\u044f \u0434\u043e\u043c\u0435\u043d\u043e\u0432, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0443\u0436\u0435\u043d \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u043d\u0435 \u0442\u0430\u043a\u0438\u0445 \u0447\u0438\u0441\u0442\u044b\u0445, \u043c\u0435\u0441\u0442\u0430\u043c\u0438 \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u0445, \u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0433\u0438\u0431\u043a\u0438\u0445 \u0438 \u0434\u0435\u0448\u0451\u0432\u044b\u0445. \u0412 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u043f\u043b\u0430\u043d\u0435 \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u043d\u0430\u0434\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0430\u043a\u0446\u0435\u043d\u0442 \u043d\u0435 \u043d\u0430 \u0442\u0438\u043f\u0430\u0445, \u0430 \u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445 (\u0438 \u0425\u041c). \u041f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435 \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043c\u044b \u043d\u0435 \u0443\u043f\u0440\u0451\u043c\u0441\u044f \u0432 \u043f\u0440\u0435\u0434\u0435\u043b \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0440\u0430\u0437 \u043c\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u043e\u0431\u043e\u043b\u043e\u0447\u043a\u0430\u043c\u0438. \u0423\u043b\u0443\u0447\u0448\u0438\u043c \u0438\u0445 \u0444\u043e\u0440\u043c\u0443, \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u043c \u043e\u0431\u044a\u0451\u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0438 \u043f\u043e\u0447\u0442\u0438 \u0434\u043e\u0439\u0434\u0451\u043c \u0434\u043e \u0442\u0438\u043f\u043e\u0432 \u0432 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u043e\u043c \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0438 \u0441\u043b\u043e\u0432\u0430.<\/p>\n<hr\/>\n<p>\u041d\u041b\u041e \u043f\u0440\u0438\u043b\u0435\u0442\u0435\u043b\u043e \u0438 \u043e\u0441\u0442\u0430\u0432\u0438\u043b\u043e \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u043c\u043e\u043a\u043e\u0434 \u0434\u043b\u044f \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0435\u0439 \u043d\u0430\u0448\u0435\u0433\u043e \u0431\u043b\u043e\u0433\u0430:<br \/> <a href=\"https:\/\/firstvds.ru\/?utm_source=habr&amp;utm_medium=article&amp;utm_campaign=product&amp;utm_content=vds15exeptprogrev\" rel=\"noopener noreferrer nofollow\">-15% \u043d\u0430 \u0437\u0430\u043a\u0430\u0437 \u043b\u044e\u0431\u043e\u0433\u043e VDS<\/a> (\u043a\u0440\u043e\u043c\u0435 \u0442\u0430\u0440\u0438\u0444\u0430 \u041f\u0440\u043e\u0433\u0440\u0435\u0432) \u2014 <strong>HABRFIRSTVDS<\/strong>.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/917404\/\"> https:\/\/habr.com\/ru\/articles\/917404\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"\"><\/figure>\n<p>\u041a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u043b\u0430\u0441\u044c \u0441 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0430 <a href=\"https:\/\/habr.com\/ru\/articles\/554960\/\" rel=\"noopener noreferrer nofollow\">\u0442\u0430\u0439\u043b\u043e\u0432\u044b\u0445 \u043c\u0438\u0440\u043e\u0432<\/a> \u043d\u0430 F#. \u041e\u0434\u043d\u0430\u043a\u043e \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0435\u0433\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u044f \u043e\u0441\u043d\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0441\u0442\u0451\u043a\u0441\u044f \u043f\u043e \u0434\u0440\u0435\u0432\u0443, \u0437\u0430 \u0441\u0447\u0451\u0442 \u0447\u0435\u0433\u043e \u0443 \u043d\u0430\u0441 \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u044d\u0442\u0430\u043f \u0438\u0437 \u043f\u044f\u0442\u0438 \u0433\u043b\u0430\u0432 \u043f\u0440\u043e \u044f\u0437\u044b\u043a\u043e\u0432\u044b\u0435 \u0444\u0438\u0447\u0438 \u0438 \u043f\u0440\u043e\u0447\u0443\u044e \u00ab\u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442\u0430\u043b\u043e\u0447\u043a\u0443\u00bb. \u0414\u0443\u043c\u0430\u044e, \u0447\u0442\u043e \u0441 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u043e\u0439 <a href=\"https:\/\/habr.com\/ru\/companies\/first\/articles\/909536\/\" rel=\"noopener noreferrer nofollow\">\u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043e<\/a>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b \u043e\u0431\u0440\u0430\u0442\u0438\u043c\u0441\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043a \u0442\u0430\u0439\u043b\u043e\u0432\u044b\u043c \u043c\u0438\u0440\u0430\u043c.<\/p>\n<p>\u041d\u043e \u043d\u0430\u0447\u043d\u0451\u043c \u043c\u044b \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441 \u043a\u043e\u043d\u0446\u0430 \u2014 \u0441 \u0430\u0434\u0430\u043f\u0442\u0430\u0446\u0438\u0438 \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438. \u042d\u0442\u043e \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u043a\u0430, \u043d\u043e \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0435\u0451 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043c\u044b \u0443\u0441\u043f\u0435\u0435\u043c \u0437\u0430\u043a\u0440\u0435\u043f\u0438\u0442\u044c \u043f\u0440\u043e\u0439\u0434\u0435\u043d\u043d\u044b\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u0438 \u043f\u043e \u0438\u043d\u0435\u0440\u0446\u0438\u0438 \u0437\u0430\u0441\u043a\u043e\u0447\u0438\u0442\u044c \u0432 \u043d\u043e\u0432\u044b\u0439.<\/p>\n<p>\u042d\u0442\u0430 \u0433\u043b\u0430\u0432\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u00ab\u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043d\u044b\u043c \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u043c\u00bb. \u0415\u0451 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043e\u0431\u0440\u0443\u0431\u0438\u0442\u044c \u0438\u0437-\u0437\u0430 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u0438\u044f \u0443\u0434\u043e\u0431\u043e\u0432\u0430\u0440\u0438\u043c\u044b\u0445 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432. \u041e\u0447\u0435\u0440\u0447\u0438\u0432\u0430\u0442\u044c \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u0442\u0435\u043c\u044b \u0432 \u0442\u0430\u043a\u0438\u0445 \u0442\u0435\u043a\u0441\u0442\u0430\u0445 \u0441\u043b\u043e\u0436\u043d\u043e, \u043d\u043e \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0434\u043e\u043b\u0435\u0439 \u0443\u0441\u043b\u043e\u0432\u043d\u043e\u0441\u0442\u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u043f\u043e \u0438\u0442\u043e\u0433\u0443 \u0432 \u044d\u0442\u043e\u0439 \u0433\u043b\u0430\u0432\u0435 \u043c\u044b \u043d\u0430\u0443\u0447\u0438\u043c\u0441\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043b\u044e\u0431\u0443\u044e \u0445\u0442\u043e\u043d\u044c. \u0417\u0430\u0447\u0435\u043c \u043e\u043d\u0430 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u043b\u0430\u0441\u044c, \u043d\u0430\u0447\u043d\u0451\u043c \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u0442\u044c \u0432 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437, \u0430 \u0447\u0442\u043e \u0441 \u043d\u0435\u0439 \u0434\u0435\u043b\u0430\u0442\u044c \u0434\u0430\u043b\u044c\u0448\u0435, \u0432\u044b\u044f\u0441\u043d\u0438\u043c \u043f\u043e\u0437\u0434\u043d\u0435\u0435.<\/p>\n<h3>\u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0435\u0440\u0435\u043d\u043e\u0441 \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438<\/h3>\n<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 <a href=\"https:\/\/habr.com\/ru\/articles\/554960\/\" rel=\"noopener noreferrer nofollow\">\u041f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u044b\u0435 \u0442\u0430\u0439\u043b\u043e\u0432\u044b\u0435 \u043c\u0438\u0440\u044b<\/a> \u0434\u0430\u043d \u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438 \u0447\u0435\u0440\u0435\u0437 <code>A*<\/code> (\u043f\u043e-\u0440\u0443\u0441\u0441\u043a\u0438 \u00ab\u0430\u0441\u0442\u0430\u0440\u00bb). \u042d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c, \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043c\u0435\u043d\u044f \u0443\u0447\u0438\u043b\u0438 \u0435\u0449\u0451 \u0432 \u0448\u043a\u043e\u043b\u0435, \u043d\u043e \u0435\u0433\u043e \u043b\u0435\u0433\u043a\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u0443\u0441\u043b\u043e\u0436\u043d\u0438\u0442\u044c \u043f\u043e\u0434 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438. \u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0434\u0430\u0451\u0442\u0441\u044f \u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0435\u0433\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u043b \u0441 GDScript \u043d\u0430 F#, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u043b \u043f\u043e\u0434 \u0441\u0432\u043e\u0438 \u0438\u0433\u0440\u043e\u0432\u044b\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0438.<\/p>\n<p>\u041c\u044b \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u0435\u043c \u043f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0442\u043e\u0442 \u0436\u0435 \u043f\u0443\u0442\u044c, \u043d\u043e \u0432\u043c\u0435\u0441\u0442\u043e \u043c\u0435\u0445\u0430\u043d\u0438\u043a \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0438\u043c\u0441\u044f \u043d\u0430 \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u0412 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0435 3 \u0431\u043b\u043e\u043a\u0430: \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u043b\u043a\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 <code>PriorityStack<\/code> \u0438, \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0441\u0430\u043c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043f\u043e\u0438\u0441\u043a\u0430. \u041f\u0440\u0438\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b \u0435\u0441\u0442\u044c \u0432\u043e \u0432\u0441\u0435\u0445 \u0431\u043b\u043e\u043a\u0430\u0445, \u043d\u043e \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044f \u0441\u044e\u0436\u0435\u0442\u0430 \u0432\u0430\u0436\u043d\u0435\u0435 \u0432\u0441\u0435\u0445 \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u0438\u0441\u043a. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u0443\u0442 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0434\u0438\u0442\u044c, \u0447\u0442\u043e \u043c\u044b \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0441\u043c\u044b\u0441\u043b\u0435 \u0431\u0443\u0434\u0435\u043c \u0438\u0437\u043e\u0431\u0440\u0435\u0442\u0430\u0442\u044c \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434, \u0438\u0431\u043e \u0432 Godot \u0435\u0441\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0435 <code>AStar2D<\/code>, <code>AStarGrid2D<\/code> \u0438 \u0447\u0442\u043e-\u0442\u043e \u0435\u0449\u0451 \u0434\u043b\u044f 3D. \u042f \u0438\u043c\u0438 \u0442\u0430\u043a \u0438 \u043d\u0435 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f, \u043d\u043e \u043e\u043d\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0441 \u043e\u0431\u044b\u0447\u043d\u044b\u043c\u0438 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f\u043c\u0438. \u0427\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 (\u043a\u0430\u043a \u0443 \u043c\u0435\u043d\u044f), \u0442\u043e \u044f \u0441\u0447\u0451\u043b \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c<s>\u0441\u044f<\/s> \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u043f\u043e\u0434 \u043d\u0438\u0445.<\/p>\n<h4>\u0412\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/h4>\n<p>\u0411\u043e\u043b\u044c\u0448\u0435 \u0432\u0441\u0435\u0433\u043e \u043d\u0430 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445 \u0441\u043a\u0430\u0437\u0430\u043b\u0430\u0441\u044c \u0437\u0430\u043c\u0435\u043d\u0430 \u0441\u0430\u043c\u043e\u043b\u0435\u043f\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u0447\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u0442\u0438\u043f\u044b. \u041f\u0435\u0440\u0435\u043d\u043e\u0441 \u043d\u0430 F# \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b, \u043d\u043e \u044f \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u0438\u043c \u043a\u0430\u043a \u043f\u043e\u0432\u043e\u0434\u043e\u043c. \u0423 \u043c\u0435\u043d\u044f \u0438\u0441\u0447\u0435\u0437\u0430\u044e\u0449\u0435 \u0440\u0435\u0434\u043a\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0432\u0435\u0440\u0448\u0430\u0442\u044c \u00ab\u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438\u00bb. \u0415\u0441\u043b\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0447\u0443\u0436\u0438\u0435 \u0431\u0430\u0433\u0438, \u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0443 \u043c\u0435\u043d\u044f \u043e\u0442\u043d\u0438\u043c\u0430\u0435\u0442 \u043a\u0430\u043a\u0430\u044f-\u043d\u0438\u0431\u0443\u0434\u044c \u0444\u0438\u0433\u043d\u044f, \u0442\u0438\u043f\u0430 \u0438\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e <code>bool<\/code>, \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u043e\u0433\u043e <code>&gt;<\/code> \u0432\u043c\u0435\u0441\u0442\u043e <code>&gt;=<\/code> \u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0447\u0451\u0442\u0430 \u043d\u0430 1. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043f\u043e\u0431\u0430\u0438\u0432\u0430\u044e\u0441\u044c \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434 \u0442\u0430\u043a:<\/p>\n<pre><code>func in_map(grid_pos:Vector2, map_size:Vector2) -&gt; bool: return grid_pos.x &lt; map_size.x and grid_pos.x &gt;= 0 and grid_pos.y &gt;= 0 and grid_pos.y &lt; map_size.y <\/code><\/pre>\n<p>\u0410 \u043d\u0435 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"fsharp\">let inMap mapSize pos =     Rect2I(Vector2I.Zero, mapSize).HasPoint pos <\/code><\/pre>\n<p>\u0421\u0443\u0434\u044f \u043f\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0443 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u043e\u0432, \u0432 Godot-\u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0435 \u043d\u0438\u043a\u0442\u043e \u0442\u0430\u043a\u0438\u0445 \u0441\u0442\u0440\u0430\u0445\u043e\u0432 \u043d\u0435 \u0438\u0441\u043f\u044b\u0442\u044b\u0432\u0430\u0435\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u0430\u043c \u043f\u0440\u043e\u0446\u0432\u0435\u0442\u0430\u0435\u0442 \u044d\u0442\u0430\u043a\u0438\u0439 BCL-\u043d\u0438\u0433\u0438\u043b\u0438\u0437\u043c. \u0421 \u044d\u0442\u0438\u043c \u043d\u0430\u0434\u043e \u0447\u0442\u043e-\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u0438\u0431\u043e \u044f \u0443\u0436\u0435 <s>\u0431\u043e\u043b\u044c\u0448\u0435 \u0433\u043e\u0434\u0430<\/s> \u043f\u043e\u0447\u0442\u0438 \u043f\u043e\u043b\u0442\u043e\u0440\u0430 \u0433\u043e\u0434\u0430 \u043a\u043e\u0432\u044b\u0440\u044f\u044e\u0441\u044c \u0432 \u0434\u0432\u0438\u0436\u043a\u0435, \u043d\u043e \u0442\u0430\u043a \u0438 \u043d\u0435 \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u043b \u0430\u0432\u0442\u043e\u0440\u0430, \u043a\u043e\u0434 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0431\u043b\u0438\u0437\u043a\u0438\u043c \u043a \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u0447\u043d\u043e\u043c\u0443 \u043f\u0440\u0435\u0434\u0435\u043b\u0443. \u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u044f \u0447\u0443\u0432\u0441\u0442\u0432\u0443\u044e \u0441\u0435\u0431\u044f \u0434\u0438\u0441\u043a\u043e\u043c\u0444\u043e\u0440\u0442\u043d\u043e, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u0435\u0434\u044a\u044f\u0432\u043b\u044f\u044e \u043f\u0440\u0435\u0442\u0435\u043d\u0437\u0438\u0438 \u043a \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434\u0430\u043c \u0432\u043d\u0443\u0442\u0440\u0438 \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434\u0430.<\/p>\n<hr\/>\n<p>\u042f \u043f\u043e\u043c\u0435\u043d\u044f\u043b \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u044b\u0439 <code>Vector2<\/code> \u043d\u0430 \u0434\u0438\u0441\u043a\u0440\u0435\u0442\u043d\u044b\u0439 <code>Vector2I<\/code> \u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u043b \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u0414\u043b\u044f \u0443\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u043a\u0430\u0440\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u043b\u0441\u044f \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0440\u0430\u043d\u044c\u0448\u0435 \u0432\u0441\u0435\u0445. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u043e\u043b\u044f \u0438\u0434\u0451\u0442 \u043f\u0435\u0440\u0432\u044b\u043c, \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u043e\u043b\u044f (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f) \u2014 \u0432\u0442\u043e\u0440\u044b\u043c, \u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 (\u043a\u043b\u0435\u0442\u043a\u0430 \u043f\u043e\u043b\u044f) \u2014 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c.<\/p>\n<pre><code>func can_stand(grid_pos:Vector2, obsts:PoolVector2Array, map_size:Vector2) -&gt; bool: return not (grid_pos in obsts) and in_map(grid_pos, map_size) <\/code><\/pre>\n<pre><code class=\"fsharp\">let canStand mapSize isObstacle pos =     inMap mapSize pos     &amp;&amp; not ^ isObstacle pos <\/code><\/pre>\n<p>\u041a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f <code>obsts<\/code> \u0432 F# \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043b\u0430 \u0431\u044b\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c \u0438 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b\u0430\u0441\u044c \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e-\u043f\u0440\u0435\u0434\u0438\u043a\u0430\u0442. \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043e \u0434\u0430\u043d\u043d\u044b\u0445 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043c\u0435\u043d\u044c\u0448\u0435, \u0447\u0435\u043c \u00ab\u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439\u00bb \u0442\u0438\u043f, \u043d\u043e \u0442\u0430\u043a\u0443\u044e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043f\u0440\u043e\u0449\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c. \u0427\u0438\u0441\u0442\u043e \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0432\u0437\u044f\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>IReadOnlySet<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u0438 \u0434\u043e\u0442\u043d\u0435\u0442\u043e\u0432\u0441\u043a\u0438\u043c <code>HashSet<\/code>, \u0438 F#-\u0441\u043a\u0438\u043c <code>Set<\/code>, \u0447\u0442\u043e \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b\u043e \u0431\u044b \u043d\u0430\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u0435, \u0442\u0430\u043a \u0438 \u0438\u043c\u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438. \u041e\u0434\u043d\u0430\u043a\u043e \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u043c\u0441\u044f \u0441 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f\u043c\u0438 <code>Set&lt;'a when 'a : comparion&gt;<\/code>. \u042d\u0442\u0430 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f \u0442\u0440\u0435\u0431\u0443\u0435\u0442, \u0447\u0442\u043e\u0431\u044b \u0442\u0438\u043f <code>'a<\/code> \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u043b \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 (\u0431\u043e\u043b\u044c\u0448\u0435, \u043c\u0435\u043d\u044c\u0448\u0435 \u0438 \u0442. \u0434.), \u0432 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a <code>Vector2I<\/code> \u0432 Godot \u044d\u0442\u0438\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e\u043c \u043d\u0435 \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442.<\/p>\n<p>\u041d\u0430\u0434\u043e \u043b\u0438\u0431\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0443\u044e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e (\u0438\u0437 <code>System.Collections.Immutable<\/code> \u0438\u043b\u0438 <code>FSharpx.Collections<\/code>), \u043b\u0438\u0431\u043e \u0432\u0437\u044f\u0442\u044c <code>Set&lt;int * int&gt;<\/code> \u0438 \u0441\u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 <code>Vector2I IReadOnlySet<\/code>. \u0417\u0430\u0434\u0430\u0447\u0430 \u0440\u0435\u0448\u0430\u0435\u043c\u0430, \u043d\u043e \u0432\u043e\u043e\u0431\u0449\u0435-\u0442\u043e \u0432 \u043d\u0435\u0434\u0440\u0430\u0445 <code>canStand<\/code> \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u043c\u0435\u0442\u043e\u0434 (<code>Contains<\/code>), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 <code>Set<\/code> \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c:<\/p>\n<pre><code class=\"fsharp\">interface IReadOnlySet&lt;Vector2I&gt; with     override this.Contains pos =          (obstacles : _ Set).Contains(pos.X, pos.Y)     ...     \/\/ \u0415\u0449\u0451 6 override \u0432 \u044d\u0442\u043e\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 \u0438 3 \u0432 \u043f\u0440\u0435\u0434\u043a\u0430\u0445 <\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 9 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c (\u0438\u043b\u0438 \u0438\u043c\u0438\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c) \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0437-\u0437\u0430 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043a\u043e\u043c\u0443-\u0442\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u044d\u0441\u0442\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u043c \u0432\u044b\u0440\u0430\u0437\u0438\u0442\u044c <code>obsts<\/code> \u0447\u0435\u0440\u0435\u0437 \u00ab\u043e\u0431\u0449\u0435\u043f\u0440\u0438\u043d\u044f\u0442\u044b\u0439\u00bb \u0442\u0438\u043f.<\/p>\n<hr\/>\n<p>\u0412\u0441\u0435 \u0448\u0430\u0433\u0438 \u043d\u0430 \u0435\u0434\u0438\u043d\u0438\u0446\u0443 \u0432\u043f\u0440\u0430\u0432\u043e, \u0432\u043b\u0435\u0432\u043e \u0438 \u0442. \u0434. \u0438\u043c\u0435\u044e\u0442 \u043e\u0434\u043d\u043e\u0438\u043c\u0451\u043d\u043d\u044b\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0432 \u043a\u043b\u0430\u0441\u0441\u0430\u0445, \u043d\u043e \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u043e \u043d\u0438\u0445 \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442:<\/p>\n<pre><code>func neighbors(grid_pos:Vector2,  obsts:PoolVector2Array, map_size:Vector2) -&gt; PoolVector2Array: var res:PoolVector2Array = [] var _neighbors = PoolVector2Array([grid_pos+Vector2(-1, 0), grid_pos+Vector2(1, 0),  grid_pos+Vector2(0, -1), grid_pos+Vector2(0, 1)]) for neigh in _neighbors: if can_stand(neigh, obsts, map_size): res.append(neigh) return res <\/code><\/pre>\n<pre><code class=\"fsharp\">let neighbours mapSize isObstacle pos =     [         Vector2I.Left         Vector2I.Right         Vector2I.Up         Vector2I.Down     ]     |&gt; Seq.map ^ fun p -&gt; p + pos     |&gt; Seq.filter ^ canStand mapSize isObstacle <\/code><\/pre>\n<hr\/>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043d\u0435 \u043d\u0430\u0434\u043e \u0437\u0430\u0431\u044b\u0432\u0430\u0442\u044c, \u043f\u0440\u043e \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438:<\/p>\n<pre><code>func heuristic(a:Vector2, b:Vector2) -&gt; int: return int(abs(a.x-b.x)+abs(a.y-b.y)) <\/code><\/pre>\n<pre><code class=\"fsharp\">let heuristic (a : Vector2I) b =     let xy = (a - b).Abs()     xy.X + xy.Y <\/code><\/pre>\n<h4>PriorityStack<\/h4>\n<p>\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a:<\/p>\n<pre><code>class PriorityStack:  var items:Array  func _init(): items = Array()  func empty() -&gt; bool: return items.size() == 0  func put(item, priority:int) -&gt; void: if empty(): items.append([item, priority]) elif priority &lt;= items[0][1]: items.insert(0, [item, priority]) elif priority &gt; items[-1][1]: items.append([item, priority]) else: for i in range(len(items)): if priority &lt;= items[i][1]: items.insert(i, [item, priority]) break  func take(): # \"get\" name already taken by Variant return items.pop_front()[0] <\/code><\/pre>\n<p>\u0412 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 <code>PriorityStack<\/code> \u2014 \u044d\u0442\u043e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f \u0442\u043e\u0447\u0435\u043a (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 <code>Vector2I<\/code>), \u0443\u043f\u043e\u0440\u044f\u0434\u043e\u0447\u0435\u043d\u043d\u044b\u0445 \u043f\u043e \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0443 (<code>int<\/code>). \u0412\u0430\u0436\u043d\u043e, \u0447\u0442\u043e \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u044b \u0442\u043e\u0447\u0435\u043a \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0442\u044c \u0438 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043a\u043b\u044e\u0447\u0430\u043c\u0438. \u0422\u0430\u043a\u0436\u0435 \u0432\u0430\u0436\u043d\u043e, \u0447\u0442\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438 \u043d\u0435 \u043d\u0443\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u043a \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438. \u041e\u043d \u0432\u0441\u0435\u0433\u0434\u0430 \u0437\u0430\u0431\u0438\u0440\u0430\u0435\u0442 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0441 \u0441\u0430\u043c\u044b\u043c \u043d\u0438\u0437\u043a\u0438\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u043e\u043c (\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0433\u043e\u043b\u043e\u0432\u0435 \u0441\u043f\u0438\u0441\u043a\u0430).<\/p>\n<p>\u0412 dotnet \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0445\u043e\u0436\u0438\u043c \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u043c \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 <code>PriorityQueue&lt;Vector2I, int&gt;<\/code>, \u043d\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u043d\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u0435\u043d \u0441\u0442\u0435\u043a\u0443. \u0417\u0430\u0442\u044b\u043a \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u0443\u043a\u043b\u0430\u0434\u043a\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0441 \u043e\u0434\u043d\u0438\u043c \u0438 \u0442\u0435\u043c \u0436\u0435 \u0443\u0440\u043e\u0432\u043d\u0435\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0430. <code>PriorityStack<\/code> \u043f\u0440\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u0432\u044b\u0434\u0430\u0441\u0442 \u0441\u0430\u043c\u043e\u0433\u043e \u0441\u0432\u0435\u0436\u0435\u0433\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u0430, \u0430 <code>PriorityQueue<\/code> \u043a\u043e\u0433\u043e-\u0442\u043e \u00ab\u0438\u0437\u00bb. \u041a\u043e\u0433\u043e \u0442\u043e\u0447\u043d\u043e \u043d\u0435 \u0437\u043d\u0430\u044e, \u043d\u043e \u0442\u0430\u043c \u043d\u0435 \u0440\u0430\u043d\u0434\u043e\u043c, \u043d\u0435 <code>FIFO<\/code> \u0438 \u043d\u0435 <code>LIFO<\/code>.<\/p>\n<details class=\"spoiler\">\n<summary>\u0427\u0443\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u0438\u043a\u0438 \u043f\u043e `PriorityQueue`<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0426\u0438\u0442\u0430\u0442\u0430 \u0438\u0437 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438:<\/p>\n<blockquote>\n<p><code>Note that the type does not guarantee first-in-first-out semantics for elements of equal priority.<\/code><\/p>\n<\/blockquote>\n<pre><code class=\"fsharp\">property {     let! items =         Range.constant 1 10         |&gt; Gen.int32         |&gt; Gen.list ^ Range.constant 2 10         |&gt; Gen.map ^ List.mapi ^ fun index priority -&gt; priority, index     let trueQueue = TruePriorityQueue()     let dotnetQueue = PriorityQueue()     do  for priority, value in items do             trueQueue.Put priority value             dotnetQueue.Put priority value     let actual, expected =         let f factory =             items             |&gt; Seq.choose ^ fun _ -&gt; factory ()             |&gt; List.ofSeq         f dotnetQueue.TryTake         , f trueQueue.TryTake     counterexample $\"Dotnet PriorityQueue: {actual}\"     counterexample $\"True PriorityQueue: {expected}\"     return actual = expected } <\/code><\/pre>\n<pre><code>*** Failed! Falsifiable (after 1 test and 4 shrinks): [(7, 0); (1, 1); (7, 2)] Dotnet PriorityQueue: [1; 2; 0] True PriorityQueue: [1; 0; 2] <\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0421\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c \u043f\u0443\u0442\u0438 \u0443 \u0432\u0441\u0435\u0445 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u0430\u044f, \u043d\u043e \u0441\u0430\u043c \u043f\u0443\u0442\u044c \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432 \u043c\u043e\u0436\u0435\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u0434\u0440\u0443\u0433\u0438\u043c. \u041d\u0430 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 \u0432\u043c\u0435\u0441\u0442\u043e \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0431\u0443\u043a\u0432\u044b <code>\u0413<\/code> \u0443 <code>PriorityQueue<\/code> \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u043f\u044c\u044f\u043d\u044b\u0439 \u0411\u0440\u0435\u0437\u0435\u043d\u0445\u0435\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a \u0442\u043e\u043c\u0443 \u0436\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a, \u0447\u0435\u043c <code>PriorityStack<\/code>:<\/p>\n<figure class=\"\"><\/figure>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c, \u043d\u0435 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0435\u0433\u043e \u0431\u044b\u043b\u043e \u043d\u0435\u043b\u044c\u0437\u044f:<\/p>\n<pre><code class=\"fsharp\">type PriorityStack&lt;'priority, 'value when 'priority : comparison&gt; () =     let items = ResizeArray()          member _.Put (priority : 'priority) (item : 'value) =         items         \/\/ \u0415\u0441\u043b\u0438 `priority &lt;= p`, \u0442\u043e \u0443 LIFO         \/\/ \u0435\u0441\u043b\u0438 `priority &lt; p`, \u0442\u043e \u0443 FIFO         |&gt; Seq.tryFindIndex ^ fun (p, _) -&gt; priority &lt;= p         |&gt; function             | Some index -&gt; items.Insert(index, (priority, item))             | None -&gt; items.Add (priority, item)      member _.TryTake () =         if items.Count = 0 then None else         let _, res = items.[0]         items.RemoveAt 0         Some res <\/code><\/pre>\n<p>\u0422\u0443\u0442 \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>option<\/code>, \u0447\u0442\u043e \u0440\u0430\u0434\u0438\u043a\u0430\u043b\u044c\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0430\u0435\u0442 \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0441\u0442\u044c \u0438 \u043e\u0431\u0435\u0441\u0441\u043c\u044b\u0441\u043b\u0438\u0432\u0430\u0435\u0442 \u0443\u0434\u0430\u043b\u0451\u043d\u043d\u044b\u0439 \u043c\u043d\u043e\u044e <code>IsEmpty<\/code>.<\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u043e\u043f\u044f\u0442\u044c \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0435\u043c\u0441\u044f \u0441 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435\u043c <code>when 'priority : comparison<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0442\u0438\u043f \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0430 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435. \u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0443 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442 \u0432\u043e\u043f\u0440\u043e\u0441\u044b \u043a \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044e <code>priority &lt;= p<\/code>. \u0415\u0441\u043b\u0438 \u0431\u044b \u0440\u0435\u0447\u044c \u0448\u043b\u0430 \u043d\u0435 \u043e \u0442\u0438\u043f\u0435, \u0430 \u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0442\u043e \u044d\u0442\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0431\u044b\u043b\u043e \u0431\u044b \u0432\u044b\u0432\u0435\u0434\u0435\u043d\u043e \u0438\u0437 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438. \u0422\u043e \u0435\u0441\u0442\u044c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043f\u0440\u043e\u0433\u043d\u0443\u043b \u0431\u044b \u043e\u0431\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 \u0443\u0433\u043e\u0434\u0443 \u043b\u043e\u0433\u0438\u043a\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0421 \u0442\u0438\u043f\u0430\u043c\u0438 \u0442\u0430\u043a\u0430\u044f \u043c\u0430\u0433\u0438\u044f \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u0414\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u0438 \u0438 \u0438\u0445 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u043d\u0430\u0434\u043e \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0442\u044c \u044f\u0432\u043d\u043e. \u0412 \u043e\u0431\u0449\u0438\u0445 \u0447\u0435\u0440\u0442\u0430\u0445 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0441 \u0433\u0435\u043d\u0435\u0440\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0441\u0435\u0442\u0442\u0435\u0440\u043e\u0432. \u0422\u0435\u0440\u043f\u0438\u043c\u043e, \u043d\u043e \u0438\u043d\u043e\u0433\u0434\u0430 \u0431\u0435\u0441\u0438\u0442.<\/p>\n<p><code>PriorityStack<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445, \u0438 \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u043d\u043e\u0433\u0434\u0430 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u043d\u0430\u0440\u0443\u0436\u0443, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u043b\u043e\u0433\u0438 \u0443\u043f\u0430\u0432\u0448\u0438\u0445 \u0442\u0435\u0441\u0442\u043e\u0432 \u0438\u043b\u0438 \u0432 \u043c\u0430\u0441\u043a\u0443 \u043a\u0430\u0440\u0442\u044b. \u0414\u0430\u043d\u043d\u044b\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043b\u0438\u043d\u0435\u0439\u043d\u043e, \u0447\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u043e \u043e\u0442\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0432 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 <code>_ IEnumerable<\/code> <\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-463012","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/463012","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=463012"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/463012\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=463012"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=463012"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=463012"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}