밑에소스가요 에러는안뜨는데 게속 이상해서요 포인터쪽이 문제인데! 도와주세요 뭘 어뜩해 고쳐야할지 모르겟ㄴㅔ요
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

 

typedef struct game { // 데이터 저장용 구조체 선언
 int first; // 처음에 쓰러뜨린 핀 수
 int second; // 스페어 처리 핀 수
 int score; // 해당 프레임의 점수 저장
 int curFrame; // 현재 프레임 확인용 플래그
} GAME; // GAME 이라는 type 으로 해당 구조체를 정의함

 

GAME *Game[12][4] = {0}; // 12 , 4의 2차원 배열 GAME 구조체를 선언함 - 원래는 10 , 4면 되긴 하지만 점수 계산때문에 10 이상의 뒷자리가 필요함.
int Bonus[4] = {0}; // 마지막 프레임의 마지막 보너스 핀 수 저장하는 배열 선언
int Price[4] = {0}; // 등수 출력을 위한 배열 선언

 

int InputIntControl(int*, int, int); // 범위를 설정하여 정수를 입력받는 함수

void ProcessFrame(int, int);  // 프레임에서 쓰러뜨린 핀 수를 입력하는 부분이 들어있는 함수

void DisplayScoreBoard(int, int); // 스코어 보드를 보여주는 함수

int ControlScore(int, int, int); // 스코어 보드의 점수 표시를 제어하는 함수

void CalCulScore(int, int); // 점수를 계산하는 함수

void Swap(int*, int*); // 두 정수를 서로 바꿔주는 함수

 

int main() // 메인 함수 시작
{
 int i, frame, turn, player; // 프레임, 플레이어 차례, 플레이어 최대 명수 변수 선언

 printf(\"\\n ****************************************\\n\");
 printf(\" *\\t 볼링 점수 계산 프로그램\\t*\");
 printf(\"\\n ****************************************\\n\\n\\n\");
 printf(\"게임에 참여할 선수의 수를 입력하세요 (최대 4명) : \");
 
 if (InputIntControl(&player, 0, 4)) { // 범위 설정 정수 입력 함수를 호출하여 player에 입력을 받음
  printf(\"\\n%d명이 게임을 시작합니다.\\n\\n\", player); // 게임 시작 인원 출력
 }

 for (frame = 0; frame < 10; ++frame) { // 10 프레임까지 for문 반복
  for (turn = 0; turn < player; ++ turn) { // player의 수 만큼 turn for문 반복
   ProcessFrame(frame, turn); // 프레임에서 쓰러뜨린 핀 수 입력받는 함수 호출
   DisplayScoreBoard(frame, player); // 스코어보드를 보여주는 함수 호출
  }
 }

 for (i = 0; i < player; ++i) // 점수 표시용 배열에 점수 전부 넣어주기 위한 반복
  Price[i] = Game[9][i]->score;

 for(turn = 0; turn < player; ++ turn) { // 버블 정렬 실행하여 점수를 높은순서대로 정렬
  for (i = 0; i < player - 1; ++i) {
   if (Price[i] < Price[i + 1])
    Swap(&Price[i], &Price[i + 1]);
  }
 }

 for (i = 0; i < player; ++i) // 점수가 높은 순으로 출력
  printf(\"%d 등 - %d 점\\n\", i + 1, Price[i]);

 return 0;
}

 

void ProcessFrame(int frame, int turn) // 프레임에서 쓰러뜨린 핀 수 입력받는 함수 정의
{
 ++Game[frame][turn]->curFrame; // 함수가 시작하면 해당 플레이어의 프레임 확인 플래그를 1 더해준다.
 printf(\" %d번째 프레임에서 %d번째 선수가 쓰러뜨린 핀의 수를 입력하세요. \", frame + 1, turn + 1);
 InputIntControl(&Game[frame][turn]->first, 0, 10); // 핀 수는 0개부터 10개까지이므로 범위를 0 ~ 10 지정하여 범위 설정 정수 입력 함수 호출
 if(Game[frame][turn]->first < 10 && Game[frame][turn]->first >= 0) { // 스트라이크가 아닐때
  printf(\" %d개의 핀이 남았습니다. 스페어 처리된 핀의 수를 입력하세요. \", 10 - Game[frame][turn]->first);
  InputIntControl(&Game[frame][turn]->second, 0, 10 - Game[frame][turn]->first); // 0 ~ 남은 핀 수 범위 설정 정수 입력 함수 호출
  if(Game[frame][turn]->first + Game[frame][turn]->second == 10) { // 스페어 처리 성공일때
   printf(\"   스페어 처리 되었습니다. 축하합니다 !!!\");
   if(frame + 1 == 10) { // 10프레임일때 보너스 프레임을 더 입력받는다
    printf(\"\\n  보너스 프레임 1번의 기회가 더 주어집니다!!\\n\");
    printf(\"  보너스 프레임에서 쓰러뜨린 핀의 수를 입력하세요.  \");
    InputIntControl(&Bonus[turn], 0, 10); // 보너스로 쓰러뜨린 핀 수 범위 설정 정수 입력 함수 호출하여 입력
   }
  }
 }
 if(Game[frame][turn]->first == 10) { // 스트라이크 일때
  printf(\"    스트라이크 입니다. 축하합니다 !!!\");
  if(frame + 1 == 10) { // 10프레임일때 보너스 프레임을 더 입력받는다
   printf(\"\\n  보너스 프레임 2번의 기회가 더 주어집니다!!\\n\");
   printf(\"  첫번째 보너스 프레임에서 쓰러뜨린 핀의 수를 입력하세요.  \");
   InputIntControl(&Game[frame][turn]->second, 0, 10); // 10프레임 스트라이크에 의한 첫번째 보너스는 10프레임 스페어 처리로 입력받음
   printf(\"  두번째 보너스 프레임에서 쓰러뜨린 핀의 수를 입력하세요.  \");
   InputIntControl(&Bonus[turn], 0, 10); // 두번째 보너스는 보너스에 입력받음
  }
 }
}

 

void DisplayScoreBoard(int frame, int player) // 스코어보드 보여주는 함수 정의
{
 int pin, turn, result; // 프레임 당 핀 수 출력하는 변수, 플레이어 차례, 프레임 결과 체크용 변수 선언
 printf(\"\\n┏━━━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━┳━━━┓\\n\");
 printf(\"┃ 프레임 ┃   1┃   2┃   3┃   4┃   5┃   6┃   7┃   8┃   9┃    10┃\\n\");
 printf(\"┣━━━━╋━━╋━━╋━━╋━━╋━━╋━━╋━━╋━━╋━━╋━━━┫\\n\");
 for(turn = 0; turn < player; turn++) { // 플레이어 마다의 for문 반복
  printf(\"┃ 선수 %d ┃\", turn + 1); // 선수 번호 출력
  for(pin = 0; pin < 9; pin++) { // for 반복문을 이용하여 프레임마다의 쓰러뜨린 핀 수 출력해줌
   if (!Game[pin][turn]->curFrame)
    printf(\"    ┃\"); // 현재 진행된 프레임이 아닌 경우 공백
   else if (Game[pin][turn]->first != 10 && Game[pin][turn]->first + Game[pin][turn]->second == 10)
    printf(\"%2d /┃\", Game[pin][turn]->first); // 스페어 처리가 잘 끝난 프레임 출력
   else if (Game[pin][turn]->first == 10)
    printf(\" x  ┃\"); // 스트라이크로 끝난 프레임 출력
   else if (Game[pin][turn]->first + Game[pin][turn]->second != 10)
    printf(\"%2d%2d┃\", Game[pin][turn]->first, Game[pin][turn]->second); // 나머지 보통 프레임 출력
  }
  switch(Game[9][turn]->first) { // 마지막 10프레임의 첫번째 처리 핀수를 인수로 switch문 실행
  case 10: // 10이면 스트라이크
   printf(\" x\");
   break;

  default: // 나머지 경우
   if (!Game[9][turn]->curFrame)
    printf(\"  \"); // 10프레임이 진행된 적이 없을 경우 공백
   else
    printf(\"%2d\", Game[9][turn]->first); // 아니면 숫자 출력
   break;
  }
  switch(Game[9][turn]->second) { // 마지막 10프레임의 두번째 처리 핀수를 인수로 switch문 실행
  case 0: // 0이면
   if (!Game[9][turn]->curFrame) // 10프레임이 진행된 적이 없을 경우 공백
    printf(\"  \");
   else // 아니면 0 출력
    printf(\" 0\");
   break;
  
  case 1:
  case 2:
  case 3:
  case 4:
  case 5:
  case 6:
  case 7:
  case 8:
  case 9: // 1 ~ 9의 경우
   if(Game[9][turn]->first+Game[9][turn]->second == 10) { // 첫번째와 현재의 합이 10이면 스페어 처리가 잘 끝났다는 것임
    printf(\" /\"); // 스페어 처리 표시 출력
    break;
   }
   else {
    printf(\"%2d\", Game[9][turn]->second); // 아니면 그냥 숫자 출력
    break;
   }

  case 10: // 10개 쓰러뜨린 경우
   if(Game[9][turn]->first == 0) { // 첫번째가 0일 경우는 스페어 처리이다
    printf(\" /\");
    break;
   }
   else {
    printf(\" x\"); // 아니면 스트라이크
    break;
   }
  }
 
  switch(Bonus[turn]) { // 10프레임 마지막 보너스 기회
  case 0: // 0일 경우
   if (!Game[9][turn]->curFrame) // 10프레임이 진행된 적이 없으면
    printf(\"  \"); // 공백을 출력
   else
    printf(\" 0\"); // 아니면 0을 출력
   break;

  case 1:
  case 2:
  case 3:
  case 4:
  case 5:
  case 6:
  case 7:
  case 8:
  case 9: // 1 ~ 9 경우
   if(Game[9][turn]->second + Bonus[turn] == 10) { // 두번째와 세번째의 합으로 10개를 쓰러뜨렸을 경우
    printf(\" /\"); // 스페어 처리
    break;
   }
   else {
    printf(\"%2d\", Bonus[turn]); // 핀 개수 표시
    break;
   }
  case 10: // 10개 쓰러뜨렸을 경우
   if(Game[9][turn]->second == 0) { // 앞에서 0개 쓰러뜨렸을 경우
    printf(\" /\"); // 스페어 처리로 인식
    break;
   }
   else {
    printf(\" x\"); // 스트라이크
    break;
   }
  }
  printf(\"┃\\n\");
  printf(\"┃        ┃\");
 
  for(result = 0; result < 9; result++) { // 점수 출력 부분 for문
   if (!Game[result][turn]->curFrame || !ControlScore(result, turn, frame)) // 이미 진행된 프레임이 아니거나 계산 이유상 점수 출력이 불가능하 경우
    printf(\"    ┃\"); // 공백을 출력
   else
    printf(\"%4d┃\", Game[result][turn]->score); // 점수를 출력해줌 - 점수 계산은 ControlScore안에서 해줌
  }
  if (Game[9][turn]->curFrame) { // 10번 프레임이 진행되었을 경우 경우
   CalCulScore(9, turn); // 마지막 점수 계산 수행
   printf(\"%6d┃\", Game[9][turn]->score); // 10번 프레임에 점수 출력
  }
  else
   printf(\"      ┃\"); // 공백 출력

  if(turn == player - 1) // 플레이어의 차례 변수의 증가가 플레이어 수 - 1 까지 되었을 경우 스코어보드 밑을 닫아줌.
   printf(\"\\n┗━━━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━┻━━━┛\\n\\n\");
  else // 아니면 연결되는 부분으로 출력.
   printf(\"\\n┣━━━━╋━━╋━━╋━━╋━━╋━━╋━━╋━━╋━━╋━━╋━━━┫\\n\");
 }  
}

 

int ControlScore(int result, int turn, int frame) // 스코어 보드의 점수 표시를 제어하는 함수 정의
{
 if (frame < 9) { // 프레임이 10프레임 미만일 경우
  if (Game[result][turn]->first == 10 && (!Game[result + 1][turn]->curFrame || Game[result + 1][turn]->first == 10) && !Game[result + 2][turn]->curFrame) {
   return 0; // 연속 3 스트라이크이거나 스페어 처리나 다음 차례가 아직 시작 하지 않는 등으로 당장 점수 계산이 불가능할 때 불가능하다고 0 리턴.
  }

  if (Game[result][turn]->first + Game[result][turn]->second == 10 && !Game[result + 1][turn]->curFrame) {
   return 0; // 스페어 처리가 되었지만 다음 차례가 아직 시작하지 않아 점수 출력 불가능하다고 0 리턴
  }
 }

 CalCulScore(result, turn); // 점수를 계산하여 score 안에 넣어주는 함수 호출.

 return 1; // 1을 리턴 - 리턴값에 따라서 공백 출력이거나 점수 출력이 결정된다.
 
}

 

void CalCulScore(int result, int turn) // 점수 계산하는 함수 정의
{
 int oldscore = 0; // 이전 스코어 선언 후 정의
 if (result > 0) // 프레임이 1프레임이 아닌 경우
  oldscore = Game[result - 1][turn]->score; // 이전 스코어에 이전까지의 누적 점수값 넣어줌.
 if (Game[result][turn]->curFrame) { // 실행된 적이 있는 프레임일 경우에 아래의 문장 실행
  if (result == 9) // 10 프레임인 경우
    Game[result][turn]->score = oldscore + Game[result][turn]->first + Game[result][turn]->second + Bonus[turn]; // 10프레임 두번째 세번째 등의 예외 처리를 위해 추가된 문장
  else {
   if (Game[result][turn]->first == 10) { // 스트라이크일 경우
    if (Game[result + 1][turn]->first == 10 && Game[result + 2][turn]->first == 10) // 3연속 스트라이크일 경우 (터키 / 트리플)
     Game[result][turn]->score = oldscore + 30; // 맨 처음 스트라이크에 30점 추가
    else // 그렇지 않으면 10점 + 다음 프레임의 첫번째와 두번째 쓰러뜨린 핀 수 의 합을 더해준 것을 점수에 누적
     Game[result][turn]->score = oldscore + 10 + Game[result + 1][turn]->first + Game[result + 1][turn]->second;
   }
   else if (Game[result][turn]->first != 10 && Game[result][turn]->first + Game[result][turn]->second == 10) // 스페어 처리의 경우
    Game[result][turn]->score = oldscore + 10 + Game[result + 1][turn]->first; // 10점에서 다음 프레임의 첫번째 쓰러뜨린 핀 수 의 합을 더해준 것을 점수에 누적
   else
    Game[result][turn]->score = oldscore + Game[result][turn]->first + Game[result][turn]->second; // 현재 프레임의 첫번째와 두번째 쓰러뜨린 핀 수의 값 누적
  }
 }
}

 

int InputIntControl(int* input, int bottom, int top) // 정수의 범위를 입력하고 그 범위 내의 정수만 입력받을 수 있게 하는 함수
{
 char n[32]; // 문자열 크기 32짜리 선언
 int temp; // 임시용 정수 변수 선언

 while (scanf(\"%s\",n) == 1) { // scanf로 정상적인 문자열 1개가 입력될 때 까지 반복함
 
  fflush(stdin); // scanf 입력 버퍼에 들어있는 것을 날려버림
 
  if (atoi(n) == 0 && strcmp(n, \"0\") != 0) // atoi(n) - 문자열을 정수로 바꿔주는 함수(숫자만 넣을 수 있고 다른 값을 넣으면 0이 나옴)
   temp = top + 1; // atoi() 함수와 strcmp(스트링 비교 함수) 를 이용하여 정확히 정수가 들어왔는지 판단한다. 틀리면 top + 1을 강제 입력.
  else
   temp = atoi(n); // 맞으면 정수로 치환된 입력값을 임시 변수에 넣음.

  if (temp > top || temp < bottom) { // 입력받은 정수가 top보다 크거나, bottom 보다 작으면 오류 메세지 출력 후 continue;
   printf(\"정수 입력 오류입니다. 다시 입력하세요 : \");
   continue;
  }

  *input = temp; // call by reference 에 의한 외부에서 입력된 *input 의 내용이 변경됨.

  break; // 잘 되었으면 break
 }
 return 1; // 위의 과정들이 잘 되었으면 1을 리턴
}

 

void Swap(int *p, int *q) // 버블 정렬을 위해 두 수를 바꿔주는 함수 정의
{
 int tmp;

 tmp = *p;
 *p = *q;
 *q = tmp;
}