Страницы

Поиск по вопросам

суббота, 21 декабря 2019 г.

Способ хранения координат фишек

#cpp #массивы #visual_cpp #динамические_массивы


Пишу бота, который будет играть в простейшую игру. В начале каждого хода из файла
считывается игровое поле, которое представляет собой матрицу 8х8. В игре 4 игрока,
их фишки, соответственно, обозначены цифрами 1, 2, 3, 4 и расставлены на игровом поле.
Нужно найти все фишки каждого игрока и каким-то образом хранить местоположение (координаты)
каждой фишки. Как можно это сделать? Пробовал запоминать координаты в обычный массив
и в vector, но это не совсем удобно.
    


Ответы

Ответ 1



Есть два варианта хранения - хранение состояния игры (доски), а на ней фишек (например, массив int board[8][8]; в котором пустые поля обозначены нулями, а непустые - номером стоящей там фишки. Но исходя из "Необходимо, чтобы можно было максимально просто получить доступ к координатам выбранной фишки", вам нужен второй вариант - а именно, массив фишек с их координатами (x,y), которые можно реализовать как стандартный pair, а можно с помощью своей структуры типа struct Point { int x,y; }; Но, как я понимаю, вам нужно и то, и другое - чтобы, зная фишку, сразу получить возможные ходы - например, пустая ли какая-то клетка? Я бы просто делал класс типа Game, который бы хранил и доску, и четыре фишки, и при каждом ходе обновлял как координаты фишки, так и состояние доски. Интерфейс такого класса содержал бы функции для - возврата координат фишки номер N - возврата номера фишки на поле (x,y) (0, если пусто) - перемещения фишки N на новое поле. Как бы вы ни старались, сделать этот класс медленным - с 64 полями - у вас не получится. Какое нужно внутреннее представление - смотрите сами, что вам привычнее.

Ответ 2



Пробовал запоминать координаты в обычный массив и в vector, но это не совсем удобно. А что неудобно? Если делать массив, то нужно конвертер в наглядную форму сделать. И будет всё очень даже удобно. Но я бы взял пример из шахмат. Где одна ось буквами обозначается, другая цифрами. Координаты записываются как A6, E3... и т.д. Это и очень быстрый вариант, и очень наглядный.

В чем разница между int.Parse() и Convert.ToInt32()

#c_sharp


В чем разница между int.Parse() и Convert.ToInt32() в C# ?
    


Ответы

Ответ 1



int.Parse преобразует строку (string) в int (если может). Convert.ToInt32 преобразует в int значение любого типа, из перечисленных здесь. boolean, double, float и т.д. А самое главное, может преобразовать экземпляр любого класса, реализующего IConvertible. Если говорить о строках, то Convert.ToInt32 внутри всё равно использует int.Parse. Но есть нюанс: public static int ToInt32(String value) { if (value == null) return 0; return Int32.Parse(value, CultureInfo.CurrentCulture); } Для неинициализированной строки int.Parse выбросит исключение, Convert.ToInt32 вернет 0.

Каким образом компании зарабатывают на opensource?

#лицензирование #opensource #it_бизнес


Меня всегда интересовал вопрос, каким образом компании зарабатывают на opensource
проектах? У меня существует две догадки (к сожалению я в вопросах лицензирования не силен).


Должна существовать лицензия, которая позволяет распространять коммерческое по на
базе открытого (например без предоставления исходного кода по требованию). Тогда вполне
логично, что на этом можно заработать. 
Можно продавать услуги по обслуживанию открытого по, но тогда непонятно, кто будет
готов заплатить за услуги подобного рода? (хотя тут как по мне можно привести пример
обслуживания серверов, использующих открытое по)

    


Ответы

Ответ 1



Варианты: ПО с откодом может быть разделено на базовый функционал и на дополнительный (модули, пакеты и прочее). Дополнительные делают платным, а базовый так и остаётся бесплатным, но ограниченным в возможностях, и для того чтобы эти возможности расширить, клиенты покупают доп. возможности. Если, как сказано в вопросе, продукт хотят распространять без предоставления кода, то можно купить такую расширенную лицензию у разработчиков откод проекта. Платное консультированию и внедрение ПО. Написание и продажа учебных пособий для ПО. Реклама в основном ПО, куда же без неё. Написание (создание) обучающих уроков или каких-либо других ресурсов (сайтов, видео и т.п), где также можно встретить рекламу. Спонсирование, бывает и такое. Разновидность ПО: открытое-бесплатное и корпоративное. Продажа атрибутики (логотипов, символов): наклейки, игрушки и т.п.

Для чего нужен отрицательный margin и положительный padding в bootstrap?

#css #bootstrap #padding #margin #grid_layout


Bootstrap'ом редко пользовался, как-то не вникал в эти положительные и отрицательные
отступы блоков.  

Подскажите, для чего в блоке .container положительный padding, а в блоке .row отрицательный
margin? Какая практическая польза в этих отступах?  
    


Ответы

Ответ 1



Это сделано для выравнивания. У каждой колонки слева и справа есть padding, равный 15px. Он нужен для генерации одинакового отступа между колонками. Однако в этом случае отступ слева у первой и отступ справа у последней колонки в строке складывается с отступами контейнера. Чтобы нивелировать его используется .row с отрицательным margin равным 15px. Если использовать .row, то левый отступ у первого столбца и правый отступ у правого столбца "проваливаются" в уже существующие отступы у контейнера и не занимают дополнительного места. На вопрос почему бы не убрать отступ у контейнера и отказаться от отрицательного margin у .row ответ простой: блоков с контейнером может быть несколько, и в одном из них может отсутствовать сетка. Чтобы блоки с сеткой и без нее были выравнены по левой и правой границе, как раз и придумали этот прием с отрицательными margin. А сам padding у контейнера еще нужен и для того, чтобы его содержимое не прилипало к границе экрана на небольших разрешениях. update: при многократной вложенности, в качестве контейнера выступает уже колонка, а принцип действия тот же самый.

Ответ 2



Отрицательный отступ у .row для того, чтобы при многоуровневой структуре не суммировались отступы у блоков разных уровней.
В приведенном примере блок #inner будет по размеру такой же как блок #outer. Если бы у row не было отрицательных отступов, то блок #inner был бы меньше блока #outer на 15px с каждой стороны.

Как получить содержимое круглых и фигурных скобок первого уровня?

#регулярные_выражения


Я имею следующую структуру:

(Q){(W){g}(E){z}}


Мне необходимо достать то, что находится в круглых и фигурных скобках первого уровня. Т.е.

Q и (W){g}(E){z}


Пробовал "\((.+?)\){.*?}" но это обрезает последнюю фигурную скобку.
    


Ответы

Ответ 1



В C# можно использовать балансирующие группы: \((?(?>[^()]+|(?\()|(?<-o>\)))*(?(o)(?!)))\){(?(?>[^{}]+|(?{)|(?<-w>}))*(?(w)(?!)))} См. демо \( - открывающая скобка ) (?(?>[^()]+|(?\()|(?<-o>\)))*(?(o)(?!))) - все, что между ( и ) \) - закрывающая скобка ) { - открывающая скобка { (?(?>[^{}]+|(?{)|(?<-w>}))*(?(w)(?!))) - все, что между { и } } - закрывающая скобка }.

Ответ 2



Используйте рекурсивный шаблон, например в таком варианте /\(((?>[^()]+|(?R))*)\)|{((?>[^{}]+|(?R))*)}/g Результат будет в первой или второй группе в зависимости от вида скобок. Пример тут https://regex101.com/r/HRABRe/1

Ответ 3



Для обработки вложенности скобок в регулярных выражениях используются рекурсивные проверки. Для первой группы круглых скобок, в случае если в них могут быть еще круглые скобки, это выглядит так: ( # начинаем первую группу захвата \( # первый символ - круглая скобка ( # вторая группа захвата - требуемый результат (?: (?1) | # внутри которой может быть повторено выражение всей первой группы .)*? # или любой символ, много раз ) \) ) Все выражение целиком выглядит так: (\(((?:(?1)|.)*?)\))({((?:(?3)|.)*?)}) Требуемые результаты в 2 и 4 группах захвата. Если внутри первых круглых скобок вложенности быть не может, то начало можно сократить до того, как вы изначально пробовали, т.е. до \((.*?)\). Тогда еще надо будет не забыть поменять ссылку (?3) Тест на regex101.com UPD: Исходя из комментария "Круглые скобки содержат имя параметра, фигурные содержат параметры. Параметр может содержать другие параметры", в случае если поддержки рекурсии в вашем диалекте регулярных выражений нет можно применить: \((.*?)\){(.*)} Первый захват не жадный, до первой встреченной круглой скобки, второй - жадный, захватит все до последней фигурной скобки, если других фигурных скобок в строке не будет, такого выражения будет достаточно

Как в KDE сделать чтобы на экране входа всегда была английская раскладка?

#linux #kde


Имеется Arch Linux с установленной KDE последней версии — 5.10.0. В качестве менеджера
входа в систему используется SDDM. Имеется ровно две раскладки — русская и английская.
На экране входа будет выбрана последняя использованная раскладка. Как изменить это,
чтобы независимо от последней использованной раскладки на экране входа всегда была
английская раскладка? Последовательность действий, иллюстрирующая проблему:


Включаю компьютер, появляется экран входа, раскладка клавиатуры ­— английская (это
хорошо)
Вхожу в систему, изменяю раскладку клавиатуры на русскую
Блокирую экран с помощью CtrlAltL, либо закрываю и открываю крышку ноутбука
В обоих случаях появляется экран входа с русской раскладкой клавиатуры (это плохо)


Проблема в том, что пароль состоит из английских символов, и каждый раз при входе
мне приходится смотреть, какая сейчас раскладка и менять её, если она русская.
    


Ответы

Ответ 1



Я тоже задавался этим вопросом. Вариант 1 (проверка по наличию процесса lockscreen) Создал скрипт $ cat ~/scripts/enru.sh #!/bin/bash CHKSTR=`ps aux| grep -v grep | grep lockscreen` if [[ $CHKSTR == *lockscreen* ]]; then kbd=`setxkbmap -print | sed -n 's#xkb_symbols[^"]*"\([^"]*\)".*$#\1#p' | awk -F+ '{print $2}'` if [[ $kbd == ru ]]; then xdotool key 'alt+shift' fi fi Добавил в crontab от имени пользователя строку $crontab -u USERNAME -e * * * * * DISPLAY=:0 bash ~/scripts/enru.sh >/dev/null 2>/dev/null Скрипт каждую минуту проверяет, запущен ли процесс usr/lib/unity/unity-panel-service --lockscreen-mode и, при его наличии, запускает проверку и изменение раскладки клавиатуры. Вариант 2 (запуск при нажатии Ctrl+Alt+L) Создал скрипт $ cat ~/scripts/enru2.sh #!/bin/bash gnome-screensaver-command --lock && gsettings set org.gnome.desktop.input-sources current 0 # current 0 говорит о том, что нужно включить дефолтную раскладку en_EN. current 1, соответственно, ru_RU Проверяем, есть ли у нас дополнительные комбинации клавиш, которые мы уже используем: $ gsettings get org.gnome.settings-daemon.plugins.media-keys custom-keybindings ['/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/'] custom0 говорит о том, что одна комбинация уже добавлена, поэтому надо добавить следующую - custom1: $ gsettings set org.gnome.settings-daemon.plugins.media-keys custom-keybindings "['/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/', '/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/']" Если же вы добавляете свою первую комбинацию клавиш, то выполните команду $ gsettings set org.gnome.settings-daemon.plugins.media-keys custom-keybindings "['/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/']" Отключаем хоткеи для системного lockscreen'а: $ gsettings set org.gnome.settings-daemon.plugins.media-keys screensaver '' Задаём имя нашему хоткею: $ gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/ name 'Lockscreen' Указываем, какую команду надо выполнять: $ gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/ command "/home/$USER/scripts/enru2.sh" Задаём комбинацию клавиш для запуска блокировки экрана: $ gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/ binding 'l'

Ответ 2



Имеются два независимых варианта решения, причём можно использовать оба одновременно. В обоих вариантах используется программа xkb-switch. Была выбрана эта программа, так как она позволяет легко переключить раскладку на английскую (альтернативный способ — определять раскладку, и если она русская, эмулировать нажатие комбинации клавиш смены раскладки с помощью xdotool — может не сработать). В Arch Linux установить xkb-switch можно из AUR. Первый вариант работает, если вы блокируете сеанс с помощью перехода в ждущий режим (то есть, например, при закрытии и последующем открытии крышки ноутбука). Заключается он в написании скрипта, который будет выполняться непосредственно перед переходом компьютера в ждущий режим. Для systemd скрипт может выглядеть следующим образом: # /etc/systemd/system/suspend@.service [Unit] Description=Change keyboard layout to english immediately before suspend Before=sleep.target [Service] User=%I Type=simple Environment=DISPLAY=:0 ExecStart=/usr/local/bin/xkb-switch -s us [Install] WantedBy=sleep.target Чтобы скрипт заработал, нужно выполнить следующую команду: sudo systemctl enable suspend@имя_вашего_пользователя.service Второй вариант работает, если вы блокируете сеанс, но не выключаете компьютер (так происходит, например, при нажатии CtrlAltL). Заключается он в написании скрипта, который будет выполняться каждые несколько десятков секунд (например, каждую минуту). Этот скрипт будет проверять, заблокирован ли сеанс (например, проверив, существует ли процесс с именем, содержащим lockscreen), и если заблокирован, то менять раскладку на английскую. Подробное описание второго варианта для Ubuntu.

Select for update skip locked

#sql #oracle #oracle11g


Не могу понять, на английском читаю, кажется что ничего дополнительного не делает
не документированная фича skip locked в oracle 11g. 

Объясните, какие различия с этой фичей и без неё. 
    


Ответы

Ответ 1



Разница между запросоми с for update, с опцией skip locked и без неё, следующая: Без этой опции запрос не вернётся, если в выборке есть как минимум одна залоченная строчка. Т.е. он будет ожидать (wait) пoка трансакция не будет завершена в сессии, которая затребовала lock. Если добавить nowait, то он вернётся сразу же с исключением, которое может быть обработано. ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired С опцией skip locked он вернётcя сразу же и вернёт только незалоченные строчки или no rows selected, если таковых нет. И важное отличие для работы с курсорами - курсор с for update залочит все строки попадающие под условие курсора сразу при open, а если добавить skip locked, то только те строки будут залочены, которые были действительно считаны в fetch, что позволяет ограничить количество залоченых строк, или возвращать открытый курсор как результат функции с ещё не залочеными строками. Не документированной опция skip locked была в 9i и 10g версиях. С 11g она документирована, см. здесь. В этом ответе подрузумевается row lock, для exclusive table lock см. документацию. Небольшой пример. В первой сессии: SQL> select emp_id from emp where emp_id in (1, 2) for update; EMP_ID ---------- 1 2 2 rows selected. В другой сессии: SQL> select emp_id from emp where emp_id in (1, 2, 3) for update nowait; select emp_id from emp where emp_id in (1, 2, 3) for update nowait * ERROR at line 1: ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired SQL> select emp_id from emp where emp_id in (1, 2, 3) for update skip locked; EMP_ID ---------- 3 1 row selected. SQL> select emp_id from emp where emp_id in (1, 2, 3) for update; -- ждёт, пока в первой сессии не будет произведён откат