이모지 링크

 

https://kr.piliapp.com/twitter-symbols/

https://www.unicode.org/emoji/charts/full-emoji-list.html

https://kr.piliapp.com/symbol/#graphic

 

 

1)

#include <stdio.h>

#define emoji_Size sizeof "🔚" // icon size == 5byte
#define movable 8
#define x_Blocks (movable + 2)         // 이동 블럭 수 + 양쪽 벽 2개
#define x_Total (emoji_Size * x_Blocks) // x 축 전제 크기

int main(void)
{
    char map[x_Total] = {"⬛🔚🔙🔚🔙🔚🔙🔚🔙⬛"};

    printf("emoji  size: %ld Byte\n", sizeof "🔚");
    printf("x axis cnt : %d\n", x_Blocks);
    printf("array size : %ld Byte\n", sizeof map);

    printf("%s\n\n", map);
}

 

// icon  size: 5Byte
// x axis cnt: 10
// array size: 50Byte
// ⬛🔚🔙🔚🔙🔚🔙🔚🔙⬛

 

 

 

2)

#include <stdio.h>

int main(void)
{
    // 1차원 배열
    char map1[10] = {"1 2 3 4 5"};

    printf("%s\n", map1);
    printf("%ld Byte\n\n", sizeof map1); // 9+1

    // 2차원 배열
    char map2[2][10] = {
        "0 1 2 3 4",
        "5 6 7 8 9"};

    printf("%s\n", map2[0]);
    printf("%s\n", map2[1]);
    printf("%ld Byte\n\n", sizeof map2); // (9+1)*2

    // 좌표 평면상의 x축, y축과 인덱스 값 간의 차이점 확인
    // 아래 출력분을 중첩된 반복문으로 출력할 수 있으면, 콘솔 게임 맵 출력 완성
    printf("%c %c %c %c %c\n", map2[0][0], map2[0][2], map2[0][4], map2[0][6], map2[0][8]);
    printf("%c %c %c %c %c\n", map2[1][0], map2[1][2], map2[1][4], map2[1][6], map2[1][8]);
}
// 1 2 3 4 5
// 10 Byte

// 0 1 2 3 4
// 5 6 7 8 9
// 20 Byte

// 0 1 2 3 4
// 5 6 7 8 9

 

 

 

3)

#include <stdio.h>

int main(void)
{
    /* Case 1. [↖방향] 좌표 0,0 시작 2차원 배열 계산이 편한경우 */
    \
    char map1[5][10] = {
        "0 1 2 3 4",
        "1 a b c d",
        "2 e f g h",
        "3 i j k l",
        "4 m n o p"};

    int maxRow = sizeof map1 / sizeof map1[0]; // [1 시작 정수 계산 사용]
    int y_MaxIdx = maxRow - 1;                 // [0 시작 index 계산 사용] 행 마지막 인덱스
    int block_sz = 2;                          // 열의 블록 한칸 사이즈(띄어쓰기 고려)
    printf("2차원 맵 사이즈: %ld, 행 사이즈: %ld\n\n", sizeof map1, sizeof map1[0]);

    // [step1] 키 입력
    int x_Input = 4; // x 축으로 4칸
    int y_Input = 3; // y 축으로 3칸

    // [step2] 키 입력값이 유효하면, 계산후 할당
    int _x = 0; 
    int _y = 0;

    // [step3] 아이콘 사이즈 반영을 위한 공백 반영
    _x = x_Input * block_sz; // block * 2
    _y = y_Input;
    printf("map1[%d][%d], 값: %c\n", _y, _x / block_sz, map1[_y][_x]);


    /* Case 12. [↙방향] 좌표 0,4 시작 좌표 계산이 편한경우 */

    char map2[5][10] = {
        "4 m n o p",
        "3 i j k l",
        "2 e f g h",
        "1 a b c d",
        "* 1 2 3 4"};

    _x = 0;
    _y = 4;
    _x = x_Input * block_sz; // block * 2
    _y = y_MaxIdx - y_Input; //
    printf("map2[%d][%d], 값: %c\n", _y, _x / block_sz, map2[_y][_x]);
}



 

 

4) 출력

#include <stdio.h>

int main(void)
{
    /* Case 1. [↖방향] 좌표 0,0 시작 2차원 배열 계산이 편한경우 */

    char map1[5][10] = {
        "01234",
        "1abcd",
        "2efgh",
        "3ijkl",
        "4mnop"};

    int rowSZ = sizeof map1[0];
    int colSZ = sizeof map1 / rowSZ; // [1 시작 정수 계산 사용]
    int y_MaxIdx = colSZ - 1;        // [0 시작 index 계산 사용] 행 마지막 인덱스
    int block_sz = 2;                 // 열의 블록 한칸 사이즈(띄어쓰기 고려)
    printf("2차원 맵 사이즈: %ld, 행 사이즈: %d\n\n", sizeof map1, rowSZ);

    // [1] 키 입력
    int x_Input = 1; // x 축으로 x칸
    int y_Input = 3; // y 축으로 y칸

    // [2] 케릭터 위치 초기값
    int _x = 0;
    int _y = 0;

    // [3] 키 입력값이 유효하면, 케릭터 좌표값 계산후 할당
    _x = x_Input;
    _y = y_Input;
    

    // [4] 맵 출력 시, 배열에 공백이 없다면, 
    // 컬러 아이콘은 글자2.5~3개 정도로 표시되므로 중첩되어 깨짐. 3+양쪽 공백 1칸 출력시 추가해야 함
    char level[5][5] = {"🤺", "🏇", "♖ ", "♕ ", "♔ "};

    for (size_t i = 0; i < colSZ; i++)
    {
        for (size_t j = 0; j < rowSZ; j++)
        {
            if(i == _y && j == _x)
                printf("%5s", level[1]);
            else
                printf("%3c", map1[i][j]);
        }
        printf("\n");
    }
}

 

 

 

 

5) 콘솔 게임 만들기

 

 

 

1)키를 입력받고,

2)캐릭터 이모지의 위치를 변경하는 로직 동작 후,

3)이동된 결과를 출력하도록 구현하시오

(맵 모양 및 크기와 이모지는 개인 선택)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <termios.h>

int getch();

int main(void)
{
    char map3[16][64] = {
        "10  10  10  10  10  10  10  10  10  10  10  10  10  10  10  10  ",
        "10  0   0   0   0   0   0   0   0   0   0   0   0   0   0   10  ",
        "10  0   0   0   2   0   0   0   0   0   0   0   0   0   0   10  ",
        "10  0   0   0   2   0   0   0   0   0   0   0   0   0   0   10  ",
        "10  0   0   0   2   0   2   2   0   0   0   0   0   0   0   10  ",
        "10  0   0   0   0   2   2   2   0   0   0   0   0   0   0   10  ",
        "10  0   0   0   0   0   2   2   0   0   0   0   0   0   0   10  ",
        "10  0   0   0   0   0   0   0   0   0   0   0   0   0   0   10  ",
        "10  0   0   0   0   0   0   0   0   0   0   0   0   0   0   10  ",
        "10  0   0   0   0   0   0   0   0   2   0   0   0   0   0   10  ",
        "10  0   0   0   0   0   0   0   0   2   0   0   0   2   0   10  ",
        "10  0   0   0   0   0   0   0   0   2   2   2   0   2   0   10  ",
        "10  0   0   0   0   0   0   0   0   0   0   0   0   0   0   10  ",
        "10  0   0   0   0   0   0   0   0   0   0   0   0   0   0   10  ",
        "10  0   0   0   0   0   0   0   0   0   0   0   0   0   0   10  ",
        "10  10  10  10  10  10  10  10  10  10  10  10  10  10  10  10  "};

    // 🟥🟧🟨🟩🟦🟫🟪⬛⬜🛡⚔🗡🔪🚬🧪🪓💍💰🔫💎⛲🦺♻🔰
    // 🗻🌁 🚢🏄🐳🌊⛵🌌🎇🎆🌠🌴🌱🌿🍀🎍🎋🍃🐉🐲🦕🟩🌿🍀🐍🚧🌳🌲🦴🟨🦑

    char emoji[11][5] = {"🟥", "🟧", "🟨", "🟩", "🟦", "🟫", "🟪", "⬛", "⬜", "🌑", "🗻"};
    char emoji_items[15][5] = {"🔪", "🚬", "🧪", "🪓", "💍", "💰", "🔫", "💎", "🎴", "🦺", "🏹"};

    char four[5] = "\0";

    char level[5][5] = {"🤺", "🏇", "♖ ", "♕ ", "♔ "};

    // player start point
    int x = 4;
    int y = 10;

    char move = 0;
    char arrow_list[8][5] = {"↖", "↟", "↗", "↞", "↠", "↙", "↡", "↘"};
    char arrow = 0;

    char temp_char[5] = "\0";
    int emoji_num = 0;

    int max_X = sizeof(map3[16]);
    int max_Y = sizeof(map3) / sizeof(map3[16]);

    for (;;)
    {
        printf(" ");

        printf("\n");

        printf("\n");
        printf("q  w  e  \n");
        printf(" ↖ ↟↗   \n");
        printf("a↞  ↠ d  플레이어(x,y) %d,%d\n", (x / 4), y);
        printf(" ↙ ↡↘    이동방향: %s %s\n", arrow_list[arrow], emoji[atoi(temp_char)]);
        printf("z  x  c ");

        printf(" 입력 키값 >> ");


        printf("%c\n", move);

        move = getch();

        system("clear");
    }
}

int getch()
{
    int c;
    struct termios oldattr, newattr;

    tcgetattr(STDIN_FILENO, &oldattr); // 현재 터미널 설정 읽음
    newattr = oldattr;
    newattr.c_lflag &= ~(ICANON | ECHO);        // CANONICAL과 ECHO 끔
    newattr.c_cc[VMIN] = 1;                     // 최소 입력 문자 수를 1로 설정
    newattr.c_cc[VTIME] = 0;                    // 최소 읽기 대기 시간을 0으로 설정
    tcsetattr(STDIN_FILENO, TCSANOW, &newattr); // 터미널에 설정 입력
    c = getchar();                              // 키보드 입력 읽음
    tcsetattr(STDIN_FILENO, TCSANOW, &oldattr); // 원래의 설정으로 복구
    return c;
}

 

move = getch();

printf("%c\n", move);

if (move == 65 || move == 97) // ↞a
{
    // 케릭터 좌표 변경 로직
    break;
}
else if (move == 68 || move == 100) // d↠
{
    // 케릭터 좌표 변경 로직
    break;
}
else if (move == 'x' || move == 'X' || move == 's' || move == 'S') // x↡
{
    // 케릭터 좌표 변경 로직
    break;
}
else if (move == 87 || move == 119) // w↟
{
    // 케릭터 좌표 변경 로직
    break;
}
else if (move == 81 || move == 113) // ↖q
{
    // 케릭터 좌표 변경 로직
    break;
}
else if (move == 69 || move == 101) // e↗
{
    // 케릭터 좌표 변경 로직
    break;
}
else if (move == 90 || move == 122) // ↙z
{
    // 케릭터 좌표 변경 로직
    break;
}
else if (move == 67 || move == 99) // c↘
{
    // 케릭터 좌표 변경 로직
    break;
}
else
{
    printf("이동할 수 없는 지역입니다.\n다시 입력해주세요");
    break;
}

 

 

 

 

6) kbhit

#include <termios.h>   // 터미널 I/O 속성 제어
#include <unistd.h>    // STDIN_FILENO, usleep 등 POSIX 함수
#include <fcntl.h>     // 파일 디스크립터 제어(fcntl)
#include <stdio.h>     // getchar, ungetc, EOF
#include <stdio_ext.h> // __fpurge (GNU 확장)

/*-----------------------------------------------------------
  1) getch()
     - Windows의 _getch()와 비슷하게, 한 글자를 즉시 읽어 반환
     - 내부에서 터미널을 ‘비차단·비에코·단문자’ 모드로 잠깐 변경
-----------------------------------------------------------*/
int getch(void)
{
    int c;                         // 읽어 올 문자
    struct termios oldattr, newattr;

    tcgetattr(STDIN_FILENO, &oldattr);  // 현재 터미널 속성 백업
    newattr           = oldattr;        // 복사 후 수정
    newattr.c_lflag  &= ~(ICANON | ECHO); // Canonical(라인 버퍼)·Echo 해제
    newattr.c_cc[VMIN]  = 1;            // 최소 1문자 입력 시 즉시 반환
    newattr.c_cc[VTIME] = 0;            // 대기 시간 0 (즉시)
    tcsetattr(STDIN_FILENO, TCSANOW, &newattr); // 수정 상태 적용

    c = getchar();                       // **블로킹**: 문자 입력까지 대기

    tcsetattr(STDIN_FILENO, TCSANOW, &oldattr); // 원상 복구
    return c;                            // 읽은 문자 반환
}

/*-----------------------------------------------------------
  2) kbhit()
     - Windows의 _kbhit()처럼, 입력 버퍼에 문자가 *존재*하는지만 확인
     - Non-blocking 모드로 getchar() 시도 → EOF 아니면 입력이 있음
-----------------------------------------------------------*/
int kbhit(void)
{
    /* 참고용: sleep(1)  = 1초, usleep(1 000 000) = 1초 (µs 단위) */

    struct termios oldt, newt;       // 터미널 속성
    int           ch;                // getchar 결과
    int           oldf;              // 원래 파일 플래그

    /* 1) 터미널 속성 백업 후 Canonical·Echo 해제 (라인 버퍼 off) */
    tcgetattr(STDIN_FILENO, &oldt);
    newt          = oldt;
    newt.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);

    /* 2) STDIN을 Non-blocking 플래그(O_NONBLOCK)로 변경 */
    oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
    fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

    /* 3) 실제로 문자 읽기 시도 ― 입력 없으면 EOF 즉시 반환 */
    ch = getchar();

    /* 4) 터미널 속성·파일 플래그 모두 원상 복구 */
    tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
    fcntl(STDIN_FILENO, F_SETFL, oldf);

    /* 5) 문자 있으면 다시 버퍼에 넣고 1 리턴, 없으면 0 */
    if (ch != EOF)
    {
        ungetc(ch, stdin); // 다음 getchar()가 동일 문자 읽도록 복원
        return 1;          // 입력 존재
    }
    return 0;              // 입력 없음
}

/*-----------------------------------------------------------
  3) getKey()
     - kbhit()로 먼저 입력 유무 확인
     - 있으면 getch()로 실제 문자 읽어 반환
     - 없으면 0 반환 (호출 측에서 '키 없음'으로 간주)
-----------------------------------------------------------*/
char getKey(void)
{
    __fpurge(stdin);        // 표준 입력 버퍼 비우기 (GNU 확장)
                            // → 불필요하면 제거해도 무방
    if (kbhit()) {          // 입력이 존재한다면
        return getch();     // 즉시 문자 한 개 읽어 반환
    }
    return 0;               // 아무 입력도 없을 때
}