C.언어 구조 배열 이 뱀 을 게 걸 스 럽 게 먹 는 작은 게임 을 실현 한다.
뱀 은 본질 적 으로 구조 배열 이다.배열 에 좌표 x,y 의 값 을 저장 하고 하나의 순환 을 통 해 이 를 인쇄 한다.뱀의 이동 은 끊임없이 새로 고침 하고 다시 인쇄 한다.그래서 벽 에 부 딪 히 고 자신 을 물 면 배열 x,y 값 의 간단 한 비교 일 뿐이다.
2.사용 하 는 지식 포인트
구조 배열 Windows API 함수
3.구체 적 실현
먼저 정적 페이지 를 실현 하고 지도,초기 뱀 몸,음식 을 해결 합 니 다.
여기 에는 윈도 API 지식,즉 컨트롤 러 의 좌표 수정 이 필요 하 다
// 1
void Pos(int x, int y)
{
COORD pos;
HANDLE hOutput;
pos.X = x;
pos.Y = y;
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOutput, pos);
}
COORD 는 윈도 API 에서 정의 하 는 구조 로 콘 솔 에 있 는 좌 표를 나타 낸다
typedef struct _COORD {
SHORT X; // horizontal coordinate
SHORT Y; // vertical coordinate
} COORD;
코드 의 일곱 번 째 줄 은 화면 버퍼 의 핸들 을 얻 고 여덟 번 째 줄 은 커서 위 치 를 직접 수정 하 는 함수 입 니 다.1.지도.
Pos()함수 가 있 으 면 상 자 를 인쇄 하 는 것 이 문제 가 되 지 않 습 니 다.만약 에 우리 가'-'를 상하 테두리 로 하고'|'을 좌우 테두리 로 한다 면 이것 은 타당 하지 않 을 것 같 지만 사실은 우 리 는 이미 구덩이 에 빠 졌 으 니 코드 와 실제 효과 도 를 직접 올 려 라.
//LONG==60
//WIDTH==30
void CreateMap()
{
int i;
for(i=0;i<LONG;i++)//
{
Pos(i,1);
printf("-");
Pos(i,WIDTH-1);
printf("-");
}
for(i=2;i<WIDTH-1;i++)//
{
Pos(0,i);
printf("|");
Pos(LONG-1,i);
printf("|");
}
}
문제 발 견 했 어 요?이것 은 정상 적 인 뱀 이다.근 데 왜 이상해 보 여요?테 두 리 를 모두'\#'로 바 꿔 서...
이것 은 훨씬 분명 하 다.우리 의 상하 테 두 리 는 각각 60 개의'\#'이 있 고 길이 60 너비 30 의 장방형 이 수출 된 후에 뜻밖에도 정사각형 이 되 었 다 는 것 을 알 아야 한다.
원인 은 여기에 있다.
콘 솔 에 있 는 모든 문자 의 길이 와 너비 비율(픽 셀 점)이 다 르 기 때문에 위의 그림 과 같은 알 이 아 픈 상황 이 발생 할 수 있 습 니 다.
해결 방법 도 간단 하 다.'●'■'⊙'등 특수 기 호 를 도입 해 야 한다.이 문자 들 의 특징 은 두 개의 일반 문자 의 위 치 를 차지 하 는 것 이다.
그래서 상하 테두리 에 60/2=30 개의 기호 가 있 습 니 다.정사각형 으로 유지 하려 면 좌우 도 30(28+2)개의 기호 로 설정 할 수 있 습 니 다.
코드 및 효과 도 는 다음 과 같다.
void CreateMap()
{
int i;
for(i=0;i<LONG;i+=2)
{
Pos(i,0);
printf("■");
Pos(i,WIDTH-1);
printf("■");
}
for(i=1;i<WIDTH-1;i++)
{
Pos(0,i);
printf("■");
Pos(LONG-2,i);
printf("■");
}
}
이렇게 보면 훨씬 편안 하지만 복잡 도 를 향상 시 켰 다.위의 테두리 의 모든 기호의 좌 표 는 각각(0,0)(2,0)(4,0).
2.뱀 한 마리 초기 화
뱀 과 음식 은 본질 적 으로 하나의 좌표 이기 때문에 우 리 는 새로운 데이터 유형 Node 를 정의 할 수 있다.모든 Node 는 두 개의 변수(x,y)를 저장 한 구조 체 이 고 Node 를 통 해 뱀 과 음식 을 정의 할 수 있다.
typedef struct node{
int x;
int y;
}Node;
Node snake[60];
자,이제 snake 라 는 뱀 을 정 의 했 습 니 다.이 뱀 은 비만 의 적당 한 길이 와 너비 가 일치 하기 위해 서 우 리 는'⊙'으로 뱀의 매 절 을 대표 한다.처음에 우 리 는 뱀 을 지도 중간 에 나타 나 게 했 는데 뱀 머리 는 오른쪽 에 있 고 모두 3 개의 노드 가 있 었 다.그래서 우 리 는 모든 노드 의 좌 표를 구 해 야 한다.
void InitializeSnake()
{
int i;
for(i=0;i<3;i++)
{
snake[i].x = (LONG/2-i*2);//(30,15)(28,15)(26,15)
snake[i].y = WIDTH/2;
Pos(snake[i].x,snake[i].y);
printf("⊙");
}
}
이렇게 해서 우 리 는(30,15)(28,15)(26,15)세 좌표 에서 뱀 한 마 리 를 확정 했다.X 좌표 사이 에서 2 가 줄 어 든 것 은 X 축 이 두 기본 치 를 차지 하기 때문이다.3.무 작위 음식 등장
먼저 음식의 좌 표를 저장 할 변 수 를 만 듭 니 다.
Nodefood;
그것 의 좌 표를 얻 는 것 은 사실 랜 덤 값 으로 길 고 넓 은 값 을 취하 여 구간(지도)범위 안에 있 게 하 는 것 이다.
void CreateFood()
{
int i;
srand((unsigned int)time(0));
while(1)
{
do{
food.x = rand()%(LONG-6)+2;
}while(food.x%2!=0);
food.y = rand()%(WIDTH-2)+1;
for(i=0;i<3+length;i++)
if(food.x==snake[i].x && food.y==snake[i].y)
{
i=-1;
break;
}
if(i>=0)
{
Pos(food.x,food.y);
printf("●");
break;
}
}
//AfterEatFood();
}
X 의 좌표 값 구법 은 rand()%(LONG-6)+2 이다.음식'●'도 두 글자 의 위치 이기 때문에 가능 한 수 치 는(2,y)(4,y)...(56,y)상하 가 모두 30 글자 로 넓 어 지고 0 부터 각각+2 이기 때문에 마지막 하 나 는(58,y)이다.Rand()%(LONG)의 수치 범 위 는 0~59 이 고 x=1,x=2,x=58,x=59 는 지도 범위 이기 때문에 LONG-6(60-6=54)에 나머지 를 취해 야 한다.그러면 수치 범 위 는 0~54 이 고 2 를 더 하면 2~56 이 된다.또한 뱀의 각 절 좌표 와 이동 x 좌 표 는 모두+2 이기 때문에 음식의 x 좌 표 는 반드시 짝수 여야 한다.이것 은 도(...)while()로 해결 하고 먼저 값 을 취하 고 판단 하면 안 되면 다시 수치 를 얻 을 수 있다.
Y 의 좌 표 는 조금 간단 합 니 다.좌표 값 이 1~28 이면 됩 니 다.
또 좌 표를 구하 고 음식 이 뱀 몸 과 겹 치 는 지 판단 하고 겹 치면 다시 값 을 부여 한다.
위의 것 을 다 하면 우 리 는 기본 적 인(정적)효 과 를 얻 을 수 있다.지금 우 리 는 그것 을 움 직 이게 해 야 한다.
주:86 줄 은 콘 솔 창 이 길 고 넓 은 시스템 함 수 를 설정 합 니 다.
4.뱀 을 움 직 이게 한다
뱀 이 이동 할 때마다 발생 하 는 일 은 배열 의 값 이 바 뀌 고 모든 좌표 위치 에서 뱀 몸 을 인쇄 하 는 것 이다.
뱀 이 계속 움 직 이기 위해 서 우 리 는 순환 이 필요 하 다.
while(1)
{
// ,
//
}
우선,우 리 는 방향 을 정 해 야 한다.이것 은 두 개의 변수 가 필요 하 다.하 나 는 입력 값(임의의 값 일 수 있다)이 고,다른 하 나 는 방향 을 정 하 는 변수 이다.여기 함수 하나 소개 할 게 요.
int kbhit(void);
// , 0 , 0
이것 은 비 차단 함수 입 니 다.키 를 눌 렀 을 때 0 이 아 닌 것 으로 되 돌아 갑 니 다.그러나 이 때 버튼 코드 는 키보드 버퍼 대기 열 에 있 습 니 다.따라서 키보드 에 응답 이 있 는 지 확인 한 후에 char 변 수 를 사용 하여 입력 을 버퍼 에서 조정 합 니 다.
if(kbhit())
ch = getch();
ch 를 판단 하고 상황(뒤로 갈 수 없 음 등)에 맞 는 입력 이 라면 switch 를 실행 하여 좌 표를 바 꿉 니 다.
if(ch=='w'&&direction!='s')
direction = ch;
else if(ch=='s'&&direction!='w')
direction = ch;
else if(ch=='a'&&direction!='d')
direction = ch;
else if(ch=='d'&&direction!='a')
direction = ch;
else if(ch==' ')
continue;
여기 빈 칸 을 설정 하 는 것 은 일시 정지 입 니 다.뱀 이 처음부터 이동 하도록 direction 을 d(오른쪽으로)로 설정 합 니 다. 방향 이 확 정 된 후에 하나의 switch 문 구 를 사용 하여 좌 표를 판단 합 니 다.
switch(direction)
{
case 'w':
if(snake[0].x==food.x && snake[0].y-1==food.y)
{
length++;
score+=10;
snake[2+length].x = snake[2+length-1].x;
snake[2+length].y = snake[2+length-1].y;
for(i=length+3-2;i>0;i--)
{
snake[i].x = snake[i-1].x;
snake[i].y = snake[i-1].y;
}
CreateFood();
}
else
{
Pos(snake[2+length].x,snake[2+length].y);
printf(" ");
for(i=length+3-1;i>0;i--)
{
snake[i].x = snake[i-1].x;
snake[i].y = snake[i-1].y;
}
}
snake[0].y -=1;
break;
case 's':
//。。。
case 'a':
//。。。
case 'd':
//。。。
}
뱀 머리의 다음 단 계 를 판단 하고 음식 을 먹 었 을 때 점수 등 전역 변 수 를 처리 한 다음 에 snake[2+length-1](음식 을 먹 은 후의 마지막 두 번 째 변수)의 값 을 snake[2+length](이때 새로 추 가 된 꼬리 부분)에 부여 합 니 다.마지막 두 번 째 절 부터 앞의 절 좌표 값 을 뒤의 절 에 부여 하고 두 번 째 절 이 이전의 뱀 머리 좌 표를 얻 을 때 까지 한다.음식 이 먹 힌 후에 무 작위 로 음식 함수 가 나타난다.
음식 을 먹 지 못 했다 면 마지막 절 좌표 에 먼저 가서 빈 칸 을 입력 하면 없 애고 각 절 에 다시 값 을 부여 하 는 셈 이다.뱀 머리 뒤에 마디 마다 값 을 부여 한 후에 입력 값 에 따라 단독으로 뱀 머리 에 값 을 부여 합 니 다.예 를 들 어'w'를 입력 하면 위로 올 라 가기 때문에 뱀 머리 는 세로 좌표 에서 1 을 줄 입 니 다.
나머지 입력 도 마찬가지 입 니 다.snake 배열 의 각 값 을 업데이트 한 후에 하나의 함수 로 인쇄 합 니 다.
이렇게 이동 부분 이 이 루어 졌 으 니 이 제 는 작은 모듈 만 처리 하면 된다.
5.이동 후 처리.
이 부분 은 상대 적 으로 간단 하 다.즉,뱀 이 벽 에 부 딪 혔 는 지,자신 을 물 었 는 지 판단 한 다음 에 이런 상황 을 처리 하 는 것 이다.우 리 는 두 가지 함수 로 그것 을 해결 하 는 것 이다.
int ThroughWall()
{
if(snake[0].x==0 || snake[0].x==58 ||
snake[0].y==0 || snake[0].y==29)
{
Pos(25,15);
printf(" ");
return 1;
}
Pos(0,WIDTH);
printf(" ");
}
int BiteItself()
{
int i;
for(i=3;i<=2+length;i++)
if((snake[0].x==snake[i].x) && (snake[0].y==snake[i].y))
{
Pos(25,15);
printf(" ");
return 1;
}
}
반환 값 이 1 이면 게임 도 GG 입 니 다.
if(ThroughWall()==1)
{
Pos(25,WIDTH);
system("pause");
exit(0);
}
if(BiteItself()==1)
{
Pos(25,WIDTH);
system("pause");
exit(0);
}
마지막 으로 Sleep()함 수 를 한 줄 더 추가 하여 리 셋 시간(매번 다시 인쇄 하 는 시간 간격)을 처리 합 니 다.speed 는 음식 을 먹 을 때마다 줄 어드 는 변수 이다.Sleep(speed);
소스 코드 여기 있 습 니 다:구조 배열 구현_탐식 하 다.
4.정리 와 반성.
먼저 뱀의 구조 적 으로 볼 때 구조 배열 의 실현 은'효율'이라는 단 어 를 직접적 으로 무시 했다.배열 은 대량의 공간 을 차지 하고 용량 제한 이 있 으 며 좋 은 방법 이 아니다.
그 다음으로 BUG 의 문 제 는 Through Wall()함수 에서 뱀 머리 좌 표를 판단 할 때 뱀 머리 에서(x,1)위치 로 이동 할 때 게임 이 바로 끝나 고 아무런 힌트 도 없다.
그러나 이상 하 게 도 판단 후 Pos(0,WIDTH)를 넣는다.printf(" "); 이 두 줄 의 상 관 없 는 문장 후에 이 문 제 는 해결 되 었 고,나 는 이 두 줄 의 문장 에 대한 원래 의 목적 은 단지 끊임없이 반 짝 이 는 커서 를 지도 밖으로 내 보 내 려 고 했 을 뿐이다.
그리고 while()순환 에 코드 줄 이 너무 많 습 니 다.특히 switch-case 에 있 는 각종 뱀 몸의 이동(구조 배열 의 요소 좌표 값 변환)은 move()함수 로 추상 화 되 어야 합 니 다.
기타
이것 은 나의 첫 번 째 코드(snakeV 1.0)에 대한 재 구성 으로 프로그램 구조 에 큰 변화 가 있다.
재 구성 기간 에링크 구현탐식 하 다.을 연 구 했 고 구조 적 으로 안의 일부 사상 을 채택 했다.
개인 텅 빈 github:MagicXyxxx 의 github
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C 언어 체인 시계는 뱀을 탐식하는 작은 게임을 실현한다본고의 실례는 여러분에게 C 언어 체인표가 뱀 탐식 게임을 실현하는 구체적인 코드를 공유하여 참고하도록 하였으며, 구체적인 내용은 다음과 같다. 프로젝트 이름: 뱀놀이 운영 환경: Linux 프로그래밍 언어: C 언...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.