Guest User

quiz_system

a guest
Jul 30th, 2014
248
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*=============================================================================
  2.         Quiz System
  3.             by Daniel_Cortez
  4.  
  5.         www.pro-pawn.ru
  6.  
  7. This code is licensed under the terms of zlib/libpng license.
  8.  
  9. Copyright (c) 2013 Daniel_Cortez
  10. This software is provided 'as-is', without any express or implied warranty.
  11. In no event will the authors be held liable for any damages arising from the
  12. use of this software. Permission is granted to anyone to use this software for
  13. any purpose, including commercial applications, and to alter it and
  14. redistribute it freely, subject to the following restrictions:
  15.     1.  The origin of this software must not be misrepresented; you must not
  16.         claim that you wrote the original software. If you use this software in
  17.         a product, an acknowledgment in the product documentation would be
  18.         appreciated but is not required.
  19.     2.  Altered source versions must be plainly marked as such, and must not be
  20.         misrepresented as being the original software.
  21.     3. This notice may not be removed or altered from any source distribution.
  22. =============================================================================*/
  23.  
  24. #include <a_samp>
  25. #include <dc_cmd>
  26.  
  27.  
  28. const
  29.     // time between each question (in seconds)
  30.     // (время между вопросами в секундах)
  31.     QUIZ_TIMEOUT                = 30,
  32.  
  33.     // prize for the correct answer ($)
  34.     // (награда за правильный ответ)
  35.     QUIZ_PRIZE                  = 2000,
  36.  
  37.     // min and max quantity of arithmetical operations in question
  38.     // (мин. и макс. кол-во арифметических операций в вопросе)
  39.     QUIZ_MIN_ARITHMETICAL_OPS   = 3,
  40.     QUIZ_MAX_ARITHMETICAL_OPS   = 5,
  41.  
  42.     // max length for question and answer respectively
  43.     // (макс. длина под вопрос и ответа соответственно)
  44.     QUIZ_MAX_QUESTION_LENGTH    = 63,
  45.     QUIZ_MAX_ANSWER_LENGTH      = 23,
  46.  
  47.     // max amount of answer variants in multiple-choice questions
  48.     // (макс. кол-во вариантов ответа)
  49.     QUIZ_MAX_ANSWER_OPTIONS     = 4;
  50.  
  51.  
  52. #define GivePrize(%0)\
  53.     GivePlayerMoney(%0, QUIZ_PRIZE) // можете заменить выдачу денег на свою, например на PlayerInfo[%0][pMoney] += QUIZ_PRIZE
  54.  
  55.  
  56. enum multiple_choice_question_info{
  57.     mcqQuestion[QUIZ_MAX_QUESTION_LENGTH+1],
  58.     mcqAnswers,
  59.     mcqCorrectAnswer,
  60.     mcqAnswer[QUIZ_MAX_ANSWER_OPTIONS*(QUIZ_MAX_ANSWER_LENGTH+1)]
  61. };
  62.  
  63. static const multiple_choice_questions[][multiple_choice_question_info] = {
  64.     {
  65.         {"Кто написал роман \"Война и мир\"?"},
  66.         // "4, 3" означает 4 варианта ответа, 3-й правильный
  67.         4, 3, {"А.С.Пушкин", "М.Ю.Лермонтов", "Л.Н.Толстой", "И.С.Тургенев"}
  68.     },
  69.     {
  70.         {"Кто был избран первым президентом Российской Федерации?"},
  71.         // 3 варианта ответа
  72.         3, 2, {"В.В.Путин", "Б.Н.Ельцин", "Д.А.Медведев"}
  73.     }
  74. };
  75.  
  76.  
  77. enum single_choice_question_info{
  78.     scqQuestion[QUIZ_MAX_QUESTION_LENGTH],
  79.     scqAnswer[QUIZ_MAX_ANSWER_LENGTH]
  80. };
  81.  
  82. static const single_choice_questions[][single_choice_question_info] = {
  83.     {
  84.         {"Назовите самую длинную в мире реку."},
  85.         {"Амазонка"}
  86.     },
  87.     {
  88.         {"Какая страна имеет самую большую в мире площадь территории?"},
  89.         {"Россия"}
  90.     }
  91. };
  92.  
  93.  
  94.  
  95. // Check some constant values
  96. // (проверить значение констант)
  97. // Too bad there's no way to correctly show errors in Russian. Oh well...
  98. #if QUIZ_MIN_ARITHMETICAL_OPS <= 1
  99.     #error QUIZ_MIN_ARITHMETICAL_OPS must be more than 1
  100. #endif
  101.  
  102.  
  103. static
  104.     cur_question_answer[QUIZ_MAX_ANSWER_LENGTH],
  105.     cur_quiz_player_answered[MAX_PLAYERS char] = {0, ...},
  106.     cur_quiz_answered = 0;
  107.  
  108.  
  109. CMD:quiz(playerid, params[]){
  110.     if(cur_quiz_answered)
  111.         return SendClientMessage(playerid, -1, "На этот вопрос уже ответили, попробуйте позже.");
  112.     if(cur_quiz_player_answered{playerid})
  113.         return SendClientMessage(playerid, -1, "Вы уже ответили на этот вопрос, попробуйте позже.");
  114.     if(isnull(params))
  115.         return SendClientMessage(playerid, -1, "Использование: /quiz [Ваш ответ]");
  116.     if(strcmp(params, cur_question_answer, true) == 0)
  117.     {
  118.         static const
  119.             fmt_str0[] = "Викторина: Поздравляем, Вы правильно ответили на вопрос и получили вознаграждение: $%d.",
  120.             fmt_str1[] = "Викторина: Игрок %s правильно ответил на вопрос. Ответ: %s.";
  121.         const
  122.             size0 = sizeof(fmt_str0)-2+11,
  123.             size1 = sizeof(fmt_str1)-2+MAX_PLAYER_NAME-2+QUIZ_MAX_ANSWER_LENGTH;
  124.         #if size0>size1
  125.         const size = size0;
  126.         #else
  127.         const size = size1;
  128.         #endif
  129.         new string[size];
  130.         format(string, sizeof(string), fmt_str0, QUIZ_PRIZE);
  131.         SendClientMessage(playerid, -1, string);
  132.         GetPlayerName(playerid, string, sizeof(string));
  133.         format(string, sizeof(string), fmt_str1, string, cur_question_answer);
  134.         SendClientMessageToAll(-1, string);
  135.         GivePrize(playerid);
  136.         cur_quiz_answered = 1;
  137.     }
  138.     else
  139.         SendClientMessage(playerid, -1, "Викторина: К сожалению, это неправильный ответ, попробуйте в следующий раз!");
  140.     cur_quiz_player_answered{playerid} = 1;
  141.     return 1;
  142. }
  143.  
  144.  
  145. // don't look at that code, it's horrible -_-
  146. @___dc_quiz_timer();
  147. @___dc_quiz_timer(){
  148.     for(new i=0; i<sizeof(cur_quiz_player_answered)*(cellbits/charbits); ++i)
  149.         cur_quiz_player_answered{i} = 0;
  150.     cur_quiz_answered = 0;
  151.     enum questionType{
  152.         QUESTION_TYPE_ARITHMETICAL,
  153.         QUESTION_TYPE_MULTIPLE_CHOICE,
  154.         QUESTION_TYPE_SINGLE_CHOICE
  155.     };
  156.     new question_type = random(_:questionType);
  157.     switch(question_type){
  158.         case QUESTION_TYPE_ARITHMETICAL:{
  159.             enum question_ops{
  160.                 // Dividing is not implemented to avoid confusion of players
  161.                 // with answer format (ex. "1024" or "1024.0").
  162.                 // Деление не реализовано, чтобы игроки не путались с форматом
  163.                 // ответа (пример: "1024" или "1024.0")
  164.                 QUESTION_OP_ADD,
  165.                 QUESTION_OP_SUB,
  166.                 QUESTION_OP_MUL
  167.             };
  168.             static const question_op_signs[_:question_ops] = {'+', '-', '*'};
  169.             new op_count = QUIZ_MIN_ARITHMETICAL_OPS+random(QUIZ_MAX_ARITHMETICAL_OPS-QUIZ_MIN_ARITHMETICAL_OPS+1);
  170.             new result = random(1000);
  171.             new rand, op, last_operand = result;
  172.             static const question_arithmetical_fmt_str[] = "Викторина: Сколько будет %s ?";
  173.             new string[sizeof(question_arithmetical_fmt_str)-2+(3)+(1+1)*(QUIZ_MAX_ARITHMETICAL_OPS-1)];
  174.             valstr(string, result);
  175.             for(new i=1; i<op_count; ++i){
  176.                 rand = 1+random(9);
  177.                 op = random(_:question_ops);
  178.                 switch(op){
  179.                     case QUESTION_OP_ADD:{
  180.                         result += rand;
  181.                         last_operand = rand;
  182.                     }
  183.                     case QUESTION_OP_SUB:{
  184.                         result -= rand;
  185.                         last_operand = -rand;
  186.                     }
  187.                     case QUESTION_OP_MUL:{
  188.                         result -= last_operand;
  189.                         last_operand *= (rand);
  190.                         result += last_operand;
  191.                     }
  192.                 }
  193.                 format(string, sizeof(string), "%s%c%d", string, question_op_signs[op], rand);
  194.             }
  195.             format(string, sizeof(string), question_arithmetical_fmt_str, string);
  196.             SendClientMessageToAll(0xF0F080FF, string);
  197.             SendClientMessageToAll(0xF0F080FF, "Для ответа используйте {00d0f0}/quiz [ответ]");
  198.             format(cur_question_answer, sizeof(cur_question_answer), "%d", result);
  199.         }
  200.         case QUESTION_TYPE_MULTIPLE_CHOICE:{
  201.             static const multiple_choice_question_str[] = "Викторина: ";
  202.             new string[sizeof(multiple_choice_question_str)+QUIZ_MAX_QUESTION_LENGTH];
  203.             new rand = random(sizeof(multiple_choice_questions));
  204.             string = multiple_choice_question_str;
  205.             strcat(string, multiple_choice_questions[rand][mcqQuestion]);
  206.             SendClientMessageToAll(0xF0F080FF, string);
  207.             for(new i=0,j=0,pos; i<multiple_choice_questions[rand][mcqAnswers]; ++i){
  208.                 format(string, sizeof(string), "\t%d. ", i+1);
  209.                 pos = strlen(string);
  210.                 for(; j<(QUIZ_MAX_ANSWER_LENGTH+1)*QUIZ_MAX_ANSWER_OPTIONS; ){
  211.                     string[pos++] = multiple_choice_questions[rand][mcqAnswer][j];
  212.                     if(multiple_choice_questions[rand][mcqAnswer][j++] == '\0')
  213.                         break;
  214.                 }
  215.                 SendClientMessageToAll(0xF0F080FF, string);
  216.             }
  217.             SendClientMessageToAll(0xF0F080FF, "Для ответа используйте {00d0f0}/quiz [номер ответа]");
  218.             format(cur_question_answer, sizeof(cur_question_answer), "%d", multiple_choice_questions[rand][mcqCorrectAnswer]);
  219.         }
  220.         case QUESTION_TYPE_SINGLE_CHOICE:{
  221.             static const single_choice_question_str[] = "Викторина: ";
  222.             new string[sizeof(single_choice_question_str)+QUIZ_MAX_QUESTION_LENGTH];
  223.             new rand = random(sizeof(single_choice_questions));
  224.             string = single_choice_question_str;
  225.             strcat(string, single_choice_questions[rand][scqQuestion]);
  226.             SendClientMessageToAll(0xF0F080FF, string);
  227.             cur_question_answer[0] = '\0', strcat(cur_question_answer, single_choice_questions[rand][scqAnswer]);
  228.             SendClientMessageToAll(0xF0F080FF, "Для ответа используйте {00d0f0}/quiz [ответ]");
  229.         }
  230.     }
  231. }
  232.  
  233. public OnGameModeInit(){
  234.     print(
  235.         "#========================================#\n"\
  236.         "#  Quiz System by Daniel_Cortez loaded.  #\n"\
  237.         "#    (c) 2013 Daniel_Cortez              #\n"\
  238.         "#            www.pro-pawn.ru             #\n"\
  239.         "#========================================#"
  240.     );
  241.     SetTimer("@___dc_quiz_timer", QUIZ_TIMEOUT*1000, 1);
  242.     #if defined quiz_sys__OnGameModeInit
  243.     quiz_sys__OnGameModeInit();
  244.     #endif
  245.     return 1;
  246. }
  247. #if defined _ALS_OnGameModeInit
  248.     #undef  OnGameModeInit
  249. #else
  250.     #define _ALS_OnGameModeInit
  251. #endif
  252. #define OnGameModeInit  quiz_sys__OnGameModeInit
  253. #if defined quiz_sys__OnGameModeInit
  254.     forward quiz_sys__OnGameModeInit();
  255. #endif
RAW Paste Data