Comments 46
Пока живы такие очумельцы — за нашу Родину можно не беспокоиться ;)
Ждём Doom на баше =).
Отличный практикум на bash. И комменты исходнике просто отличные. Спасибо.
Не думал, что в Unicode есть символы для шахматных фигур. И вправду, они есть en.wikipedia.org/wiki/Chess_symbols_in_Unicode =)))
торт
Круть! ;)
С кнопками я тоже как то бился помню… как то так:
С кнопками я тоже как то бился помню… как то так:
#!/bin/bash
# Прочитать 1 символ.
# -s отключить эхо, -n1 только один символ, -r считывать "\" не дожидаясь экранирования
while read -s -n1 key
do
...
done
Так не получится. Курсорные клавиши выдают по три символа за раз, курсорные с шифтом (на Маке) — шесть, так что надо какой-то определять конец комбинации :) Я придумал два выхода — либо найти все комбинации, которые генерируются и собрать их, либо замерять задержки между нажатиями. У меня используется гибрид — для того, чтобы понимать, что нашёлся конец я использую словарь, чтобы определить, что клавиша нажата в составе комбинации — меряю задержку.
Кстати да, для курсорных и прочих клавиш где передаются более одного символа, я делал счетчик их, и типа конечного автомата для их приема, обрабатывал только небходимые мне.
Вот и получается, что нужно либо знать все комбинации и как-то их хранить (каких только клавиш на компьютерах не бывает и что они только не шлют в консоль, хранить это накладно, обрабатывать — долго), либо делать как-то детектор конца комбинации.
Причём конечный автомат тоже не очень-то поможет — есть комбинации, не содержащие признака, что дальше может что-то идти, то есть есть комбинация abcd, а есть abcdef, их никак не различить, если делать конечный автомат.
Причём конечный автомат тоже не очень-то поможет — есть комбинации, не содержащие признака, что дальше может что-то идти, то есть есть комбинация abcd, а есть abcdef, их никак не различить, если делать конечный автомат.
Да, детектор по времени нужен. Я кстати был удивлен, когда писал код для работы с терминалом, ввод и вывод. Куча ESC последовательностей, причем разных для разных терминалов (я поддерживал только vt-100) и не придумали хотя бы признака конца последовательности! А если ты ее не обрабатываешь, то она вылазит левыми символами, т.к. само тело то в ASCII. Это создает массу сложностей.
Понятно конечно что все это тянется от печатных машинок и все это legacy и много рудиментов и обратная совместимость… Зоопарк короче :D Это уже не раз тут обсуждали…
Понятно конечно что все это тянется от печатных машинок и все это legacy и много рудиментов и обратная совместимость… Зоопарк короче :D Это уже не раз тут обсуждали…
У нас товарищ перед увольнением сделал сетевой морской бой на виндовых батниках. Хотели даже традицию такую ввести, перед увольнением писать морской бой на чем-нибудь экзотическом)
Мать моя женщина o_O.
Я тоже годика полтора назад писал морской бой в консоли. Только упор делался как раз на наличие всех проверок, и умный АИ.
Но и «дизайн» тоже не оставил в стороне, все цвета и символы были хорошо подобраны (хотя у меня было только ASCII и 16 цветов).
Надо бы раскопать код…
Но и «дизайн» тоже не оставил в стороне, все цвета и символы были хорошо подобраны (хотя у меня было только ASCII и 16 цветов).
Надо бы раскопать код…
Ксоникс, шахматы… Что следующее? Неужто и вправду Doom? :D
Нет, наверное таки Diablo IV :-P
Нет, наверное таки Diablo IV :-P
Повешусь я такое делать :)
Мы верим в тебя, падаван ))))
ну 3D и правда тут х.з., а вот что-то типа Rogue было бы посильно, наверное = )
Даёшь тетрис! =)
Может быть :)
uuner.doslash.org/forfun/sedtris.sed — тетрис на Седе
Осталось режим игры с компьютером написать :)
Ээм, простите за занудство, но это не самый правильный способ — мерить задержку между нажатиями клавиш для выявления комбинации.
Сугубо говоря, он верен до тех пор, пока число циклов тактового генератора между обработками прерывания первой и второй клавиши последовательности больше единицы. (Сейчас-то это почти всегда так, но вот ранее… :-)
Итак, чтобы не быть болтолологом, предложу своё решение:
во-первых, я бы заменил явно указание кодов клавиш на их эскейп-аналоги, это решение получше, так как ориентируемся на коды клавиш для терминала(см пример из книги abs-guide):
И теперь, комбинация клавишь в эскейп-последовательности выглядит так (для SHIFT+ARR_DOWN):
так что, читая по три символа это будет выглядеть как-то так:
Сугубо говоря, он верен до тех пор, пока число циклов тактового генератора между обработками прерывания первой и второй клавиши последовательности больше единицы. (Сейчас-то это почти всегда так, но вот ранее… :-)
Итак, чтобы не быть болтолологом, предложу своё решение:
во-первых, я бы заменил явно указание кодов клавиш на их эскейп-аналоги, это решение получше, так как ориентируемся на коды клавиш для терминала(см пример из книги abs-guide):
# Коды клавиш.
arrowup='\[A'
arrowdown='\[B'
arrowrt='\[C'
arrowleft='\[D'
insert='\[2'
delete='\[3'
SUCCESS=0
далее, после считывания, сравниваем кодами:read -n3 key # Прочитать 3 символа.
echo -n "$key" | grep "$insert"
if [ "$?" -eq $SUCCESS ]
then
echo "Нажата клавиша \"Insert\"."
exit $SUCCESS
fi
И теперь, комбинация клавишь в эскейп-последовательности выглядит так (для SHIFT+ARR_DOWN):
'\[1;2B'
, где '\[1;' — начало escape-последовательности, 2B — коды клавиш, 2 — SHIFT, B — ARR_DOWNтак что, читая по три символа это будет выглядеть как-то так:
seq='\[1'
shift_down=';2B'
read -n3 key # Прочитать 3 символа.
echo -n "$key" | grep "$arrowup"
[ "$?" -eq $SUCCESS ] && : # своя обработка
echo -n "$key" | grep "$arrowdown"
[ "$?" -eq $SUCCESS ] && :
echo -n "$key" | grep "$arrowrt"
[ "$?" -eq $SUCCESS ] && :
echo -n "$key" | grep "$arrowleft"
[ "$?" -eq $SUCCESS ] && :
echo -n "$key" | grep "$seq"
if [ "$?" -eq $SUCCESS ] ; then
read -n3 key
echo -n "$key" | grep "$shift_down"
[ "$?" -eq $SUCCESS ] && echo "Pressed Shift-Down"
#etc
fi
Что будет если пользователь нажал не курсорные клавиши?
тогда ведётся считывание (в моём примере по три символа), заменяя
read -n3 key
на read -n1 key
можно вести обработку нажатия и печатных символов, затем, среди них обнаруживать escape-последовательности.Ну то есть вы предлагаете один из способов, который я упоминал — искать известные последовательности. Как уже говорил, он не работает, так как есть последовательности разной длины, но с одним началом.
мм, а какие две последовательности в ваших комбинациях совпадают?
(я что-то не заметил, курсорные клавиши, курсорные с зажатой управляющей клавишей и обычные все различаются)
(я что-то не заметил, курсорные клавиши, курсорные с зажатой управляющей клавишей и обычные все различаются)
Если курсорную клавишу зажать с shift на «маке», будет последовательность ровно такая же как курсорная, только длиннее. Это только один пример.
Мне хотелось сделать обработку в которую я достаточно быстро смогу добавить любые новые клавиши, на длине и маске основываться нельзя — будут ложные нажатия.
Мне хотелось сделать обработку в которую я достаточно быстро смогу добавить любые новые клавиши, на длине и маске основываться нельзя — будут ложные нажатия.
ясно, хотя это странно, в bash под linux они различаются.
ладно, ваша взяла, хотя по мне это некий «костыль», извините уж.
ладно, ваша взяла, хотя по мне это некий «костыль», извините уж.
Конечно костыль, ещё бы! Если бы в shell было какое-то нормальное встроенное средство для этого, было бы здорово.
Ещё пример, кстати, вспомнил. Любая длинная последовательность начинается с Esc (0x1B), если нажать клавишу Esc, то будет выдана именно она. Как различить это начало длинной последовательности или пользователь просто Esc нажал?
да, на счёт этого я в курсе, я предлагал решение к вашей конкретно задаче, где в используемые клавиши Esc не входит:)
ps
вообще, конечно, спасибо, тут вы придумали хоть какое-то решение. Как-то пытался найти функцию, возвращающую состояние буфера ввода, но, может, плохо искал, думаю, это решение было бы слегка красивей.
ps
вообще, конечно, спасибо, тут вы придумали хоть какое-то решение. Как-то пытался найти функцию, возвращающую состояние буфера ввода, но, может, плохо искал, думаю, это решение было бы слегка красивей.
Забыл сказать: статья мне понравилась, сам когда-то, админя также развлекался с напарником; вывод был разве что на разные терминалы сервера, а не игра по сети, но уже был и таймер ходов, и лог, и чёрт вспомнит, что ещё!
Sign up to leave a comment.
Сетевая игра на bash: шахматы