//CMD대신에 WINDOW창을 이용한 헥사프로그램 응용

//CMD대신에 WINDOW창을 이용한 헥사프로그램 응용

//CMD대신에 WINDOW창을 이용한 헥사프로그램 응용

//CMD대신에 WINDOW창을 이용한 헥사프로그램 응용

 

//필요파일 1. mainsrc.c

//필요파일 2. wincommon.h

//필요파일 3. wincommon.c

 

//실행파일만드는 방법

//gcc -Wall -DTEST_PRINTF -c mainsrc.c

//gcc -Wall -DTEST_PRINTF -c wincommon.c

//gcc -o mainexe mainsrc.o wincommon.o -lm -lws2_32 -lgdi32

 

#include "wincommon.h"

 

char design[6][2+1];

 

LRESULT CALLBACK WndProc(HWND hwnd,UINT iMsg,

                      WPARAM wParam , LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,

                LPTSTR lpszCmdLine , int nCmdShow)

{

    HWND hwnd;

    MSG msg;

 

    // 윈도우 클래스 생성

 

    WNDCLASS WndClass;                        // 윈도우 클래스 타입인 WNDCLASSEX의 변수를 만들고 각 필드에 값 부여

    WndClass.style = CS_HREDRAW | CS_VREDRAW; // 윈도우의 크기를 변경하면 다시 그리는 형태의 윈도우

    WndClass.lpfnWndProc = WndProc;           // WndProc은 메시지 처리를 위한 함수의 이름

    WndClass.cbClsExtra = 0;                  // 보통 클래스와 운도우를 위한 여분의 메모리는 사용치 않는다.

    WndClass.cbWndExtra = 0;                  // 그러므로 값을 0을 써준다.

    WndClass.hInstance = hInstance;           // 응용 프로그램 인스턴스를 WinMain()의 첫번째 매개변수로 넣어줌 

    WndClass.hIcon = LoadIcon(NULL , IDI_APPLICATION);                   // 로드하는 아이콘

    WndClass.hCursor = LoadCursor(NULL , IDC_ARROW);                     // 로드하는 커서

    WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);        // 흰색바탕(WHITE_BRUSH)의 윈도우를 생성한다.

    WndClass.lpszMenuName = NULL;             // 아직은 메뉴도 만들지 않고 사용치 않으므로 NULL이다.

    WndClass.lpszClassName = "Window Class Name";    // 윈도우 클래스 이름을 "Window Class Name 라고 하였다.

 

    RegisterClass(&WndClass);                 // 커널에 등록하기 위한 함수 사용방법은 매개변수로 WNDCLASSEX의

                                              // 주소를 넣어주면 된다.

 

    // 윈도우를 만드는 함수 CreateWindow()     

  

    hwnd = CreateWindow(                          // 윈도의 핸들값 반환

    "Window Class Name",                          // 윈도우 클래스 이름 

    "Window Title Name",                          // 만들어질 윈도우 타이틀바에 나타날 이름

    WS_OVERLAPPEDWINDOW,      // 이미 정의된 스타일 값중 선택할수 있다. (WS_OVERLAPPEDWINDOW)는 

                              // 타이틀바에 최소회 , 최대화 ,닫기 버튼이 나타나며 오른쪽 마우스 버튼을

                              // 눌렀을 때 시스템 메뉴가 나타나는 윈도우이다.

    CW_USEDEFAULT,            // 생성되는 윈도우가 어느 위치에 나타나야 하는지 x값과 y좌표값으로 써준다.

    CW_USEDEFAULT,            // CW_USEDEFAULT는 커널에 의해 기본값을 사용하라는 의미이다.

    CW_USEDEFAULT,            // 생성되는 윈도우의 폭과 높이 값으로 단위는 픽셀이다.

    CW_USEDEFAULT,            // CW_USEDEFAULT는 커널에 의해 기본값을 사용하라는 의미이다.

    NULL,

    NULL,

    hInstance,

    NULL

    );

 

    // 윈도우를 화면에 보여줌

    ShowWindow(hwnd,nCmdShow);       // nCmdShow는 윈도우를 화면에 나타내는 방법으로 상수값을 제공한다.

    UpdateWindow(hwnd);              // 윈도우에 WM_PAINT 메시지를 보내 화면에 기본 출력을 한다.

    while(GetMessage(&msg , NULL , 0 , 0))

    {

        TranslateMessage(&msg);                                      // 두 메시지를 하나로 변형할때 사용한다.

        DispatchMessage(&msg);                                       // 메시지를 처리하는 함수에 메시지를 보낸다.

    }

    return msg.wParam;

}

       

LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam , LPARAM lParam)  // 이벤트 저장되는 곳

{

   HDC hdc;

   PAINTSTRUCT ps;

 

   static int hexa[MAPY][MAPX];

   static int __design[3];

   static int xpos, ypos;

   static int score;

   static int screenxpos = 100;

   static int screenypos = 100;

 

   int i, k, j;

   char rbuf[4096];

 

    if(iMsg == WM_CREATE)   /* 윈도우 생성시 */

    {

       init(hexa, &xpos, &ypos, __design);

       score = 0;

       InvalidateRect(hwnd,NULL,FALSE);

       SetTimer(hwnd, 1, 300, NULL);

   }

    if(iMsg == WM_DESTROY)   /* 윈도우 종료시 */

   {

      KillTimer(hwnd, 1);

       PostQuitMessage(0);   /* 강제 종료     */

   }

  if(iMsg == WM_DESTROY)   /* 윈도우 종료시 */

  {

      KillTimer(hwnd, 1);

       PostQuitMessage(0);   /* 강제 종료     */

  }

  if(iMsg == WM_PAINT)

  {

        hdc=BeginPaint(hwnd, &ps);

       for(i=0; i<MAPY; i++)

       {

          for(k=0; k<MAPX; k++)

          {

             if(hexa[i][k] == 10)

             {

                continue;

             }

             else if(hexa[i][k] == 0)

             {

                TextOut(hdc, screenxpos + 8 * 2 * k, screenypos + 8 * 2 * i, "□", 2);

             }

             else

             {

                TextOut(hdc, screenxpos + 8 * 2 * k, screenypos + 8 * 2 * i, design[ hexa[i][k] ], 2);

             }

          }

       }

       EndPaint(hwnd, &ps);

    }

   if(iMsg == WM_TIMER)

   {

        k = f_downkey(hexa, &xpos, &ypos, __design);

 

      if(k==0)

      {

         if(ypos == 0)

         {

            KillTimer(hwnd, 1);

 

            sprintf(rbuf, "------------------------------------------------------------\n"

                          "HI!,  THIS IS TETTRIS GAME MESSAGE BOX, NEXT TRY,,!!!       \n"

                          "DTAE    : PARK BYEONG SOOL(2016/12/06)                      \n"

                      "AUTHOR  : PARK BYEONG SOOL                                  \n"

                         "HISTORY : PARK BYEONG SOOL                                  \n"

                        "SCAORE   : %.3d                                             \n"

                      "------------------------------------------------------------\n", score);

            MessageBox(hwnd , rbuf,"TETTRIS CAPTION",MB_OK);

            return 0;

         }

         else

            {

                while(1)

                {

               j=0;

                    if( f_check_horizontal(hexa, &score) == 0 ) j++;

               if( f_check_vertical(hexa, &score) == 0 ) j++;

               if( f_check_left_to_right(hexa, &score) == 0 ) j++;

                  if( f_check_right_to_left(hexa, &score) == 0 ) j++;

 

                  if(j == 4) break;

             }

          }

            xpos = MAPX / 2;

          ypos = 0;

 

          __design[0] = 1 + ( rand() % 5 );

           __design[1] = 1 + ( rand() % 5 );

           __design[2] = 1 + ( rand() % 5 );

 

          hexa[ypos+0][xpos] = __design[0];

          hexa[ypos+1][xpos] = __design[1];

          hexa[ypos+2][xpos] = __design[2];

      }

      InvalidateRect(hwnd,NULL,FALSE);

   }

   if(iMsg == WM_KEYDOWN)

   {

      switch(wParam) 

      {

         case VK_ESCAPE:

            KillTimer(hwnd, 1);

            sprintf(rbuf, "------------------------------------------------------------\n"

                          "HI!,  THIS IS TETTRIS GAME MESSAGE BOX, NEXT TRY,,!!!       \n"

                          "DTAE    : PARK BYEONG SOOL(2016/12/06)                      \n"

                      "AUTHOR  : PARK BYEONG SOOL                                  \n"

                      "HISTORY : PARK BYEONG SOOL                                  \n"

                        "SCAORE   : %.3d                                             \n"

                         "------------------------------------------------------------\n", score);

            MessageBox(hwnd , rbuf,"TETTRIS CAPTION",MB_OK);

            return 0;

        case VK_LEFT:

           k = f_leftkey(hexa, &xpos, &ypos, __design);

          break;

        case VK_RIGHT:

           k = f_rightkey(hexa, &xpos, &ypos, __design);

          break;

        case VK_DOWN:

           k = f_downkey(hexa, &xpos, &ypos, __design);

          break;

        case VK_SPACE:

             k = f_spacekey(hexa, &xpos, &ypos, __design);

             break;

        case VK_RETURN:

          while(1)

          {

                 k = f_downkey(hexa, &xpos, &ypos, __design);

               if(k==0) break;

              else InvalidateRect(hwnd,NULL,FALSE);

          }

            break;

       }

       InvalidateRect(hwnd,NULL,FALSE);

   }

    return DefWindowProc(hwnd,iMsg,wParam , lParam); /* 나머지는 커널이 처리하도록 메시지를 전달한다. */

}

//공통 라이브러리 함수(LINK시에 함께 컴파일)

//공통 라이브러리 함수(LINK시에 함께 컴파일)

//공통 라이브러리 함수(LINK시에 함께 컴파일)

//gcc -c mainsrc.c

//gcc -c common.c

//gcc main_exe_filename main.o common.o

//gcc main_exe_filename main.o common.o

//gcc main_exe_filename main.o common.o

 

#include "common.h"

 

extern char design[6][2+1];

 

int f_rightkey(int hexa[MAPY][MAPX], int *x, int *y, int __des[3])

{

     if(check(hexa, *x + 1, *y, 0) == 1)

    {

       hexa[*y+0][*x] = 0;

        hexa[*y+1][*x] = 0;

        hexa[*y+2][*x] = 0;

 

        *x = *x + 1;

 

       hexa[*y+0][*x] = __des[0];

        hexa[*y+1][*x] = __des[1];

        hexa[*y+2][*x] = __des[2];

 

       return 1;

    }

    else

    {

       return 0;

    }

}

int f_leftkey(int hexa[MAPY][MAPX], int *x, int *y, int __des[3])

{

    if(check(hexa, *x - 1, *y, 0) == 1)

    {

      hexa[*y+0][*x] = 0;

       hexa[*y+1][*x] = 0;

       hexa[*y+2][*x] = 0;

 

       *x = *x - 1;

 

       hexa[*y+0][*x] = __des[0];

       hexa[*y+1][*x] = __des[1];

       hexa[*y+2][*x] = __des[2];

 

       return 1;

    }

    else

    {

       return 0;

    }

}

int f_downkey(int hexa[MAPY][MAPX], int *x, int *y, int __des[3])

{

    if(check(hexa, *x, *y + 1, 1)==1)

   {

      hexa[*y+0][*x] = 0;

       hexa[*y+1][*x] = 0;

       hexa[*y+2][*x] = 0;

 

       *y = *y + 1;

 

      hexa[*y+0][*x] = __des[0];

      hexa[*y+1][*x] = __des[1];

      hexa[*y+2][*x] = __des[2];

 

      return 1;

   }

   else

   {

      return 0;

   }

}

int f_enterkey(int hexa[MAPY][MAPX], int *x, int *y, int __des[3])

{

    return 1;

}

int f_spacekey(int hexa[MAPY][MAPX], int *x, int *y, int __des[3])

{

   int tmp;

 

   tmp = __des[0];

   __des[0] = __des[1];

   __des[1] = __des[2];

   __des[2] = tmp;

 

   hexa[*y+0][*x] = __des[0];

   hexa[*y+1][*x] = __des[1];

   hexa[*y+2][*x] = __des[2];

 

    return 1;

}

void f_quitmsg(int idx)

{

printf(

"----------------------------------------------------------------------\n"

"MinGW provides a complete Open Source programming tool set            \n"

"which is suitable for the development of native MS-Windows appications\n"

"and which do not depend on any 3rd-party C-Runtime DLLs.              \n"

"(It does depend on a number of DLLs provided by Microsoft themselves, \n"

"as components of the operating system; most notable among these is MSV\n"

"the Microsoft C runtime library. Additionally, threaded applications m\n"

"with a freely distributable thread support DLL, provided as part of Mi\n"

"                                                                      \n"

"MinGW compilers provide access to the functionality of the Microsoft C\n"

"and some language-specific runtimes. MinGW, being Minimalist,         \n"

"does not, and never will, attempt to provide a POSIX runtime environme\n"

"for POSIX application deployment on MS-Windows.                       \n"

"If you want POSIX application deployment on this platform, please cons\n"

"DATE    :                                                             \n"

"AUTHOR  :                                                             \n"

"SCORE   :[%.4d]                                                       \n"

"SCORE   :[%.4d]                                                       \n"

"SCORE   :[%.4d]                                                       \n"

"SCORE   :[%.4d]                                                       \n"

"SCORE   :[%.4d]                                                       \n"

"SCORE   :[%.4d]                                                       \n"

"SCORE   :[%.4d]                                                       \n"

"----------------------------------------------------------------------\n", idx, idx, idx, idx, idx, idx, idx);

}

int check(int hexa[MAPY][MAPX], int x, int y, int idx)

{

   int result;

 

   result = 0;

 

    if(idx == 0)

   {

        if(hexa[y+0][x]>0) result = 1;

       if(hexa[y+1][x]>0) result = 1;

       if(hexa[y+2][x]>0) result = 1;

   }

   if(idx == 1)

    {

      if(hexa[y+2][x] >0) result = 1;

   }

 

   if(result == 1) return -1;

   return 1;

}

void gotoxy(int x, int y)

{

    COORD Pos = {x - 1, y - 1};

    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Pos);

}

void f_display_all(int hexa[MAPY][MAPX])

{

   int i, k;

 

   for(i=0; i<MAPY; i++)

   {

      for(k=0; k<MAPX; k++)

      {

         if(hexa[i][k] == 10)

         {

            continue;

         }

         else if(hexa[i][k] == 0)

         {

            gotoxy(k * 2 + 1, i + 2);

           printf("□");

         }

         else

         {

            gotoxy(k * 2 + 1, i + 2);

            printf("%s", design[ hexa[i][k] ]);

         }

      }

   }

}

void f_display(int hexa[MAPY][MAPX], int x, int y)

{

int i, k;

 

/*

hexa[y-1][x]

hexa[y+0][x]

hexa[y+1][x]

hexa[y+2][x]

 

hexa[y-1][x+1]

hexa[y+0][x+1]

hexa[y+1][x+1]

hexa[y+2][x+1]

 

hexa[y-1][x-1]

hexa[y+0][x-1]

hexa[y+1][x-1]

hexa[y+2][x-1]

*/

    for(i=-1; i < 3; i++)

   {

      if(y + i> MAPY -1) continue;

      if(y + i < 0) continue;

      if(x < 0) continue;

        if(x > MAPX - 1) continue;

 

       if(hexa[y + i][x] == 10) continue;

       else if(hexa[y + i][x] == 0)

       {

           gotoxy(x * 2 + 1, y + i + 2);

            printf("□");

      }

      else

      {

            gotoxy(x * 2 + 1, y + i + 2);

          printf("%s", design[ hexa[y + i][x] ]);

      }

  }

  for(i=-1; i < 3; i++)

  {

    if(y + i> MAPY -1) continue;

    if(y + i < 0) continue;

    if(x + 1 < 0) continue;

      if(x + 1 > MAPX - 1) continue;

 

     if(hexa[y + i][x + 1] == 10) continue;

     else if(hexa[y + i][x + 1] == 0)

     {

         gotoxy( (x + 1) * 2 + 1, y + i + 2);

           printf("□");

     }

     else if(hexa[y + i][x + 1] == 1)

     {

           gotoxy( (x + 1) * 2 + 1, y + i + 2);

         printf("%s", design[ hexa[y + i][x + 1] ]);

     }

  }

  for(i=-1; i < 3; i++)

  {

     if(y + i> MAPY -1) continue;

     if(y + i < 0) continue;

     if(x - 1 < 0) continue;

      if(x - 1 > MAPX - 1) continue;

 

     if(hexa[y + i][x - 1] == 10) continue;

     else if(hexa[y + i][x - 1] == 0)

     {

           gotoxy( (x - 1) * 2 + 1, y + i + 2);

            printf("□");

     

     else

     {

            gotoxy( (x - 1) * 2 + 1, y + i + 2);

          printf("%s", design[ hexa[y + i][x - 1] ]);

     }

   }

}

void init(int hexa[MAPY][MAPX], int *x, int *y, int __des[3])

{

   int i, k;

 

   //char design[6][2+1] = {"", "●","◆","■","◀","▶"};

   strcpy(design[0], "");

   strcpy(design[5], "●");

   strcpy(design[1], "◆");

   strcpy(design[2], "■");

   strcpy(design[3], "◀");

   strcpy(design[4], "▶");

 

   for(i=0; i<MAPY; i++)

   {

      for(k=0; k<MAPX; k++)

      {

         hexa[i][k] = 0;

      }

  }

 

   for(i=0; i<MAPY; i++)

   {

      hexa[i][0]      = 10;

      hexa[i][MAPX-1] = 10;

   }

   for(k=0; k<1 + MAPX + 1; k++)

    {

      hexa[MAPY-1][k] = 10;

   }

 

 

   *x = MAPX / 2;

   *y = 0;

 

   __des[0] = 1 + ( rand() % 5 );

   __des[1] = 1 + ( rand() % 5 );

   __des[2] = 1 + ( rand() % 5 );

 

   hexa[*y+0][*x] = __des[0];

   hexa[*y+1][*x] = __des[1];

   hexa[*y+2][*x] = __des[2];

}

void f_delete_column( int hexa[MAPY][MAPX], int x, int y )

{

    int k;

 

    for(k = y; k >= 1; k--)

    {

        hexa[ k][ x ] = hexa[ ( k - 1 ) ][ x ];

    }

int f_check_horizontal(int hexa[MAPY][MAPX], int *sc)

{

    int i, k, j, idx;

 

    for(i = 0; i <MAPY - 1; i++ )

    {

        for(k = 1; k <MAPX - 3; k++ )

        {

            idx = 0;

            while( 1 )  

            {

                if( hexa[ i][ k + idx ] != 0 )

                {

                    if( hexa[ i][ k + idx ] == hexa[ i][ k + idx + 1 ] )

                    {

                        idx = idx + 1;

                    }

                    else break;

                }

                else break; 

            }

 

            if( idx >= 2 )

            {

              (*sc)++;

                for( j = k; j <= k + idx; j++ )

                {

                    f_delete_column( hexa, j, i );

                }

                return 1;

            }

        }

    }

    return 0;

}

int f_check_vertical(int hexa[MAPY][MAPX], int *sc)

{

    int i, k, j, idx;

 

    for( k = 1; k < MAPX - 1; k++ )

    {

        for( i = MAPY - 2; i >= 0; i-- ) 

        {

            idx = 0;

            while( 1 )

            {

                if( hexa[ ( i - idx )][k ] != 0 )

                {

                    if( hexa[ ( i - idx )][k ] == hexa[ ( i - idx - 1 )][k ] )

                    {

                        idx = idx + 1;

  

                    }

                    else break;

                }

                else break; 

            }

 

            if( idx >= 2 )

            {

              (*sc)++;

                for( j = i; j >= i - idx; j-- )

                {

                    f_delete_column( hexa, k, i );

                }

 

                return 1;

            }

        }

    }

    return 0;

int f_check_left_to_right(int hexa[MAPY][MAPX], int *sc)

{

    int i, k, j, idx;

 

    for(k = 1; k <MAPX - 1; k++ )

    {

        for(i = 0; i <MAPY - 1; i++ )

        {

            idx = 0;

            while( 1 )

            {

                if( hexa[ ( i + idx ) ][k + idx ] != 0 )

                {

                    if( hexa[ ( i + idx )][( k + idx ) ] == hexa[ ( i + idx + 1 )][( k + idx + 1 ) ] )

                    {

                        idx = idx + 1;

            }

                    else break;

                }

                else break;

            }

 

            if( idx >= 2 )

            {

              (*sc)++;

                for( j = 0; j <= idx; j++ )

                {

                    f_delete_column( hexa, k + j, i + j );

                }

 

                return 1;

            }

        }

    }

    return 0;

}  

int f_check_right_to_left(int hexa[MAPY][MAPX], int *sc)

{

    int i, k, j, idx;

 

    for(k = MAPX - 2; k >= 1; k--)

    {

        for(i = 0; i < MAPY - 1; i++)

        {

            idx = 0;

            while( 1 )

            {

                if( hexa[ (i + idx )][k - idx ] != 0 )

                {

                    if( hexa[ (i + idx )][(k - idx ) ] == hexa[ (i + idx + 1 )][(k - idx - 1 ) ] )

                    {

                        idx = idx + 1;

                  }

                    else break;

                }

                else break;

            }

 

            if( idx >= 2 )

            {

              (*sc)++;

                for( j = 0; j <= idx; j++ )

                { 

                    f_delete_column(hexa, k - j, i + j );

                }

                return 1;

            }

        }

    }

    return 0;

}

 

'c 언어 > 중급과정' 카테고리의 다른 글

WINDOWS, WIN, HEXA프로그램(헤더)  (0) 2019.10.31
WINDOWS, WIN, HEXA프로그램(메인)  (0) 2019.10.31
WINDOWS, CMD, HEXA프로그램(메인소스)  (0) 2019.10.31
WINDOWS, CMD, HEXA프로그램(헤더)  (0) 2019.10.31
엔디안  (0) 2019.10.30

//응용프로그램 메인 파일, 지역변수 이용

//응용프로그램 메인 파일, 지역변수 이용

//응용프로그램 메인 파일, 지역변수 이용

//응용프로그램 메인 파일, 지역변수 이용

 

#include "common.h"

 

char design[6][2+1];

 

void main(void)

{

   int hexa[MAPY][MAPX];

   int __design[3];

    int ____design[3];

   int xpos, ypos;

   int __xpos, __ypos;

   int score;

   int ch;

   int k, j;

 

   init(hexa, &xpos, &ypos, __design);

   f_display_all(hexa);

   score = 0;

 

    __xpos = xpos;

   __ypos = ypos;

   ____design[0] = __design[0];

   ____design[1] = __design[1];

   ____design[2] = __design[2];

 

   while(1)

   {

      if(kbhit())

      {

         ch = getch();

         if(ch == 224)    //방향키를 눌렀을때에는,,ㅡㅡ,ㅡㅡㅡ RIGHT,LEFT,UP,DOWN

         {

            ch = getch();

            if(ch == RIGHT_KEY)

            {

               k = f_rightkey(hexa, &xpos, &ypos, __design);

            }

            else if(ch == LEFT_KEY)

            {

               k = f_leftkey(hexa, &xpos, &ypos, __design);

            }

            else if(ch == DOWN_KEY)

            {

                k = f_downkey(hexa, &xpos, &ypos, __design);

            }

          }

         else if(ch == ENTER_KEY)

         {

            k = f_enterkey(hexa, &xpos, &ypos, __design);

         }

         else if(ch == SPACE_KEY)

         {

            k = f_spacekey(hexa, &xpos, &ypos, __design);

         }

         else if(ch == ESC_KEY)

         {

            break;

         }

      }

 

        //위치가 변경되었을때에만 DRAWING

      if( xpos != __xpos || ypos != __ypos)

      {

         f_display(hexa, xpos, ypos);

 

         __xpos = xpos;

         __ypos = ypos;

      }

        //디자인모양이 변경되었을때에만 DRAWING

        if( ! (__design[0] == ____design[0] && __design[0] == ____design[0] && __design[0] == ____design[0]))

      {

         f_display(hexa, xpos, ypos);

 

         ____design[0] = __design[0];

           ____design[1] = __design[1];

           ____design[2] = __design[2];

      }

 

      k=0;

      while(1)

      {

         Sleep(10);

         if(kbhit()) break;

 

         k++;

         if(k==30) break;

      }

 

      k = f_downkey(hexa, &xpos, &ypos, __design);

 

      if(k==0)

      {

         if(ypos == 0)

         {

            break;

         }

         else

            {

                while(1)

                {

               j=0;

                    if( f_check_horizontal(hexa, &score) == 0 ) j++;

               if( f_check_vertical(hexa, &score) == 0 ) j++;

               if( f_check_left_to_right(hexa, &score) == 0 ) j++;

               if( f_check_right_to_left(hexa, &score) == 0 ) j++;

 

               if(j == 4) break;

             }

          }

            xpos = MAPX / 2;

         ypos = 0;

 

          __design[0] = 1 + ( rand() % 5 );

            __design[1] = 1 + ( rand() % 5 );

            __design[2] = 1 + ( rand() % 5 );

 

          hexa[ypos+0][xpos] = __design[0];

          hexa[ypos+1][xpos] = __design[1];

          hexa[ypos+2][xpos] = __design[2];

       }

 

       if( xpos != __xpos || ypos != __ypos)

       {

          f_display(hexa, xpos, ypos);

 

          __xpos = xpos;

          __ypos = ypos;

       }

    }//END WHILE

    f_quitmsg(score);

}

 

 

 

 

 

'c 언어 > 중급과정' 카테고리의 다른 글

WINDOWS, WIN, HEXA프로그램(메인)  (0) 2019.10.31
WINDOSW, CMD, HEXA프로그램(공통)  (0) 2019.10.31
WINDOWS, CMD, HEXA프로그램(헤더)  (0) 2019.10.31
엔디안  (0) 2019.10.30
LINUX,기본적인 JSON 데이타포맷 파싱  (0) 2019.10.30

//공통 HEADER 파일

 

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

#include <Windows.h>

 

//상수 정의

#define RIGHT_KEY 77

#define LEFT_KEY 75

#define DOWN_KEY 80

#define ENTER_KEY 13

#define SPACE_KEY 32

#define ESC_KEY 27

 

#define MAPX 34

#define MAPY 30

 

//함수 프로토타입정의

void f_display_all(int hexa[MAPY][MAPX]);

void f_display(int hexa[MAPY][MAPX], int x, int y);

void gotoxy(int x, int y);

void init(int hexa[MAPY][MAPX], int *x, int *y, int __des[3]);

int check(int hexa[MAPY][MAPX], int x, int y, int idx);

void f_quitmsg(int idx);

 

void f_delete_column(int hexa[MAPY][MAPX], int x, int y );

int f_check_horizontal(int hexa[MAPY][MAPX], int *sc);

int f_check_vertical(int hexa[MAPY][MAPX], int *sc);

int f_check_left_to_right(int hexa[MAPY][MAPX], int *sc);

int f_check_right_to_left(int hexa[MAPY][MAPX], int *sc);

 

int f_rightkey(int hexa[MAPY][MAPX], int *x, int *y, int __des[3]);

int f_leftkey(int hexa[MAPY][MAPX], int *x, int *y, int __des[3]);

int f_downkey(int hexa[MAPY][MAPX], int *x, int *y, int __des[3]);

int f_enterkey(int hexa[MAPY][MAPX], int *x, int *y, int __des[3]);

int f_spacekey(int hexa[MAPY][MAPX], int *x, int *y, int __des[3]);

1. 키보드 조작에 따른 방향키및 그외 키값 정의하기

 

#include <stdio.h>

#include <conio.h>

 

int main(void)

{

    int ch, hit;

 

    while(1)

   {

      hit = kbhit();

      if(hit ==1)

      {

         ch = getch();

         printf("%d\n", ch);

 

         if(ch == 27) break;

      }

   }

}

/*-----------------------------------------

Microsoft Windows [Version 6.1.7601]

Copyright (c) 2009 Microsoft Cor

 

C:\Users\SUKSU\Downloads\__1000>a11

RIGHT 224 77

LEFT  224 75

UP    224 72

DOWN  224 80

ENTER 13

SPACE 32

ESC   27

C:\Users\SUKSU\Downloads\__1000>

-------------------------------------------*/

 

 

2. 키값 정의후에 응용프로그램 로직 개략적으로 설명하기

 

#include <stdio.h>

#include <conio.h>

 

#define RIGHT_KEY 77

#define LEFT_KEY 75

#define UP_KEY 72

#define DOWN_KEY 80

#define ENTER_KEY 13

#define SPACE_KEY 32

#define ESC_KEY 27

 

int main(void)

{

    int ch, hit;

    while(1)

    {

        hit = kbhit();

        if(hit ==1)

        {

            ch = getch();

            if(ch == 224)

         {

            ch = getch();

            if(ch == RIGHT_KEY)

            {

           // x위치가 1증가가 가능하다면, x의 위치를 1증가

            }

            if(ch == LEFT_KEY)

            {

           // x위치가 1감소가 가능하다면, x의 위치를 1감소

            }

            if(ch == DOWN_KEY)

            {

           // y위치가 1증가가 가능하다면, y의 위치를 1증가

            }

         }

            if(ch == ESC_KEY) break;

         if(ch == ENTER_KEY)

         {

        //add here

         }

         if(ch == SPACE_KEY)

         {

        //add here

         }

        }

    }

}

 

//방향키에 따른 키보드 로직 정의하기

//방향키에 따른 키보드 로직 정의하기

//방향키에 따른 키보드 로직 정의하기

//방향키에 따른 키보드 로직 정의하기

 

#include <stdio.h>

#include <conio.h>

#include <Windows.h>

 

#define RIGHT_KEY 77

#define LEFT_KEY 75

#define DOWN_KEY 80

#define ENTER_KEY 13

#define SPACE_KEY 32

#define ESC_KEY 27

 

void main(void)

{

    int hit, ch;

    int j, idx;

    int xpos, ypos;

 

    xpos = 0;

    ypos = 0;

    idx  = 0;

    while(1)

    {

        printf(">>>>[%7d][%3d][%3d]\n", idx++, xpos, ypos);

        hit = kbhit();

        if(hit == 1)

        {

            ch = getch();

            if(ch == 224)

            {

                ch = getch();

                if(ch == RIGHT_KEypos)

                {

                    xpos = xpos + 1;

                }

                if(ch == LEFT_KEypos)

                {

                    xpos = xpos - 1;

                }

                if(ch == DOWN_KEypos)

                {

                   ypos = ypos + 1;

                }

            }

            if(ch == ENTER_KEypos)

            {

            //add here

            }

            if(ch == SPACE_KEypos)

            {

            //add here

            }

            if(ch == ESC_KEypos)

            {

                break;

            }

        }

 

        // 0.01초씩 100번, 즉 1초에 한번 꼴로 반복한다. 키보드의 입력이 발생할 경우 

        // 0.01초에 반응해서 키보드에 응답한다.

        j = 0;

        while(1)

        {

           Sleep(10);

           if(kbhit()) break;

 

           j=j+1;

           if(j == 100) break;

        }

    }

}

 

/*

Microsoft Windows [Version 6.1.7601]

Copyright (c) 2009 Microsoft Corporation. All rights reserved.

 

C:\Users\SIHOO\Downloads>a11

>>>>[      0][  0][  0]

>>>>[      1][  0][  0]

>>>>[      2][  0][  0]

>>>>[      3][  0][  0]

>>>>[      4][  1][  0]

>>>>[      5][  2][  0]

>>>>[      6][  3][  0]

>>>>[      7][  4][  0]

>>>>[      8][  5][  0]

>>>>[      9][  6][  0]

>>>>[     10][  7][  0]

>>>>[     11][  8][  0]

>>>>[     12][  9][  0]

>>>>[     13][ 10][  0]

>>>>[     14][ 11][  0]

>>>>[     15][ 12][  0]

>>>>[     16][ 13][  0]

>>>>[     17][ 14][  0]

>>>>[     18][ 15][  0]

>>>>[     19][ 16][  0]

>>>>[     20][ 17][  0]

>>>>[     21][ 18][  0]

>>>>[     22][ 19][  0]

>>>>[     23][ 20][  0]

>>>>[     24][ 21][  0]

>>>>[     25][ 22][  0]

>>>>[     26][ 23][  0]

>>>>[     27][ 24][  0]

>>>>[     28][ 25][  0]

>>>>[     29][ 26][  0]

>>>>[     30][ 27][  0]

>>>>[     31][ 28][  0]

>>>>[     32][ 29][  0]

>>>>[     33][ 30][  0]

>>>>[     34][ 31][  0]

>>>>[     35][ 32][  0]

>>>>[     36][ 33][  0]

>>>>[     37][ 34][  0]

>>>>[     38][ 34][  0]

>>>>[     39][ 34][  0]

>>>>[     40][ 34][  0]

>>>>[     41][ 34][  0]

>>>>[     42][ 35][  0]

>>>>[     43][ 35][  0]

>>>>[     44][ 35][  0]

>>>>[     45][ 35][  1]

>>>>[     46][ 35][  2]

>>>>[     47][ 35][  3]

>>>>[     48][ 35][  4]

>>>>[     49][ 35][  5]

>>>>[     50][ 35][  6]

>>>>[     51][ 35][  7]

>>>>[     52][ 35][  8]

>>>>[     53][ 35][  9]

>>>>[     54][ 35][ 10]

>>>>[     55][ 35][ 11]

>>>>[     56][ 35][ 12]

>>>>[     57][ 35][ 13]

>>>>[     58][ 35][ 14]

>>>>[     59][ 35][ 15]

>>>>[     60][ 35][ 16]

>>>>[     61][ 35][ 17]

>>>>[     62][ 35][ 18]

>>>>[     63][ 35][ 19]

>>>>[     64][ 35][ 20]

>>>>[     65][ 35][ 21]

>>>>[     66][ 35][ 22]

>>>>[     67][ 35][ 23]

>>>>[     68][ 35][ 24]

>>>>[     69][ 35][ 25]

>>>>[     70][ 35][ 26]

>>>>[     71][ 35][ 27]

>>>>[     72][ 35][ 28]

>>>>[     73][ 35][ 29]

>>>>[     74][ 35][ 30]

>>>>[     75][ 35][ 31]

>>>>[     76][ 35][ 32]

>>>>[     77][ 35][ 33]

>>>>[     78][ 35][ 34]

>>>>[     79][ 35][ 35]

>>>>[     80][ 35][ 36]

>>>>[     81][ 35][ 37]

>>>>[     82][ 35][ 38]

>>>>[     83][ 35][ 39]

>>>>[     84][ 35][ 40]

>>>>[     85][ 35][ 41]

 

C:\Users\SIHOO\Downloads>

*/

/*
Firebase : Send notification with REST API(common.c)
*/


#include 
#include 
#include 
#include 

/*- ------------------------------------------------ -*
*- Current date Get function 
*- ------------------------------------------------ -*/
/*- ------------------------------------------------ -*
*- GetDate() : 현재 날짜를 YYYYMMDD형식으로하여 정수형으로 Return 
*- Return 값 : 변환된 날짜(YYYYMMDD) 
*- ------------------------------------------------ -*/
int GetDate()
{
    time_t tt;
    struct tm *ltime;
    char    ctime[8];

    time(&tt);
    ltime = localtime(&tt);
    sprintf(ctime, "%04d%02d%02d", ltime->tm_year+1900, ltime->tm_mon+1, ltime->tm_mday);
    return(atoi(ctime));
}
/*- ------------------------------------------------ -*
*- GetTime() : 현재 시간 값을 구하는 함수  
*- Return 값 : 현재 시간 (HHMMSS) 
*- ------------------------------------------------ -*/
int GetTime()
{
    time_t tt;
    struct tm *ltime;
    char    ctime[2];

    time(&tt);
    ltime = localtime(&tt);
    sprintf(ctime, "%02d%02d%02d", ltime->tm_hour, ltime->tm_min, ltime->tm_sec);
    return(atoi(ctime));
}

/*
Firebase : Send notification with REST API(sample.c)
*/
/**
BUILD & MAKE(WINDOW & LINUX COMMON)
-------------------------------------------------------------------
CC = gcc

CFLAGS += -I -g -Wall -Wno-unused-variable
LIBS += -L. -lcurl -ljson-c

.c.o:
$(CC) -c $< $(CFLAGS)

all: build

common.o : common.c
sample.o : sample.c

sample: sample.o common.o
$(CC) -o $@ $^ $(LIBS)
BUILD_FILES += sample

build: $(BUILD_FILES)

clean:
rm -f *.o
rm -f $(BUILD_FILES)
-------------------------------------------------------------------
*/
#include 
#include 

#include <curl/curl.h>
#include 
#include 
#include 
#include <sys/time.h>
#include "json.h"

#define MAX_MSG_CNT 14
#define authorization_str "AUTHORIZATION:"
#define token_str "TOKEN:"

/* holder for curl fetch */
struct curl_fetch_st {
    char *payload;
    size_t size;
};

static json_object *google_pushcall(char *authorization, char *title, char *body, char *token);
static size_t curl_callback (void *contents, size_t size, size_t nmemb, void *userp);
static CURLcode curl_fetch_url(CURL *ch, const char *url, struct curl_fetch_st *fetch);
static int jsonparsing_result(const char *buf);
static int get_config_values(char *authorization, char *token);

int GetDate();
int GetTime();

int get_config_values(char *authorization, char *token)
{
    FILE *fp=NULL;
    char rbuf[1024];

    if((fp=fopen("config.txt", "rt"))==NULL) return(-1);

    while(1)
    {
        memset(rbuf,0x00,sizeof(rbuf));
        if(fgets(rbuf, sizeof(rbuf), fp)==NULL) break;

        rbuf[strlen(rbuf)-1]=0x00;

        if(rbuf[0] == '#') continue;

        if(strstr(rbuf, authorization_str) != NULL)
        {
            strcpy(authorization, strstr(rbuf, authorization_str) + strlen(authorization_str));
        }
        if(strstr(rbuf, token_str) != NULL)
        {
            strcpy(token, strstr(rbuf, token_str) + strlen(token_str));
        }
    }
    if(fp != NULL) fclose(fp);
    return(0);
}

int main(int argc, char *argv[])
{
    json_object *json = NULL;
    int rc;

    char authorization[1024];
    char token[300];

    char *title = "FCM Message";
    char body[4096];
    char extendedmsg[MAX_MSG_CNT][300] = 
    {
    "Miracles happen to only those who believe in them.",
    "Think like a man of action and act like man of thought.",
    "Courage is very important. Like a muscle, it is strengthened by use.",
    "Life is the art of drawing sufficient conclusions from insufficient premises.",
    "By doubting we come at the truth.",
    "A man that has no virtue in himself, ever envies virtue in others.",
    "When money speaks, the truth keeps silent.",
    "Better the last smile than the first laughter.",
    "Painless poverty is better than embittered wealth.",
    "A poet is the painter of the soul.",
    "Error is the discipline through which we advance.",
    "Faith without deeds is useless.",
    "Weak things united become strong.",
    "We give advice, but we cannot give conduct.",
    };

    memset(authorization,0x00,sizeof(authorization));
    memset(token,0x00,sizeof(token));

    rc=get_config_values(authorization, token);
    if(rc)
    {
        //ERROR
    }
    else
    {
        fprintf(stderr, "authorization:(%s)\n", authorization);
        fprintf(stderr, "token:        (%s)\n", token);
    }

    memset(body,0x00,sizeof(body));
    sprintf(body, "Body>>(%d-%d)(%d)(%s)", GetDate(), GetTime(), GetTime() % MAX_MSG_CNT, extendedmsg[GetTime() % MAX_MSG_CNT]);

    json = google_pushcall(authorization, title, body, token);
    if(json == NULL) {
        return(-1);
    }

    /* debugging */
    fprintf(stderr, "RECV>>Parsed JSON: %s\n", json_object_to_json_string(json));

    rc = jsonparsing_result(json_object_to_json_string(json));
    if(rc)
    {
        //ERROR
    }
    else
    {
        //INSERT PUSH_SIT_EVENT_HIST
    }

    if(json != NULL) json_object_put(json);

    return(0);
}

/* callback for curl fetch */
size_t curl_callback (void *contents, size_t size, size_t nmemb, void *userp) 
{
    size_t realsize = size * nmemb;                             /* calculate buffer size */
    struct curl_fetch_st *p = (struct curl_fetch_st *) userp;   /* cast pointer to fetch struct */

    /* expand buffer */
    p->payload = (char *) realloc(p->payload, p->size + realsize + 1);

    /* check buffer */
    if (p->payload == NULL) {
        /* this isn't good */
        fprintf(stderr, "ERROR: Failed to expand buffer in curl_callback\n");
        /* free buffer */
        free(p->payload);
        /* return */
        return -1;
    }

    /* copy contents to buffer */
    memcpy(&(p->payload[p->size]), contents, realsize);

    /* set new buffer size */
    p->size += realsize;

    /* ensure null termination */
    p->payload[p->size] = 0;

    /* return size */
    return realsize;
}

/* fetch and return url body via curl */
CURLcode curl_fetch_url(CURL *ch, const char *url, struct curl_fetch_st *fetch) 
{
    CURLcode rcode;                   /* curl result code */

    /* init payload */
    fetch->payload = (char *) calloc(1, sizeof(fetch->payload));

    /* check payload */
    if (fetch->payload == NULL) {
        /* log error */
        fprintf(stderr, "ERROR: Failed to allocate payload in curl_fetch_url\n");
        /* return error */
        return CURLE_FAILED_INIT;
    }

    /* init size */
    fetch->size = 0;

    /* set url to fetch */
    curl_easy_setopt(ch, CURLOPT_URL, url);
    /* set calback function */
    curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, curl_callback);
    /* pass fetch struct pointer */
    curl_easy_setopt(ch, CURLOPT_WRITEDATA, (void *) fetch);
    /* set default user agent */
    curl_easy_setopt(ch, CURLOPT_USERAGENT, "curl/7.65.1");
    /* set timeout */
    curl_easy_setopt(ch, CURLOPT_TIMEOUT, 30);
    /* enable location redirects */
    curl_easy_setopt(ch, CURLOPT_FOLLOWLOCATION, 1);
    /* set maximum allowed redirects */
    curl_easy_setopt(ch, CURLOPT_MAXREDIRS, 1);
    /* fetch the url */
    rcode = curl_easy_perform(ch);

    /* return */
    return rcode;
}

json_object *google_pushcall(char *authorization, char *title, char *body, char *token)
{
    CURL *ch;                                               /* curl handle */
    CURLcode rcode;                                         /* curl result code */

    json_object *json=NULL;                                 /* json post body */
    json_object *jsonobj=NULL;                              /* json post body */

    enum json_tokener_error jerr = json_tokener_success;    /* json parse error */

    struct curl_fetch_st curl_fetch;                        /* curl fetch struct */
    struct curl_fetch_st *cf = &curl_fetch;                 /* pointer to fetch struct */
    struct curl_slist *headers = NULL;                      /* http headers to send with request */

    char post_data  [4096] = {0x00,};

    char header_definition[2048];

    char *url = "https://fcm.googleapis.com/fcm/send";

    /* init curl handle */
    if ((ch = curl_easy_init()) == NULL) {
        /* log error */
        fprintf(stderr, "ERROR: Failed to create curl handle in fetch_session\n");
        /* return error */
        return NULL;
    }

    /* set content type */
    memset(header_definition,0x00,sizeof(header_definition));
    sprintf(header_definition, "Authorization: key=%s", authorization);
    headers = curl_slist_append(headers, header_definition);
    headers = curl_slist_append(headers, "Content-Type: application/json");

    /* create json object for post */
    json      = json_object_new_object();
    jsonobj   = json_object_new_object();

    json_object_object_add(json  ,  "to"          , json_object_new_string(token));
    json_object_object_add(jsonobj, "title"       , json_object_new_string(title));
    json_object_object_add(jsonobj, "body"        , json_object_new_string(body));
    json_object_object_add(json  ,  "notification", jsonobj);

    memset(post_data, 0x00, sizeof(post_data));
    sprintf(post_data, "%s", json_object_to_json_string(json));

    /* set curl options */
    curl_easy_setopt(ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_easy_setopt(ch, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(ch, CURLOPT_POSTFIELDS, post_data);
    curl_easy_setopt(ch, CURLOPT_VERBOSE, 1L);
    curl_easy_setopt(ch, CURLOPT_POST, 1L);
    /* disconnect if we can't validate server's cert */ 
    curl_easy_setopt(ch, CURLOPT_SSL_VERIFYPEER, 0L);
    curl_easy_setopt(ch, CURLOPT_SSL_VERIFYHOST, 0L);

    /* fetch page and capture return code */
    rcode = curl_fetch_url(ch, url, cf);

    //FREE
    curl_easy_cleanup(ch);
    curl_slist_free_all(headers);

    if(json != NULL) json_object_put(json);
    if(jsonobj != NULL) json_object_put(jsonobj);

    /* check return code */
    if (rcode != CURLE_OK || cf->size < 1) {
        /* log error */
        fprintf(stderr, "ERROR: Failed to fetch url (%s) - curl said: %s\n",
            url, curl_easy_strerror(rcode));
        /* return error */
        return NULL;
    }

    /* check payload */
    if (cf->payload != NULL) 
    {

        /* parse return */
        json = json_tokener_parse_verbose(cf->payload, &jerr);
        /* free payload */
        free(cf->payload);
    }
    else 
    {
        /* error */
        fprintf(stderr, "ERROR: Failed to populate payload\n");
        /* free payload */
        free(cf->payload);
        /* return */
        return NULL;
    }

        /* check error */
    if (jerr != json_tokener_success) 
    {
        /* error */
        fprintf(stderr, "ERROR: Failed to parse json string\n");
        /* free json object */
        if(json != NULL) json_object_put(json);
        /* return */
        return NULL;
    }
    return json;
}

int jsonparsing_result(const char *buf)
{
    int ii, rc;
    char keystr[100],successtmp[100];
    struct json_object *jsonjob   = NULL;
    struct json_object *jsonvalue = NULL;

    jsonjob = json_tokener_parse(buf);
    if(NULL == jsonjob) {
        return -1;
    }
    printf("\n\n\n\n");

    memset(keystr, 0x00, sizeof(keystr));
    strcpy(keystr, "success");
    json_object_object_get_ex(jsonjob, keystr, &jsonvalue);
    memset(successtmp, 0x00, sizeof(successtmp));
    strcpy(successtmp, json_object_get_string(jsonvalue));

    if(atoi(successtmp) == 1 || atoi(successtmp) == 0)
    {
        if(atoi(successtmp) == 0) printf("[FAIL]BASIC DATA-----------------------------------\n");
        if(atoi(successtmp) == 1) printf("[SUCC]BASIC DATA-----------------------------------\n");

        memset(keystr, 0x00, sizeof(keystr));
        strcpy(keystr, "multicast_id");
        json_object_object_get_ex(jsonjob, keystr, &jsonvalue);
        printf("[%s][%s]\n", keystr, json_object_get_string(jsonvalue));

        memset(keystr, 0x00, sizeof(keystr));
        strcpy(keystr, "success");
        json_object_object_get_ex(jsonjob, keystr, &jsonvalue);
        printf("[%s][%s]\n", keystr, json_object_get_string(jsonvalue));

        memset(keystr, 0x00, sizeof(keystr));
        strcpy(keystr, "failure");
        json_object_object_get_ex(jsonjob, keystr, &jsonvalue);
        printf("[%s][%s]\n", keystr, json_object_get_string(jsonvalue));

        memset(keystr, 0x00, sizeof(keystr));
        strcpy(keystr, "canonical_ids");
        json_object_object_get_ex(jsonjob, keystr, &jsonvalue);
        printf("[%s][%s]\n", keystr, json_object_get_string(jsonvalue));

        struct json_object *pdata = NULL;
        if(json_object_object_get_ex(jsonjob, "results", &pdata)) 
        {
            for (ii = 0; ii < json_object_array_length(pdata); ii++) 
            {
                if(ii==0)
                {
                    printf("ARRAY DATA[%.4d]-----------------------------------\n", json_object_array_length(pdata));
                }

                struct json_object *successtmp = json_object_array_get_idx(pdata, ii);

                memset(keystr, 0x00, sizeof(keystr));
                strcpy(keystr, "message_id");
                rc = json_object_object_get_ex(successtmp, keystr, &jsonvalue);
                if(rc)
                {
                    printf("rc:[%d]", rc);
                    printf(",index[%.3d],key[%s]:[%s]\n", ii + 1, keystr, json_object_get_string(jsonvalue));
                }

                memset(keystr, 0x00, sizeof(keystr));
                strcpy(keystr, "error");
                rc = json_object_object_get_ex(successtmp, keystr, &jsonvalue);
                if(rc)
                {
                    printf("rc:[%d]", rc);
                    printf(",index[%.3d],key[%s]:[%s]\n", ii + 1, keystr, json_object_get_string(jsonvalue));
                }
            }
        }
    }
    else
    {
        return(-2);
    }

    return(0);
}

+ Recent posts