Комментарии 46
Пока живы такие очумельцы — за нашу Родину можно не беспокоиться ;)
+20
Ждём Doom на баше =).
+5
Отличный практикум на bash. И комменты исходнике просто отличные. Спасибо.
+3
Не думал, что в Unicode есть символы для шахматных фигур. И вправду, они есть en.wikipedia.org/wiki/Chess_symbols_in_Unicode =)))
+7
торт
+2
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Круть! ;)
С кнопками я тоже как то бился помню… как то так:
С кнопками я тоже как то бился помню… как то так:
#!/bin/bash
# Прочитать 1 символ.
# -s отключить эхо, -n1 только один символ, -r считывать "\" не дожидаясь экранирования
while read -s -n1 key
do
...
done
0
Так не получится. Курсорные клавиши выдают по три символа за раз, курсорные с шифтом (на Маке) — шесть, так что надо какой-то определять конец комбинации :) Я придумал два выхода — либо найти все комбинации, которые генерируются и собрать их, либо замерять задержки между нажатиями. У меня используется гибрид — для того, чтобы понимать, что нашёлся конец я использую словарь, чтобы определить, что клавиша нажата в составе комбинации — меряю задержку.
+1
Кстати да, для курсорных и прочих клавиш где передаются более одного символа, я делал счетчик их, и типа конечного автомата для их приема, обрабатывал только небходимые мне.
0
Вот и получается, что нужно либо знать все комбинации и как-то их хранить (каких только клавиш на компьютерах не бывает и что они только не шлют в консоль, хранить это накладно, обрабатывать — долго), либо делать как-то детектор конца комбинации.
Причём конечный автомат тоже не очень-то поможет — есть комбинации, не содержащие признака, что дальше может что-то идти, то есть есть комбинация abcd, а есть abcdef, их никак не различить, если делать конечный автомат.
Причём конечный автомат тоже не очень-то поможет — есть комбинации, не содержащие признака, что дальше может что-то идти, то есть есть комбинация abcd, а есть abcdef, их никак не различить, если делать конечный автомат.
0
Да, детектор по времени нужен. Я кстати был удивлен, когда писал код для работы с терминалом, ввод и вывод. Куча ESC последовательностей, причем разных для разных терминалов (я поддерживал только vt-100) и не придумали хотя бы признака конца последовательности! А если ты ее не обрабатываешь, то она вылазит левыми символами, т.к. само тело то в ASCII. Это создает массу сложностей.
Понятно конечно что все это тянется от печатных машинок и все это legacy и много рудиментов и обратная совместимость… Зоопарк короче :D Это уже не раз тут обсуждали…
Понятно конечно что все это тянется от печатных машинок и все это legacy и много рудиментов и обратная совместимость… Зоопарк короче :D Это уже не раз тут обсуждали…
0
У нас товарищ перед увольнением сделал сетевой морской бой на виндовых батниках. Хотели даже традицию такую ввести, перед увольнением писать морской бой на чем-нибудь экзотическом)
+2
Мать моя женщина o_O.
+1
Я тоже годика полтора назад писал морской бой в консоли. Только упор делался как раз на наличие всех проверок, и умный АИ.
Но и «дизайн» тоже не оставил в стороне, все цвета и символы были хорошо подобраны (хотя у меня было только ASCII и 16 цветов).
Надо бы раскопать код…
Но и «дизайн» тоже не оставил в стороне, все цвета и символы были хорошо подобраны (хотя у меня было только ASCII и 16 цветов).
Надо бы раскопать код…
0
НЛО прилетело и опубликовало эту надпись здесь
Ксоникс, шахматы… Что следующее? Неужто и вправду Doom? :D
Нет, наверное таки Diablo IV :-P
Нет, наверное таки Diablo IV :-P
0
Повешусь я такое делать :)
0
Мы верим в тебя, падаван ))))
0
ну 3D и правда тут х.з., а вот что-то типа Rogue было бы посильно, наверное = )
0
Даёшь тетрис! =)
0
Может быть :)
0
uuner.doslash.org/forfun/sedtris.sed — тетрис на Седе
+1
Осталось режим игры с компьютером написать :)
0
Ээм, простите за занудство, но это не самый правильный способ — мерить задержку между нажатиями клавиш для выявления комбинации.
Сугубо говоря, он верен до тех пор, пока число циклов тактового генератора между обработками прерывания первой и второй клавиши последовательности больше единицы. (Сейчас-то это почти всегда так, но вот ранее… :-)
Итак, чтобы не быть болтолологом, предложу своё решение:
во-первых, я бы заменил явно указание кодов клавиш на их эскейп-аналоги, это решение получше, так как ориентируемся на коды клавиш для терминала(см пример из книги 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
0
Что будет если пользователь нажал не курсорные клавиши?
0
тогда ведётся считывание (в моём примере по три символа), заменяя
read -n3 key
на read -n1 key
можно вести обработку нажатия и печатных символов, затем, среди них обнаруживать escape-последовательности.0
Ну то есть вы предлагаете один из способов, который я упоминал — искать известные последовательности. Как уже говорил, он не работает, так как есть последовательности разной длины, но с одним началом.
0
мм, а какие две последовательности в ваших комбинациях совпадают?
(я что-то не заметил, курсорные клавиши, курсорные с зажатой управляющей клавишей и обычные все различаются)
(я что-то не заметил, курсорные клавиши, курсорные с зажатой управляющей клавишей и обычные все различаются)
0
Если курсорную клавишу зажать с shift на «маке», будет последовательность ровно такая же как курсорная, только длиннее. Это только один пример.
Мне хотелось сделать обработку в которую я достаточно быстро смогу добавить любые новые клавиши, на длине и маске основываться нельзя — будут ложные нажатия.
Мне хотелось сделать обработку в которую я достаточно быстро смогу добавить любые новые клавиши, на длине и маске основываться нельзя — будут ложные нажатия.
0
ясно, хотя это странно, в bash под linux они различаются.
ладно, ваша взяла, хотя по мне это некий «костыль», извините уж.
ладно, ваша взяла, хотя по мне это некий «костыль», извините уж.
0
Конечно костыль, ещё бы! Если бы в shell было какое-то нормальное встроенное средство для этого, было бы здорово.
+1
Ещё пример, кстати, вспомнил. Любая длинная последовательность начинается с Esc (0x1B), если нажать клавишу Esc, то будет выдана именно она. Как различить это начало длинной последовательности или пользователь просто Esc нажал?
0
да, на счёт этого я в курсе, я предлагал решение к вашей конкретно задаче, где в используемые клавиши Esc не входит:)
ps
вообще, конечно, спасибо, тут вы придумали хоть какое-то решение. Как-то пытался найти функцию, возвращающую состояние буфера ввода, но, может, плохо искал, думаю, это решение было бы слегка красивей.
ps
вообще, конечно, спасибо, тут вы придумали хоть какое-то решение. Как-то пытался найти функцию, возвращающую состояние буфера ввода, но, может, плохо искал, думаю, это решение было бы слегка красивей.
0
Забыл сказать: статья мне понравилась, сам когда-то, админя также развлекался с напарником; вывод был разве что на разные терминалы сервера, а не игра по сети, но уже был и таймер ходов, и лог, и чёрт вспомнит, что ещё!
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Сетевая игра на bash: шахматы