home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 19 / CD_ASCQ_19_010295.iso / vrac / odoors50.zip / EX_VOTE2.C < prev    next >
C/C++ Source or Header  |  1994-09-24  |  22KB  |  577 lines

  1. /* EX_VOTE2.C - The files ex_vote1.c thru ex_vote5.c demonstrate the         */
  2. /*              possible steps in the development of a door program using    */
  3. /*              OpenDoors. The EZVote door program allows users to create    */
  4. /*              questions or surveys for other users to respond to. Users    */
  5. /*              are also able to view the results of voting on each topic    */
  6. /*              after having voted on the topic themselves.                  */
  7. /*                                                                           */
  8. /*              To recompile this program, follow the instructions in the    */
  9. /*              OpenDoors manual. Be sure to set your compiler to use the    */
  10. /*              large memory model, and add the ODOORL.LIB file to your      */
  11. /*              project/makefile.                                            */
  12. /*                                                                           */
  13. /*              Each of the ex_vote?.c files shows a further incremental     */
  14. /*              step in the construction of the EZVote door program, as      */
  15. /*              follows:                                                     */
  16. /*                                                                           */
  17. /*              EX_VOTE1.C - Demonstrates the basic elements of any door     */
  18. /*                           program. Contains the code to handle display    */
  19. /*                           of main menu, responding to the user's choice   */
  20. /*                           from the main menu, and common commands such    */
  21. /*                           as returning to the BBS and paging the system   */
  22. /*                           operator. Demonstrates basics of displaying     */
  23. /*                           text and retrieving input from user.            */
  24. /*                                                                           */
  25. /*              EX_VOTE2.C - Adds the user interface code to handle the main */
  26. /*                           menu commands specific to EZVote, such as       */
  27. /*                           answering questions, viewing the results of     */
  28. /*                           questions, and adding new questions.            */
  29. /*                           Demonstrates the use of OpenDoors functions     */
  30. /*                           such as od_input_str() for allowing the user to */
  31. /*                           input a sring of characters, and od_get_key()   */
  32. /*                           for inputting any character from the user. Also */
  33. /*                           introduces the od_control structure for         */
  34. /*                           obtaining information about the user and the    */
  35. /*                           system that the door program is running on.     */
  36. /*                                                                           */
  37. /*              EX_VOTE3.C - Adds the underlying file access functionality   */
  38. /*                           that is specific to EZVote. EZVote uses a       */
  39. /*                           relatively complex file structure in order to   */
  40. /*                           track which questions each user has voted on,   */
  41. /*                           and in order to allow a large number (200)      */
  42. /*                           question records to be stored in the file.      */
  43. /*                                                                           */
  44. /*              EX_VOTE4.C - Adds color to display and demonstrates the use  */
  45. /*                           of ANSI/AVATAR/RIP specific features.           */
  46. /*                                                                           */
  47. /*              EX_VOTE5.C - Adds support for the OpenDoors configuration    */
  48. /*                           file system, which provides automatic support   */
  49. /*                           for a wide variety of configurable options.     */
  50. /*                           EZVote adds its own configuration options to    */
  51. /*                           control program characteristics such as whether */
  52. /*                           or not the user is premitted to create their    */
  53. /*                           own questions. Also adds support for the        */
  54. /*                           OpenDoors log file system which records major   */
  55. /*                           actions taken by the user. In addition, this    */
  56. /*                           step enables the OpenDoors multiple-personality */
  57. /*                           system and adds other finishing touches.        */
  58.  
  59.  
  60. /* Include standard C header files required by EZVote. */
  61. #include <string.h>
  62. #include <stdlib.h>
  63. #include <ctype.h>
  64.  
  65. /* Include the OpenDoors header file. This line must be done in any program */
  66. /* using OpenDoors.                                                         */
  67. #include "opendoor.h"
  68.  
  69.  
  70. /* Manifest constants used by EZVote */
  71. #define NO_QUESTION              -1
  72. #define NEW_ANSWER               -1
  73.  
  74. #define QUESTION_PAGE_SIZE        17
  75.  
  76.  
  77. /* Prototypes for functions that form EZVote */
  78. void VoteOnQuestion(void);
  79. void ViewResults(void);
  80. void AddQuestion(void);
  81. void DeleteQuestion(void);
  82. int ChooseQuestion(char *pszTitle);
  83. void DisplayQuestionResult(void);
  84. void WaitForEnter(void);
  85.  
  86.  
  87. /* main() function - Program execution begins here. */
  88. main()
  89. {
  90.    /* Variable to store user's choice from the menu */
  91.    char chMenuChoice;
  92.    char chYesOrNo;
  93.  
  94.    /* Initialize OpenDoors. This function call is optional, and can be used */
  95.    /* to force OpenDoors to read the door informtion file and begin door    */
  96.    /* operations. If a call to od_init() is not included in your program,   */
  97.    /* OpenDoors initialization will be performed at the time of your first  */
  98.    /* call to any OpenDoors function. */
  99.    od_init();
  100.  
  101.    /* Loop until the user choses to exit the door. For each iteration of  */
  102.    /* this loop, we display the main menu, get the user's choice from the */
  103.    /* menu, and perform the appropriate action for their choice.          */
  104.  
  105.    for(;;)
  106.    {
  107.       /* Clear the screen */
  108.       od_clr_scr();
  109.  
  110.       /* Display main menu */
  111.       od_printf("                    EZVote - OpenDoors 5.00 demonstration Door\n\r");
  112.       od_printf("-------------------------------------------------------------------------------\n\r\n\r\n\r");
  113.       od_printf("                        [V] Vote on a question\n\r\n\r");
  114.       od_printf("                        [R] View the results of question\n\r\n\r");
  115.       od_printf("                        [A] Add a new question\n\r\n\r");
  116.       
  117.       /* If current user is the system operator, add a D function to permit */
  118.       /* deletion of unwanted questions.                                    */
  119.       if(strcmp(od_control.sysop_name, od_control.user_name) == 0)
  120.       {
  121.          od_printf("                        [D] Delete a question\n\r\n\r");
  122.       }
  123.       od_printf("                        [P] Page system operator for chat\n\r\n\r");
  124.       od_printf("                        [E] Exit door and return to the BBS\n\r\n\r");
  125.       od_printf("                        [H] End call (hangup)\n\r\n\r\n\r");
  126.       od_printf("Press the key corresponding to the option of your choice.\n\r");
  127.  
  128.       /* Get the user's choice from the main menu. This choice may only be */
  129.       /* V, R, A, D, P, E or H.                                            */
  130.       chMenuChoice = od_get_answer("VRADPEH");
  131.  
  132.       /* Perform the appropriate action based on the user's choice */
  133.       switch(chMenuChoice)
  134.       {
  135.          case 'V':
  136.             /* Call EZVote's function to vote on question */
  137.             VoteOnQuestion();
  138.             break;
  139.             
  140.          case 'R':
  141.             /* Call EZVote's function to view the results of voting */
  142.             ViewResults();
  143.             break;
  144.             
  145.          case 'A':
  146.             /* Call EZVote's function to add a new question */
  147.             AddQuestion();
  148.             break;
  149.  
  150.          case 'D':
  151.             /* Call EZVote's funciton to delete an existing question */
  152.             DeleteQuestion();
  153.             break;
  154.             
  155.          case 'P':
  156.             /* If the user pressed P, allow them page the system operator. */
  157.             od_page();
  158.             break;
  159.  
  160.          case 'E':
  161.             /* If the user pressed E, exit door and return to BBS. */
  162.             od_exit(0, FALSE);
  163.             break;
  164.  
  165.          case 'H':
  166.             /* If the user pressed H, ask whether they wish to hangup. */
  167.             od_printf("\n\rAre you sure you wish to hangup? (Y/N) ");
  168.  
  169.             /* Get user's response */
  170.             chYesOrNo = od_get_answer("YN");
  171.  
  172.             /* If user answered yes, exit door and hangup */
  173.             if(chYesOrNo == 'Y')
  174.             {
  175.                od_exit(0, TRUE);
  176.             }
  177.             break;
  178.       }
  179.    }
  180.  
  181.    return(0);
  182. }
  183.  
  184.  
  185. /* EZVote calls the VoteOnQuestion() function when the user chooses the   */
  186. /* vote command from the main menu. This function displays a list of      */
  187. /* available topics, asks for the user's answer to the topic they select, */
  188. /* and display's the results of voting on that topic.                     */
  189. void VoteOnQuestion(void)
  190. {
  191.    int nQuestion;
  192.    int nAnswer;
  193.    char szNewAnswer[41];
  194.    char szUserInput[3];
  195.    
  196.    /* Loop until the user chooses to return to the main menu, or until */
  197.    /* there are no more questions to vote on.                          */
  198.    for(;;)   
  199.    {
  200.       /* Allow the user to choose a question from the list of questions */
  201.       /* that they have not voted on.                                   */
  202.       nQuestion = ChooseQuestion("                              Vote On A Question\n\r");
  203.  
  204.       /* If the user did not choose a question, return to main menu. */
  205.       if(nQuestion == NO_QUESTION)
  206.       {
  207.          return;
  208.       }
  209.  
  210.       /* Loop until user makes a valid respose. */
  211.       for(;;)
  212.       {
  213.          /* Display question to user. */
  214.  
  215.          /* Clear the screen. */
  216.          od_clr_scr();
  217.  
  218.          /* Display question itself. */
  219.          od_printf("The Question will appear here.\n\r\n\r");
  220.  
  221.          /* Loop for each answer to the question. */
  222.          for(nAnswer = 0; nAnswer < 10; ++nAnswer)
  223.          {
  224.             /* Display answer number and answer. */
  225.             od_printf("%d. This is a possible answer.\n\r", nAnswer + 1);
  226.          }
  227.  
  228.          /* Display prompt to user. */
  229.          od_printf("\n\rEnter answer number, [A] to add your own response, [Q] to quit: ");
  230.  
  231.          /* Get response from user. */
  232.          od_input_str(szUserInput, 2, ' ', 255);
  233.          /* Add a blank line. */
  234.          od_printf("\n\r");
  235.  
  236.          /* If user entered Q, return to main menu. */
  237.          if(stricmp(szUserInput, "Q") == 0)
  238.          {
  239.             return;
  240.          }
  241.  
  242.          /* If user enetered A, and adding answers is premitted ... */
  243.          else if (stricmp(szUserInput, "A") == 0)
  244.          {
  245.             /* ... Prompt for answer from user. */
  246.             od_printf("Please enter your new answer:\n\r");
  247.             od_printf("[------------------------------]\n\r ");
  248.  
  249.             /* Get string from user. */
  250.             od_input_str(szNewAnswer, 30, ' ', 255);
  251.  
  252.             /* Record that user entered a new answer answer. */
  253.             nAnswer = NEW_ANSWER;
  254.  
  255.             /* If user entered a valid answer, then exit loop. */
  256.             if(strlen(szNewAnswer) > 0)
  257.             {
  258.                break;
  259.             }
  260.          }
  261.  
  262.          /* Otherwise, attempt to get answer number from user. */
  263.          nAnswer = atoi(szUserInput) - 1;
  264.  
  265.          /* If user input is not a valid answer. */
  266.          if(nAnswer < 0 || nAnswer >= 10)
  267.          {
  268.             /* Display message. */
  269.             od_printf("That is not a valid response.\n\r");
  270.             WaitForEnter();
  271.          }
  272.          else
  273.          {
  274.             /* Otherwise, exit loop. */
  275.             break;
  276.          }
  277.       }
  278.  
  279.       /* Display the result of voting on this question to the user. */
  280.       DisplayQuestionResult();
  281.    }
  282. }
  283.  
  284.  
  285. /* The ViewResults function is called when the user chooses the "view    */
  286. /* results" command from the main menu. This function alows the user to  */
  287. /* choose a question from the list of questions, and then displays the   */
  288. /* results of voting on that question.                                   */
  289. void ViewResults(void)
  290. {
  291.    int nChoice;
  292.  
  293.    /* Loop until user chooses to return to main menu. */
  294.    for(;;)
  295.    {   
  296.       /* Allow the user to choose a question from the list of questions that */
  297.       /* they have already voted on.                                         */
  298.       nChoice = ChooseQuestion("                                 View Results\n\r");
  299.  
  300.       /* If the user did not choose a question, return to main menu. */
  301.       if(nChoice == NO_QUESTION)
  302.       {
  303.          return;
  304.       }
  305.  
  306.       /* Display the results for the selected question. */
  307.       DisplayQuestionResult();
  308.    }
  309. }
  310.  
  311.  
  312. /* The AddQuestion() function is called when the user chooses the "add    */
  313. /* question" option from the main menu. This function allows the user     */
  314. /* to enter a new question, possible responses, and save the question for */
  315. /* other users to vote on.                                                */
  316. void AddQuestion(void)
  317. {
  318.    char szUserInput[71];
  319.    int nAnswerNumber;
  320.  
  321.    /* Clear the screen. */
  322.    od_clr_scr();
  323.    
  324.    /* Display screen header. */
  325.    od_printf("                                Add A Question\n\r");
  326.    od_printf("-------------------------------------------------------------------------------\n\r\n\r");
  327.    
  328.    /* Obtain quesiton text from the user. */
  329.    od_printf("Enter Your Question (blank line cancels)\n\r");
  330.    od_printf("[----------------------------------------------------------------------]\n\r ");
  331.    od_input_str(szUserInput, 70, ' ', 255);
  332.    
  333.    /* If question was empty, then return to main menu. */
  334.    if(strlen(szUserInput) == 0)
  335.    {
  336.       return;
  337.    }
  338.    
  339.    /* Display prompt for answers. */
  340.    od_printf("\n\rEnter Possible Answers (blank line when done)\n\r");
  341.    od_printf("   [------------------------------]\n\r");
  342.    
  343.    /* Loop, getting answers from user. */
  344.    for(nAnswerNumber = 1; nAnswerNumber <= 10; nAnswerNumber++)
  345.    {
  346.       /* Display prompt with answer number. */
  347.       od_printf("%2d: ", nAnswerNumber);
  348.       
  349.       /* Get string from user. */
  350.       od_input_str(szUserInput, 30, ' ', 255);
  351.          
  352.       /* If string was empty, then exit loop. */
  353.       if(strlen(szUserInput) == 0)
  354.       {
  355.          break;
  356.       }
  357.    }
  358.    
  359.    /* If no answers were supplied, then cancel, returning to main menu. */
  360.    if(nAnswerNumber == 1)
  361.    {
  362.       return;
  363.    }
  364.  
  365.    /* Ask whether users should be able to add their own answers. */
  366.    od_printf("\n\rShould voters be able to add their own options? (Y/N) ");
  367.    
  368.    /* Get answer from user. */
  369.    if(od_get_answer("YN") == 'Y')
  370.    {
  371.       /* If user pressed the 'Y' key. */
  372.       od_printf("Yes\n\r\n\r");
  373.    }
  374.    else
  375.    {
  376.       /* If user pressed the 'N' key. */
  377.       od_printf("No\n\r\n\r");
  378.    }
  379.    
  380.    /* Confirm save of new question. */
  381.    od_printf("Do you wish to save this new question? (Y/N) ");
  382.  
  383.    /* Get response from user. */
  384.    od_get_answer("YN");
  385. }
  386.  
  387.  
  388. /* The DeleteQuestion() function is called when the sysop chooses the   */
  389. /* "delete question" option from the main menu. This function displays  */
  390. /* a list of all questions, allowing the sysop to choose a question for */
  391. /* deletion.                                                            */
  392. void DeleteQuestion(void)
  393. {
  394.    int nQuestion;
  395.  
  396.    /* Check that user is system operator. */
  397.    if(strcmp(od_control.user_name, od_control.sysop_name) != 0)
  398.    {
  399.       return;
  400.    }
  401.  
  402.    /* Allow the user to choose a question from the list of all questions. */
  403.    nQuestion = ChooseQuestion("                              Delete A Question\n\r");
  404.  
  405.    /* If the user did not choose a question, return to main menu. */   
  406.    if(nQuestion == NO_QUESTION)
  407.    {
  408.       return;
  409.    }
  410.  
  411.    /* Confirm deletion of this question. */
  412.    od_printf("\n\rAre you sure you want to delete the question:\n\r");
  413.    od_printf("    Question will appear here.\n\r");
  414.    od_printf("[Y]es or [N]o?\n\r");
  415.  
  416.    /* Get response from user. */
  417.    od_get_answer("YN");
  418. }
  419.  
  420.  
  421. /* The ChooseQuestion() function will provide a list of questions and will */
  422. /* allow the user to choose a particular question, cancel back to the main */
  423. /* menu, and page up and down in the list of questions.                    */
  424. int ChooseQuestion(char *pszTitle)
  425. {
  426.    int nCurrent;
  427.    int nPagedToQuestion = 0;
  428.    char chCurrent;
  429.    
  430.    /* Loop, displaying current page of questions, until the user makes a */
  431.    /* choice.                                                            */
  432.    for(;;)
  433.    {
  434.       /* Clear the screen. */
  435.       od_clr_scr();
  436.  
  437.       /* Display header. */
  438.       od_printf(pszTitle);
  439.       od_printf("-------------------------------------------------------------------------------\n\r");
  440.    
  441.       /* Display list of questions on this page. */
  442.       for(nCurrent = 0;
  443.          nCurrent < QUESTION_PAGE_SIZE;
  444.          ++nCurrent)
  445.       {
  446.          /* Determine character to display for current line. */
  447.          if(nCurrent < 9)
  448.          {
  449.             chCurrent = (char)('1' + nCurrent);
  450.          }
  451.          else
  452.          {
  453.             chCurrent = (char)('A' + (nCurrent - 9));
  454.          }
  455.       
  456.          /* Display this question's title. */
  457.          od_printf("%c. A Question's title will appear here\n\r", chCurrent);
  458.       }
  459.  
  460.       /* Display prompt for input. */
  461.       od_printf("\n\r[Page %d]  Choose a question or",
  462.          (nPagedToQuestion / QUESTION_PAGE_SIZE) + 1);
  463.       if(nPagedToQuestion < 80 - QUESTION_PAGE_SIZE)
  464.       {
  465.          od_printf(" [N]ext page,");
  466.       }
  467.       if(nPagedToQuestion > 0)
  468.       {
  469.          od_printf(" [P]revious page,");
  470.       }
  471.       od_printf(" [Q]uit.\n\r");
  472.       
  473.       /* Loop until the user makes a valid choice. */
  474.       for(;;)
  475.       {      
  476.          /* Get input from user */
  477.          chCurrent = (char)od_get_key(TRUE);
  478.          chCurrent = (char)toupper(chCurrent);
  479.       
  480.          /* Respond to user's input. */
  481.       
  482.          /* If user pressed Q key. */
  483.          if(chCurrent == 'Q')
  484.          {
  485.             /* Return without a choosing a question. */
  486.             return(NO_QUESTION);
  487.          }
  488.       
  489.          /* If user pressed P key. */
  490.          else if(chCurrent == 'P')
  491.          {
  492.             /* If we are not at the first page. */
  493.             if(nPagedToQuestion > 0)
  494.             {
  495.                /* Move paged to location up one page. */
  496.                nPagedToQuestion -= QUESTION_PAGE_SIZE;
  497.                
  498.                /* Exit user input loop to display next page. */
  499.                break;
  500.             }
  501.          }
  502.       
  503.          /* If user pressed N key. */
  504.          else if(chCurrent == 'N')
  505.          {
  506.             /* If there is more questions after this page. */
  507.             if(nPagedToQuestion < 80)
  508.             {
  509.                /* Move paged.to location down one page. */
  510.                nPagedToQuestion += QUESTION_PAGE_SIZE;
  511.  
  512.                /* Exit user input loop to display next page. */
  513.                break;
  514.             }
  515.          }
  516.       
  517.          /* Otherwise, check whether the user chose a valid question. */
  518.          else if ((chCurrent >= '1' && chCurrent <= '9')
  519.             || (chCurrent >= 'A' && chCurrent <= 'H'))
  520.          {
  521.             /* Return actual question number in file. */
  522.             return(0);
  523.          }
  524.       }
  525.    }
  526. }
  527.  
  528.  
  529. /* The DisplayQuestionResult() function is called to display the results */
  530. /* of voting on a paricular question. This function is called when the   */
  531. /* user selects a question using the "view results" option, and is also  */
  532. /* called after the user has voted on a question, to display the results */
  533. /* of voting on that question.                                           */
  534. void DisplayQuestionResult(void)
  535. {
  536.    int nAnswer;
  537.  
  538.    /* Clear the screen. */
  539.    od_clr_scr();
  540.  
  541.    /* Display question itself. */
  542.    od_printf("The Question will appear here.\n\r");
  543.  
  544.    /* Display author's name. */
  545.    od_printf("Question created by ?????? on ??????\n\r\n\r");
  546.    
  547.    /* Display heading for responses. */
  548.    od_printf("Response                        Votes  Percent  Graph\n\r");
  549.    od_printf("-------------------------------------------------------------------------------\n\r");
  550.  
  551.    /* Loop for each answer to the question. */   
  552.    for(nAnswer = 0; nAnswer < 10; ++nAnswer)
  553.    {
  554.       /* Display answer, total votes and percentage of votes. */
  555.       od_printf("??????????????????????????????  ?????  ???      ===============================\n\r");
  556.    }
  557.    
  558.    /* Display footer. */
  559.    od_printf("-------------------------------------------------------------------------------\n\r");
  560.    od_printf("                         TOTAL: ???\n\r\n\r");
  561.    
  562.    /* Wait for user to press enter. */
  563.    WaitForEnter();
  564. }
  565.  
  566.  
  567. /* The WaitForEnter() function is used by EZVote to create its custom */
  568. /* "Press [ENTER] to continue." prompt.                               */
  569. void WaitForEnter(void)
  570. {
  571.    /* Display prompt. */
  572.    od_printf("Press [ENTER] to continue.\n\r");
  573.    
  574.    /* Wait for a Carriage Return or Line Feed character from the user. */
  575.    od_get_answer("\n\r");
  576. }
  577.