ncurses(또는 curses) 는 Linux/Unix 계열의 환경에서 VT100 등의 터미널과 호환되는 윈도우형 입출력 라이브러이다. 이를 이용하면 윈도우의 임의의 위치에 출력도 하고, 임의의 위치에서 입력을 받을 수도 있다.

* 카라슈바 곱셈 참조

다음은 Linux 나 Cygwin 환경이면 gcc 로 컴파일하여 실행되는 C 소스이다.

 

/*
 * Filename: ezmult_003.c
 *
 * Compile: gcc -o ezmult_003 ezmult_003.c -lform -lncurses
 *
 * Execute: ./ezmult_003
 *
 *    Date: 2014. 1. 6. (Mon)  v0.002
 *    Date: 2014. 1. 8. (Wed)  v0.003
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <form.h>
#include <ncurses.h>

int main()
{
    int x0, y0, z0;
    int s01, s02, t0;
    int x, y, z;
    int s1, s2, t;
    int i, j;
    int flag_insert_mode = 1;
    int o1 = 0;
    int o2 = 0;
    int o3 = 0;

    FIELD *field[4];
    FORM  *my_form;
    int ch;
 
    /* curses 초기화하기 */
    initscr();
    start_color();    // 색상을 사용하려면 initscr() 호출 후 즉시 이를 호출해야 함
    nonl();            // 필드에서 엔터 키가 작용되게 하기 위함
    cbreak();
    noecho();
    keypad(stdscr, TRUE);


    srand(time(NULL));
    x = rand()/(RAND_MAX + 1.0)*90 + 10;
    y = rand()/(RAND_MAX + 1.0)*90 + 10;
    z = x*y;
    s1 = (x/10)*(y/10);
    s2 = (x%10)*(y%10);
    t = (x/10)*(y%10) + (x%10)*(y/10);
   
    if (s1 < 10)
    {
         o1 = 1;
    }
    if (t < 100)
    {
         o2 = 1;
    }
    if (z < 1000)
    {
         o3 = 1;
    }
    refresh();
    

    /* 필드 초기화 */
    field[0] = new_field(1, 4-o1,  6, 14+o1, 0, 0);
    field[1] = new_field(1, 3-o2,  7, 14+o2, 0, 0);
    field[2] = new_field(1, 4-o3,  9, 14+o3, 0, 0);
    field[3] = NULL;


    /* 폼 생성하여 붙여 넣기 */
    my_form = new_form(field);
    post_form(my_form);
    refresh();


     /* 색상 초기화 */
    init_pair(1, COLOR_WHITE, COLOR_GREEN);
    init_pair(2, COLOR_WHITE, COLOR_GREEN);
    init_pair(3, COLOR_WHITE, COLOR_GREEN);
    init_pair(4, COLOR_MAGENTA, COLOR_BLACK);
    init_pair(5, COLOR_CYAN, COLOR_BLACK); 
    init_pair(6, COLOR_WHITE, COLOR_BLACK);
    init_pair(7, COLOR_BLACK, COLOR_WHITE);


    x0 = rand()/(RAND_MAX + 1.0)*90 + 10;
    y0 = rand()/(RAND_MAX + 1.0)*90 + 10;
    z0 = x0*y0;
    s01 = (x0/10)*(y0/10);
    s02 = (x0%10)*(y0%10);
    t0 = (x0/10)*(y0%10) + (x0%10)*(y0/10);


    mvprintw(3, 4, "%4d", x0);
    mvprintw(4, 3, "x%4d", y0);
    mvprintw(5, 3, "-----");
    mvprintw(6, 4, "%2d%02d", s01, s02);
    mvprintw(7, 4, "%3d", t0);
    mvprintw(8, 3, "-----");
    mvprintw(9, 4, "%4d", z0);
    refresh();


    mvprintw(3, 14, "%4d", x);
    mvprintw(4, 13, "x%4d", y);
    mvprintw(5, 13, "-----");
    mvprintw(8, 13, "-----");
    attron(COLOR_PAIR(7));
    mvprintw(0, 0, "Ins");
    attron(COLOR_PAIR(6));
    move(6, 14);
    refresh();


    set_field_type(field[0], TYPE_INTEGER, 0, 0, 9999);
    set_field_type(field[1], TYPE_INTEGER, 0, 0, 999);
    set_field_type(field[2], TYPE_INTEGER, 0, 0, 9999);
    field_opts_on(field[0], O_EDIT);
    field_opts_on(field[1], O_EDIT);
    field_opts_on(field[2], O_EDIT);
    field_opts_on(field[0], O_ACTIVE);
    field_opts_on(field[1], O_ACTIVE);
    field_opts_on(field[2], O_ACTIVE);

 
    /* 필드 옵션 설정 */
    set_field_back(field[0], A_UNDERLINE); 
    set_field_back(field[1], A_UNDERLINE); 

    set_field_back(field[2], A_UNDERLINE); 


    /* 필드 옵션 설정 */
    set_field_fore(field[0], COLOR_PAIR(1));
    set_field_back(field[0], COLOR_PAIR(2));
    set_field_fore(field[1], COLOR_PAIR(1));

    set_field_back(field[1], COLOR_PAIR(2));
    set_field_fore(field[2], COLOR_PAIR(1));
    set_field_back(field[2], COLOR_PAIR(2));


    if (s1 >= 10)
        move(6, 14);
    else
        move(6, 15);
    refresh();


    /* 사용자 요구에 따라 번복 여부 결정 */
    while((ch = getch()) != KEY_F(1) && ch != 0x1B && ch != 0x0D)   
        switch(ch)
      {

           case KEY_DOWN:
           case KEY_ENTER:
               /* 다음 필드로 가기 */
               form_driver(my_form, REQ_NEXT_FIELD);
               break;
          case KEY_UP:
              /* 이전 필드로 가기 */
              form_driver(my_form, REQ_PREV_FIELD);
              break;
         case KEY_BACKSPACE:
         case 0x7F:
              form_driver(my_form, REQ_DEL_PREV);
              break;
         case KEY_IC:
              if (flag_insert_mode != 0)
             {
                 form_driver(my_form, REQ_OVL_MODE);
                 getyx(stdscr, j, i);
                 mvprintw(0, 0, "   ");
                 move(j, i);
                 flag_insert_mode = 0;
             }
             else
            {
                 form_driver(my_form, REQ_INS_MODE);
                 getyx(stdscr, j, i);
                attron(COLOR_PAIR(7));
                mvprintw(0, 0, "Ins");
                attron(COLOR_PAIR(6));
                move(j, i);
                flag_insert_mode = 1;
            }
            break;
        case KEY_DC:
            form_driver(my_form, REQ_DEL_CHAR);
            break;
        case KEY_LEFT:
            form_driver(my_form, REQ_LEFT_CHAR);
            break;
        case KEY_RIGHT:
            form_driver(my_form, REQ_RIGHT_CHAR);
            break;
        default:
            form_driver(my_form, ch);
            break;
       }
    }
 
    form_driver(my_form, REQ_NEXT_FIELD);
 
    attron(COLOR_PAIR(6));
    mvprintw(13, 0, "You have answered");
    if (atoi(field_buffer(field[0], 0)) == s1*100 + s2)
         attron(COLOR_PAIR(5));
    else
         attron(COLOR_PAIR(4));
    mvprintw(14, 8, "%4d", atoi(field_buffer(field[0], 0)));
    if (atoi(field_buffer(field[1], 0)) == t)
         attron(COLOR_PAIR(5));
    else
         attron(COLOR_PAIR(4));
    mvprintw(15, 8, "%3d", atoi(field_buffer(field[1], 0)));
    if (atoi(field_buffer(field[2], 0)) == z)
         attron(COLOR_PAIR(5));
    else
         attron(COLOR_PAIR(4));
    mvprintw(16, 8, "%4d", atoi(field_buffer(field[2], 0)));

    attron(COLOR_PAIR(6));
    mvprintw(13, 20, "Right answer is");
    mvprintw(14, 28, "%2d%02d", s1, s2);
    mvprintw(15, 28, "%3d", t);
    mvprintw(16, 28, "%4d", z);
    if (atoi(field_buffer(field[0], 0)) == s1*100 + s2
         && atoi(field_buffer(field[1], 0)) == t
         && atoi(field_buffer(field[2], 0)) == z)
        mvprintw(18, 0, "    Your answer is right.");
    else
        mvprintw(18, 0, "    Your answer is wrong.");
    mvprintw(21, 0, "Press any key to quit...");
    getch();
   
    /* 폼을 떼어내고 메모리를 해제한다. */
    unpost_form(my_form);
    free_form(my_form);
    free_field(field[0]);
    free_field(field[1]);
    free_field(field[2]);

    endwin();

    return 0;
}
 

 

* 실행 결과:

 


 

Posted by Scripter
,