RU

Склонятор названия предмета согласно количеству

Хитрый Пряник #1300 19.12.2014 13:56 6 comments 6247 views

Скачать Склонятор 1.5

Умеет выводить склонённое слово с цифрой и без, с эпитетом и без, начинаться с прописной буквы для вставки в начало предложения (напр. Прошло 5 дней — Прошло[формат 3,0] + дней[формат 0,1]). Если эпитет для формата 3 добавлен и эпитет, то именно он будет начинаться с прописной: «Бронебойных патронов» (формат[3,1])

Вызов функции в виде func(’chisskl’,’имя_массива’,#формат,#номер_эпитета)
Внутри имя_массива[0] должно хранится количество предметов, внутри какой-либо из следующих — формы слова через пробел: имя_массива[itds+1]=‘единиц единица единицы’. itds — константа, насколько сдвинуть описание на случай совместимости с другими библиотеками, которые могут хранить что-то в первых ячейках. А так же самосовместимости. Например у нас в первой ячейке нескольких переменных эпитеты для «солнечного», а во-второй для «хмурого» и можно не вызывать второй эпитет постоянно, а лишь добавить единицу к itds

Можно посмотреть работу библиотеки не только в демке, но и в действии, а так же поиграть в квест «Тюрьма» из Космических Рейнджеров, который я пофиксил и проапгрейдил: неверно работала функция, была путаница в условиях, в итоге не было возможности участвовать в рукопашных боях. А апгрейд — вывод «дней» и «прошло» в разных форматах.


Скачать простой Склонятор 1.1

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

обе функции, если не найдут хотя бы наименования — аварийно завершаются, возвращая сообщение об ошибке.


Тестируйте пожалуйста и используйте на здоровье и во избежание страшных конструкций вида «кол-во патронов, шт.: 21» :)

Агитация:
На дворе 21 век, когда роботы не то что разговаривают, а начинают выдвигать простейшие идеи. И на фоне этого почти нигде не наблюдается культуры интерфейсного языка в программах. И не только. Пресловутые «Уважаем(ый/ая)» повсеместно. 1 штук и «0 файлы найдено» тоже. Короче, мой вклад в искоренение топорности робоязыка. Функция, выбирающая правильное склонение предмета, согласно количеству. Может добавлять эпитет (да хоть несколько), можно развивать, урезать, подтачивать напильником, как нравится.

Edited at 28.12.2014 02:13 (11 years ago)
Хитрый Пряник #1300 20.12.2014 09:48 (11 years ago)

Обновлено: добавил переменную для смещения данных в массиве, на случай, если вы уже пользуетесь массивом и храните в 1/2/3 его строке что-то. Переменная itds в objarrs. Можно так же раскоментировать строчку, смещающую и ячейку количества, если по какой-то причине количество не в нулевой хранится. Ссылка прежняя.

Хитрый Пряник #1300 21.12.2014 08:30 (11 years ago)

Обновлено. Версия 1.5
Работа в «полевых условиях» показала, что нужно ещё пара вариантов ради гибкости в тексте. А параллельно перелопатил весь код. Так же встроил в квест из Космических рейнджеров, ибо лазил туда исправлять код, из-за которого невозможно было выступать в боях или получить массаж. Заодно проверил практическую применимость, отловив последние баги и неудобства.
Теперь вот чего умеет выдать в зависимости от указания параметров:
формат 0: 0 хмудр / 1 хмудра / 2 хмудры
формат 1: не осталось хмудр / 1 хмудра / 2 хмудры
формат 2: хмудр / хмудра / хмудры
формат 3: Хмудр / Хмудра / Хмудры
при добавлении номера эпитета, добавит его: 0 кузявых хмудр
(в демке показано, как подставить случайный из набора)

Aleks Versus Moderator 21.12.2014 09:43 (11 years ago)

К чему такие сложности? Заполнение массива вариантами написания, тяжеловесные перечисления, множество правил.
всего три варианта написания для ВСЕХ чисел:
0 монет
1 монета
2 монеты
5 монет
11 монет
101 монета

Вот функция, выбирающая окончание по числу. Варианты окончаний передаются аргументом в виде одна|две-три…|ноль-пять-одинадцать….

Spoiler
!# get.word.end
! вычисляет окончание по числу.
! args[0] - число
! $args[1] - окончания в формате a|b|c
args[0] = args[0]
$args[1] = $args[1]
! деньги
args[2] = args[0] mod 10
args[3] = args[0] mod 100
$args['gwenda']='gwe_error'
if args[2]=1 and args[3]!11:
	$args['gwenda']=$func('get.word.inPos',$args[1],1)
end
if args[2]>1 and args[2]<5 and (args[3]<5 or args[3]>20):
	$args['gwenda']=$func('get.word.inPos',$args[1],2)
end
if args[2]=0 or args[2]>4 or (args[3]>10 and args[3]<21):
	$args['gwenda']=$func('get.word.inPos',$args[1],3)
end
$result=$args['gwenda']

Функция использует ещё одну функцию, она тоже весьма проста:

Spoiler
!# get.word.inPos
! Функция получает из строки вида ввв|jdkdk|kdkdk|kdkdk|... ...|воволвлв строку стоящую в указанной позиции
! $args[0] - строка
! args[1] - номер позиции
if $args[2] = '': $args[2]='|'
$args[0] = $args[0]+$args[2]
args[1] = args[1]
:for
if len($args[0])>0 and args[1]>0:
	if instr($args[0],$args[2])>0:
		$args['cs'] = $mid ($args[0],1,instr($args[0],$args[2]))
		$args[0] = $mid($args[0],instr($args[0],$args[2])+1)
	else
		$args['cs']=$args[0]
		$args[0]=''
	end
	! *pl str(args[1])+'^'+$args['1']
	args[1]-=1
	if args[1]>0: jump 'for'
end
$result=$replace($args['cs'],$args[2])

Пример использования:

"У меня в кармане <<крышки[0]>> крыш<<$func('get.word.end',крышки[0],'ка|ки|ек')>>."
Хитрый Пряник #1300 21.12.2014 14:26 (11 years ago)

Твоя версия удобна для разового использования на случайное слово в тексте. А когда у тебя на одну локацию оно по 10 раз, сильно хочется сократить вызов и не допустить опечаток.

Функция нужна для того чтобы
а) один раз заполнить одну строку (для этого строка а ) и вызывать минимальным текстом: func(’chisskl’,’крышки’). И ничто не мешает сменить вариант по умолчанию. или сократить до func(’chsk’,’Кр’) в случае если это вездесущий мусор какой — слово всё равно полное будет выдаваться из массива.

б) Не быть зажатым только одним форматом, сохраняя полную гибкость языка. И иметь возможность добавить второй формат.

в) подставь в свою версию инженеров-подводников: или дважды вызывать функцию или каждый раз писать ‘ов-подводников|ов-подводник|ов-подводники’ или путаться инженеры они или инженеры подводники.

г) патроны могут быть простыми, трассирующими, зажигательными, бронебойными. Мне нужно указать лишь цифру и добавить +args[2]-1 в код функции, чтобы она читала количество не только из патроны[0], но и из 1,2,3.
func(’chisskl’,’патроны’,0,4) даст мне «22 бронебойных патрона».

Представь, что ты уже 50 локаций сделал, а потом узнаёшь, что слово не так пишется. Ты пойдёшь по всем 50 локациям, автозаменой конечно, и всё же. Мне — изменить строчку словаря. Понадобился новый формат, например патроны:_1? Ты каждый раз будешь писать — я добавлю в функцию и буду вызывать func(’chsk’,’Кр’,4)

в) с возможностью варьировать эпитеты к одному слову и случайно и точно и изредка вводя новый эпитет.

г) функция и делит на 3 варианта 0,5—20/1/2-4.

д) функция избавляет от неграмотного «ноль патронов». Так не говорят «у меня ноль патронов», но в инвентаре и таблице допустимо и удобно. В тексте же «нет патронов»

Хитрый Пряник #1300 21.12.2014 18:20 (11 years ago)

Обновлено: ещё раз почищен код, более хитро задан диапазон.
Для тех, кому только одно слово склонять — простая версия функции.
Самый компактный выбор, который сумел сделать (i= 0/1/2):

i=0
if no (10<ld[1] and ld[1]<15):
	if ld[0]=1:i=i+1
	if 1<ld[0] and ld[0]<5: i=i+2 &!2—4, но 12—14 уже отсеяны
end
Хитрый Пряник #1300 21.12.2014 18:48 (11 years ago)

Aleks Versus, то что у тебя на две функции распепячено, у меня в итоге заняло 18 строк. При более компактном вызове и удобном заполнении вариантов. Бе-бе-бе :D
В общем изобретать велосипеды иногда не вредно. За помощь и указание на недочёты конечно же спасибо!

Log in or Register to post comments.