Comments 20
Что происходит, если новый фрукт попадает на тело змеи всё время? (т.е. змея размером с поле?)
Для змеи поиск пути лучше все таки алгоритмом А-звезды с приоритетом движения вдоль себя и вдоль стенок, чтобы избежать закольцевания.
Судя по гифке, змейка с вашим алгоритмом движется крайне неоптимально. Может быть поведение становится лучше на большой длине, но на том что показали — есть много ненужных метаний из стороны в сторону
Тогда не понятно, почему вы считаете его "идеальным"
Это не зрелищно на первых этапах. Так то можно вообще просто двигаться сканирующим лучем, оставляя коридор в 1 клетку шириной чтобы вернуться на начальную точку, вы гарантированно когда-то соберёте все яблоки, но выглядеть это будет супер уныло.
Вообще я видел что люди на первых этапах используют А-звезда, дальше цикл Гамильтона (иногда для зрелищности опять включают А-звезда если есть место, цель в прямой досягаемости, нет риска создать недоступную зону).
import System.IO
whenKeyIsPressed :: Handle -> IO a -> IO (Maybe a)
whenKeyIsPressed handle getCh = hReady handle >>= go
where go True = getCh >>= return. Just
go _ = return Nothing
main :: IO ()
main = do
hSetBuffering stdin NoBuffering
ch < — whenKeyIsPressed stdin getChar
case ch of
Just c -> putStrLn $ «Key pressed: » ++ [c]
Nothing -> return () — putStrLn «Nothing is pressed»
main
import System.IO
whenKeyIsPressed :: Handle -> IO a -> IO (Maybe a)
whenKeyIsPressed handle getCh = hReady handle >>= go
where go True = getCh >>= return . Just
go _ = return Nothing
main :: IO ()
main = do
hSetBuffering stdin NoBuffering
ch <- whenKeyIsPressed stdin getChar
case ch of
Just c -> putStrLn $ "Key pressed: " ++ [c]
Nothing -> return () -- putStrLn "Nothing is pressed"
main<b></b>
А что за курс проходили, и как долго? Довольно впечатляющий уровень для человека, который просто прошел курс.
Отличная работа! Возможно, вам будет интересно посмотреть на немного иную реализацию змейки, которую я писал для RosettaCode (https://rosettacode.org/wiki/Snake#Haskell). Она не консольная, на Gloss и автоматический поиск не гарантирует прохождения, но показывает некоторые приёмы создания DSL и использования линз.
Easy Forth — Обучающий урок как можно создать змейку на Forth и поиграть в неё тут же в браузере — набрав слово start
Очень неудобно читать код с такими случайными выравниваниями (да еще и tab-ы используются, которые у всех разные).
Надо что-то вроде
data WorldState
= Process
| GameOver
| ...
deriving (Eq)
data World
= World
{ snake :: Snake
, ...
}
let
и where
в конце строки, а не в начале новой — это что-то за гранью. Не надо так делать.
Этот код выглядит как обычный императивный код после do
, но потом видишь определение ф-ии и выпадаешь в осадок:
inputController command world = let
boost dir1 dir2 = if dir1 == dir2 then 0.05 else 0.3
filterSecondSegmentDir (x:[]) dirOld dirNew = dirNew
filterSecondSegmentDir (x:xs) dirOld dirNew | pointStep dirNew x == head xs = dirOld
| otherwise = dirNew in
надо
inputController command world =
...
where boost dir1 dir2 = if dir1 == dir2 then 0.05 else 0.3
filterSecondSegmentDir [x] dirOld dirNew = dirNew
filterSecondSegmentDir (x:xs) dirOld dirNew
-- условия на новой строке, чтобы у всех ф-ий они были
-- в одном и том же месте, а не безумной лесенкой
| pointStep dirNew x == head xs = dirOld
| otherwise = dirNew in
и, в целом, надо стараться укладываться по ширине в 80 символов. Не все разворачивают редактор на всю ширину экрана, не всем на Хабре хочется прокручивать код вправо/влево. Ну и код иногда печатают (особенно учебный).
Змейка на Haskell с циклом Гамильтона