Jump to content


Работа с русскими символами в LSL


  • Please log in to reply
6 replies to this topic

#1 Mikhail Troncon

Mikhail Troncon

    Новичок на форуме

  • Пользователи
  • PipPip
  • 20 posts
  • Основной цех:Скриптеры
  • Второй цех:Строители
  • SL Status: 

Posted 19.01.08 - 02:22

Хочу сделать викторину (Buktopuha, quis) в SL.
Принцип следующий:
Скриптом в чат шепчется вопрос, например "1+2*3 =?"
1. если кто-то рядом стоящий говорит seven - скрипт награждает его, и переходит к следующему вопросу
2. если в течение минуты никто не ответил правильно - скрипт выдает одну из подсказок:
2.1. Первую букву ответа и точки вместо недостающих букв.
2.2. Все буквы ответа беспорядочно, например "veens"при ответе "seven"
3. если в течение пяти минут никто не отвтеил - скрипт переходит к следующему вопросу.

Возможны следующие варианты загрузки вопросов в скрипт:
- несколько notecard, и рандомная загрузка по одному вопросу/ответу из рандомной нотекарты
- загрузка каждого вопроса/ответа с вэб-сервера

А теперь сложность задачи:
при работе с английскими буквами - все окей. легко слова преобразуются в нижний регистр для сравнения с оригиналом, буквы слов легко помещаются в список, который потом перемешивается и т.д.
но т.к. делаю викторину для русского языка - нужно чтобы была возможность работать с кирилицей.

вижу следующие варианты решения:
либо научиться как-то работать с кирилицей внутри lsl, либо, если этот вариант технчиески возможен - поместить на вэбсервер еще один обработчик, который вместе с вопросом, ответом - также будет выдавать подсказку - т.е. обрабатвать ее непосредственно на вэбсервере. но тут все-равно остается проблема с переводом русских слов, вбитых пользователей в нижний регистр.

вопросы:
1. есть ли варианты решений, чтобы обойтись без выноса генератора подсказки на вэбсервер?
2. есть ли вообще возможность непосредственно в LSL производить манипуляции над кирилицей?

//States
//default - initilize
//get question from notecard
//say question and waiting answers

// ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
string curent_question;
string current_right_answer;
integer handle1;
integer hint_time;

default {
	state_entry() {
		llWhisper(0, "Let`s start!");
		state get_questions;
	}
}

state get_questions {
	state_entry(){
	curent_question = "1+2*3 =";
	current_right_answer = "seven";
	state get_answers_from_ppl;
	}
}

state get_answers_from_ppl {
	state_entry() {
	llWhisper(0,"Next question:");
	llWhisper(0,curent_question);
	handle1 = llListen(0,"",NULL_KEY,"");
	llSetTimerEvent(15);
	}

	listen(integer channel, string name, key id, string message){
	  if (llToLower(message) == current_right_answer)
		{
	  llSay(0,name + ", you are winner!!! Answer is: "+current_right_answer);
	  state get_questions;
	  }
	  }
  
	timer(){
				 hint_time=hint_time+1;
			if (hint_time == 1){
				llWhisper(0,"There is a hint N"+(string)hint_time);
				integer AnswerLenght = llStringLength(current_right_answer);
				string points = "";
				integer x;
				for (x=1;x<AnswerLenght;x++)
				{
					points = points + " .";
				};
				llWhisper(0,llGetSubString(current_right_answer,0,0)+(string)points);
			}
			else if (hint_time == 5) {
				llWhisper(0, "Five minutes in past. Nobody win!");
				llSetTimerEvent(0);
				state get_questions;
			}

	}
 
	state_exit() {llListenRemove(handle1); llSetTimerEvent(0); hint_time = 0;}
}


#2 SOb Zemlja

SOb Zemlja

    Активный участник

  • Главные администраторы
  • PipPipPipPip
  • 799 posts
  • Пол:М
  • Откуда:Россия, Москва
  • Основной цех:Строители
  • Второй цех:Скриптеры
  • SL Status: 

Posted 19.01.08 - 03:03

View PostMikhail Troncon, on 19.1.2008, 2:22, said:


вопросы:
1. есть ли варианты решений, чтобы обойтись без выноса генератора подсказки на вэбсервер?
2. есть ли вообще возможность непосредственно в LSL производить манипуляции над кирилицей?
И вопросы и подсказки мне кажется стоит держать на сервере.
Для проверки работы с кириллицей собери конструкцию вида

default
{
	state_entry()
	{
		llListen(0, "", NULL_KEY, "");
	}
	listen(integer channel, string name, key id, string message)
	{
		llSay(0, llToLower(message));
	}
}

и подставляя вместо llToLower различные функции проверь нужные тебе.
К примеру, llToLower игнорирует кириллицу.

#3 Mikhail Troncon

Mikhail Troncon

    Новичок на форуме

  • Пользователи
  • PipPip
  • 20 posts
  • Основной цех:Скриптеры
  • Второй цех:Строители
  • SL Status: 

Posted 19.02.08 - 07:53

сделал я все-таки переводчик в нижний регистр кирилических символов. проблема в том, что фразу в 90 символов он переводит в нижний регистр ни больше ни меньше, чем за 8 секунд на тормозных симах и за 5 секунд на скоростных симах.
естественно, что это никуда не годится.
может есть идеи как существенно ускорить этот скрипт или сделать по другому?

скрипт на Perl, который выдает все русские символы в нижнем и верхнем регистрах. в UTF-8

string URL="http://www.***.ru/cgi-bin/sl/perl4.pl";
key http;//This stores the HTTP request we send.

string upper_case;
string lower_case;
integer handle;




default {
    state_entry() {
        //state start;
        http=llHTTPRequest(URL, [] ,"");
    }

    http_response(key id,integer status, list meta, string body)
    {
        if(http==id)
        {
            list lbody=llParseString2List(body,["\n"],[]);
            integer count=llGetListLength(lbody);
            integer i;
            for(i=0;i<count;i++)
            {
                if (i==0){lower_case = llList2String(lbody,i);}
                else if (i==1){upper_case = llList2String(lbody,i);}
             }
         llSay(0,upper_case);
         llSay(0,lower_case);
         state to_lower;
         }
    }
}

state to_lower {
    state_entry() {
        handle = llListen(0,"",NULL_KEY,"");
    }

    listen(integer channel, string name, key id, string message) 
      {
            integer x;
            
            // разбиваем полученную строку и кладем ее посимвольно в массив
            integer msg_lenght = llStringLength(message);
            list msg_list;
            for(x=0;x<msg_lenght;x++)
            {
            msg_list = (msg_list = []) + msg_list + llGetSubString(message, x, x);
            };
            
            // заменяем во всех элементах массива все кириличиеские символы верхнего регистра на нижний регистр
            integer list_lenght = llGetListLength(msg_list);
            list result_list = [];
            
            for(x=0;x<list_lenght;x++)
                {
                string original_char = llList2String(msg_list, x);
                integer index = llSubStringIndex(upper_case, original_char);
                if (index != -1)
                    {
                    result_list = (result_list = []) + result_list + llGetSubString(lower_case, index,index);
                    }
                else
                    {
                    result_list = (result_list = []) + result_list + original_char;
                    }
                };
      
      //сращиваем массив обратно в строку
            string result_string;
            for(x=0;x<list_lenght;x++)
                {
                result_string = result_string + llList2String(result_list,x);
                }
      llSay(0,result_string);
      }
}





#4 SOb Zemlja

SOb Zemlja

    Активный участник

  • Главные администраторы
  • PipPipPipPip
  • 799 posts
  • Пол:М
  • Откуда:Россия, Москва
  • Основной цех:Строители
  • Второй цех:Скриптеры
  • SL Status: 

Posted 20.02.08 - 15:56

Написал вот такой код для перевода кириллицы в нижний регистр. Код замены отдельных символов (в одну строку) взят в lslwiki.

string URL="http://www.slcontent.ru/tools/cyrABC.php";
key http;
string lowerCyrABC = "";
string upperCyrABC = "";

string toLowerCyr(string source) {
	string result = source;
	integer i;
	for(i = 0; i < llStringLength(upperCyrABC); i++) {
		string l = llGetSubString(upperCyrABC, i, i);
		integer j = llSubStringIndex(result, l);
		if(j!=-1)
			result = llDumpList2String(llParseStringKeepNulls(result, [l], []), llGetSubString(lowerCyrABC, i, i));
	}
	return result;
}

default {
	state_entry() {
		http = llHTTPRequest(URL, [] ,"");
		llListen(0, "", NULL_KEY, "");
	}
	http_response(key id,integer status, list meta, string body) {
		if(http == id) {
			list lbody = llParseString2List(body, ["\n"], []);
			if(llGetListLength(lbody) != 2) {
				llSay(0, "Error when http_response");
				return;
			}
			lowerCyrABC = llList2String(lbody, 0);
			upperCyrABC = llList2String(lbody, 1);
		}
	}
	listen(integer channel, string name, key id, string message) {
		llSay(0, toLowerCyr(message));
	}
}


#5 Zuba Zenovka

Zuba Zenovka

    Новичок на форуме

  • Пользователи
  • PipPip
  • 55 posts
  • Пол:М
  • SL Status: 

Posted 22.04.08 - 12:20

>ЛСЛ-код, сначала заружает символы с сайта

офигеть! вы чё? вы не пробывали поехать в африку через северный полюс?.. зачем символы загружать с сайта когда их можно просто сгенерировать по коду символа прямо в скрипте? __почти__ все русские буквы идут по порядку (помойму кроме ё) тоже самое в принципе можно проделать с заменой регистра...и без загрузки и генерации строки символов...например по сдвигу

#6 SOb Zemlja

SOb Zemlja

    Активный участник

  • Главные администраторы
  • PipPipPipPip
  • 799 posts
  • Пол:М
  • Откуда:Россия, Москва
  • Основной цех:Строители
  • Второй цех:Скриптеры
  • SL Status: 

Posted 22.04.08 - 12:28

View PostZuba Zenovka, on 22.4.2008, 13:20, said:

>ЛСЛ-код, сначала заружает символы с сайта

офигеть! вы чё? вы не пробывали поехать в африку через северный полюс?.. зачем символы загружать с сайта когда их можно просто сгенерировать по коду символа прямо в скрипте? __почти__ все русские буквы идут по порядку (помойму кроме ё) тоже самое в принципе можно проделать с заменой регистра...и без загрузки и генерации строки символов...например по сдвигу
Зуб, поделись кодом, а? :)

#7 Zuba Zenovka

Zuba Zenovka

    Новичок на форуме

  • Пользователи
  • PipPip
  • 55 posts
  • Пол:М
  • SL Status: 

Posted 22.04.08 - 12:36

выдержки из моего очень старого скрипта (тогда кирилица не грузилась из нотекард)

string byte2hex(integer x) 
{
	string hexc="0123456789ABCDEF";
	return llGetSubString(hexc, x = ((x >> 4) & 0xF), x) + llGetSubString(hexc, (x & 0xF), (x & 0xF));
}
 
string UnicodeIntegerToUTF8(integer a)
{
	if(a <= 0) return "";
	integer b = (a >= 0x80) + (a >= 0x800) + (a >= 0x10000) + (a >= 0x200000) + (a >= 0x4000000);
	string c = "%" + byte2hex((a >> (6 * b)) | ((0x7F80 >> b) << !b));
	while(b)
		c += "%" + byte2hex((((a >> (6 * (b=~-b))) | 0x80) & 0xBF));
	return llUnescapeURL(c);
}

GenCharString()
{
	.........
	
	for (i=1040;i<1040+64;i++)
	{
		gCharIndex+=UnicodeIntegerToUTF8(i);
	}
	gCharIndex+=UnicodeIntegerToUTF8(1105); // добавляем ё и Ё помойму)))
	gCharIndex+=UnicodeIntegerToUTF8(1025); 
}





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users