C언어 실무 프로젝트

C언어 오목 프로그램(2인용, 2차원 배열과 심화된 제어문 로직 활용) Windows API 및, 표준 라이브러리 사용 (x86 버전)

C's everything! 2022. 5. 28. 17:29
반응형

-------------------   Visual Studio x86 (32비트 프로그램) 기준입니다. --------------------

기존 소스에 (1P, 2P) 조작, 게임방법, 무승부, 상대 전적, 오목판 확장, 흑돌의 금수 알고리즘 등을 추가했습니다.

함수와 상수의 선언은 "omk.h" 헤더파일에 포함되어 있습니다.

소스가 길다보니 visual studio에 복붙하셔서 크게 보시는게 좋을 듯 싶습니다.

금수 알고리즘의 일부분을 구현하였습니다. 나머지는 이후에 더 확장시키도록 하겠습니다.

omok.h
0.00MB
omok.exe
0.02MB
오목 실행 화면
오목의 금수 알고리즘

#include "omok.h"


int main(void) {
	int end = 1;				// 차례 시작
	int j, k;				// for문 반복 변수
	char key;				// 게임 종료후 계속 진행할 여부

	start();				// 플레이어 이름 입력 받음
	reconfig();				// 게임 화면

	while (1) {
		while (end) {			// end==0, 즉, 오목이 될 때까지 진행한다.
			gotoxy(0, 22);
			if (stone == 1)printf(" ○[%s]님 차례입니다.", black_player);
			else printf(" ●[%s]님 차례입니다.", white_player);

			input(&stone);
			// 방향키에 따라 좌표를 이동하고 Enter or Space키를 누르면 해당 위치에 돌을 착수
			count++;			// 수 증가

			reconfig();			// 입력 받으면 화면 갱신
			end = omok_check(stone);	// 오목이면 0, 아니면 1을 리턴
			if (end == 0)break;
			if (stone == 1)stone = 2;	// 차례 변경, black -> white
			else stone = 1;			// 차례 변경, white -> black
		}

		victory();					// 승리자 출력

		gotoxy(43, 17);
		printf("계속하시겠습니까? (y/n)");
		key = _getch();
		if (key == 'n' || key == 'N') {			// 중단하려면
			reconfig();
			gotoxy(10, 22);
			puts("아무 키나 누르면 프로그램을 종료합니다.");
			gotoxy(10, 24);
			_getch();
			puts("머리 쓰느라 고생 많으셨습니다. 푹 쉬세요.");
			break;
		}
		else if (key == 'y' || key == 'Y') {	// 계속하려면
			end = 1;
			for (j = 0; j < 19; j++) {
				for (k = 0; k < 19; k++) {
					xy[k][j] = 0;			// 오목판 데이터 초기화
				}
			}
			count = 0;
			stone = 1;	// 1 player의 차례로 변경
			reconfig();	// 오목판 재구성
		}
	}
	return 0;
}// main함수의 끝

void start(void) {		// 플레이어 입력
	puts("\n (19*19)규격의 2인용 오목 버전입니다.");
	puts("\n 1 ~ 20자 이내로 입력하세요.(공백 입력도 가능, 한글은 2자로 취급)");
	printf("\n [○] -> 1 player 이름 : ");
	scanf(" %[^\n]s", black_player);	// [^\n]: 공백도 입력 받게함.
	printf("\n [●] -> 2 player 이름 : ");
	scanf(" %[^\n]s", white_player);	// [^\n]: 공백도 입력 받게함.
	fflush(stdin);		// 버퍼를 비워줌.

	puts("\n 2초후 게임을 시작합니다. 준비하세요!!!");
	Sleep(2000);		// 2초 정지
}

void reconfig()		// 게임 화면 구성
{
	int x, y;

	system("cls");		// 화면 청소
	for (x = 0; x < 19; x++) {				// 오목판 재구성
		for (y = 0; y < 19; y++) {
			if (xy[x][y] == 1)printf("○");		// black_player의 돌
			else if (xy[x][y] == 2)printf("●");	// white_player의 돌
			else if (xy[x][y] == 0)printf("┼ ");	// 돌이 없을 때
								//(┼ 뒤에 공백을 꼭 입력!)
		}
		printf("\n");	// y의 for문 종료 시, 다음 줄부터 입력
	}

	gotoxy(43, 1); puts("상대 전적");
	gotoxy(43, 3); printf("○ %s : %d승 %d패 %d무",	// 흑의 전적 표시
		black_player, black_score, white_score, draw);
	gotoxy(43, 4); printf("● %s : %d승 %d패 %d무",	// 백의 전적 표시 
		white_player, white_score, black_score, draw);
	gotoxy(43, 6); printf("수 : %03d", count);

	gotoxy(75, 1); puts("1 player 조작 키");
	gotoxy(75, 3); puts("        위:↑");
	gotoxy(75, 4); puts("←:왼쪽 ● 오른쪽:→ 착수:Space");
	gotoxy(75, 5); puts("      아래:↓");

	gotoxy(75, 9); puts("2 player 조작 키");
	gotoxy(75, 11); puts("        위:↑(8)");
	gotoxy(75, 12); puts("(4)←:왼쪽 ● 오른쪽:→(6) 착수:Enter");
	gotoxy(75, 13); puts("      아래:↓(5)");

	gotoxy(75, 17); puts("공통 조작 키");
	gotoxy(78, 19); puts("프로그램 종료: !");
	gotoxy(78, 20); puts("  무승부 신청: @");


	gotoxy(60, 24); puts("렌주룰 적용: 흑은 3*3, 4*4, 장목(육목 이상)금지");
	gotoxy(60, 25); puts("단, 열린 3과 열린 4에서는 적용되지 않는다.");

}

int Draw(int* stone)	// 무승부 신청
{
	int a;
	gotoxy(43, 14);
	printf("%d player의 무승부 요청!", *stone);
	gotoxy(43, 16);
	puts("승낙: y, 거절: 임의 키");
	a = _getch();

	if (a == 'y' || a == 'Y')	// 승낙
	{
		draw++;	// 전적에 들어갈 무승부 값
		for (int j = 0; j < 19; j++) {
			for (int k = 0; k < 19; k++) {
				xy[k][j] = 0;			// 오목판 데이터 초기화
			}
		}
		gotoxy(43, 18);
		puts("3초 후에 새로 시작");
		Sleep(3000);
		count = -1;		// 이후에 main()에서 1증가
		if (*stone)*stone = 2;	// 흑돌이 무승부를 요청했어도, 흑돌부터 다시 시작
					// main()에서 한 번 더 바뀌기 때문에 2로 할당
		return 0;
	}
	else // 거절
	{
		reconfig();		// 재구성
		gotoxy(0, 22);
		if (*stone == 1)printf(" ○[%s]님 차례입니다.", black_player);
		else printf(" ●[%s]님 차례입니다.", white_player);
		return 1;
	}
}
void input(int* stone)
{
	char check;			// 금수 switch문 변수
	char c;				// switch문 레이블
	int end = 1;			// while문 변수 ( 0 or 1 )

	if (*stone == 1)		// 1 player의 차례
	{
		gotoxy(x2, y);		// 차례 메시지 출력 후 커서를 돌의 위치로 이동

		while (end) {		// Space키를 누르면 해당 좌표에 1 저장하고 종료
			
			c = _getch();
			switch (c)	// 정의된 문자만을 취급
			{
			case KEYRIGHT:	// 오른쪽 방향키
				if (x < 18) { x++; x2 += 2; }	// x2: 돌은 2칸을 차지
				gotoxy(x2, y);			// x는 좌표 값, x2는 출력할 좌표 값
				break;
			case KEYLEFT:
				if (x > 0) { x--; x2 -= 2; }
				gotoxy(x2, y);
				break;
			case KEYUP:
				if (y > 0) y--;
				gotoxy(x2, y);
				break;
			case KEYDOWN:
				if (y < 18)y++;
				gotoxy(x2, y);
				break;
			case SPACE:
				if (xy[y][x] != 0)break;	// 이미 착수된 곳이면 입력 무시

				xy[y][x] = 1;

				check = check_33_44_jang();

				switch (check)
				{
				case 1:
					gotoxy(43, 8); puts("3*3 금수입니다!");
					gotoxy(43, 9); puts("흑은 그곳에 둘 수 없습니다.");
					xy[y][x] = 0;		// 금수이므로 다시 0으로 초기화
					break;
				case 2:
					gotoxy(43, 8); puts("4*4 금수입니다!");
					gotoxy(43, 9); puts("흑은 그곳에 둘 수 없습니다.");
					xy[y][x] = 0;		// 금수이므로 다시 0으로 초기화
					break;
				case 3:
					gotoxy(43, 8); puts("장목 금수입니다!");
					gotoxy(43, 9); puts("흑은 그곳에 둘 수 없습니다.");
					xy[y][x] = 0;		// 금수이므로 다시 0으로 초기화
					break;
				default:
					break;
				}
				gotoxy(x2, y);
				if (check == 0) end = 0;	// 반복문 탈출
				break;
			case DRAW:
				end = Draw(stone);	// 0이면 무승부, 1이면 기각
				break;
			case EXIT:
				system("cls");
				exit(0);			// 프로그램 종료
			}// switch()
		}// while()
	}// if(stone == 1)

	else // 2 player의 차례
	{
		gotoxy(x2, y);		// 차례 메시지 출력 후 커서를 돌의 위치로 이동

		while (end) {		// Enter키를 누르면 해당 좌표에 2 저장하고 종료
			c = _getch();
			switch (c)		// 정의된 문자만을 취급
			{
			case RIGHT:
				if (x < 18) { x++; x2 += 2; }	// x2: 돌은 2칸을 차지
				gotoxy(x2, y);			// x는 좌표 값, x2는 출력할 좌표 값
				break;
			case LEFT:
				if (x > 0) { x--; x2 -= 2; }
				gotoxy(x2, y);
				break;
			case UP:
				if (y > 0) y--;
				gotoxy(x2, y);
				break;
			case DOWN:
				if (y < 18)y++;
				gotoxy(x2, y);
				break;
			case ENTER:
				if (xy[y][x] != 0)break;	// 이미 착수된 곳이면 입력을 무시
				xy[y][x] = 2;
				end = 0;				// 반복문 탈출
				break;
			case DRAW:
				end = Draw(stone);			// 0이면 무승부, 1이면 기각
				break;
			case EXIT:
				system("cls");
				exit(0);				// 프로그램 종료
			}// switch()
		}// while()
	}// else
}// input()

int check_33_44_jang(void)
{
	int c = 0;	//  금수 초기값(금수가 아닐 때)
			//  흑돌의 3*3 금수 규칙 지정 ( 뒤에 == 0 을 쓴 이유는  3*3은 열린 3 (3의 양옆이 막혀있지 않은 3) 에서만 적용되기 때문이다.)

	if ((xy[y][x - 2] == 1 && xy[y][x - 1] == 1 && xy[y][x] == 1 && xy[y][x + 1] == 1 && xy[y][x + 2] == 1 && xy[y][x - 3] == 0 && xy[y][x + 3] == 0) ||	// 가로 3*3 검사
		(xy[y - 2][x] == 1 && xy[y - 1][x] == 1 && xy[y][x] == 1 && xy[y + 1][x] == 1 && xy[y + 2][x] == 1 && xy[y - 3][x] == 0 && xy[y + 3][x] == 0) ||	// 세로 3*3 검사

		(xy[y - 2][x - 2] == 1 && xy[y - 1][x - 1] == 1 && xy[y][x] == 1 && xy[y - 1][x + 1] == 1 && xy[y - 2][x + 2] == 1 && xy[y - 3][x - 3] == 0 && xy[y - 3][x + 3] == 0) ||	//	대각선 V 검사

		(xy[y + 2][x - 2] == 1 && xy[y + 1][x - 1] == 1 && xy[y][x] == 1 && xy[y + 1][x + 1] == 1 && xy[y + 2][x + 2] == 1 && xy[y + 3][x - 3] == 0 && xy[y + 3][x + 3] == 0) ||	//	대각선Λ 검사

		(xy[y - 2][x - 2] == 1 && xy[y - 1][x - 1] == 1 && xy[y][x] == 1 && xy[y + 1][x - 1] == 1 && xy[y + 2][x - 2] == 1 && xy[y - 3][x - 3] == 0 && xy[y + 3][x - 3] == 0) ||	//	대각선 > 검사	

		(xy[y - 2][x + 2] == 1 && xy[y - 1][x + 1] == 1 && xy[y][x] == 1 && xy[y + 1][x + 1] == 1 && xy[y + 2][x + 2] == 1 && xy[y - 3][x + 3] == 0 && xy[y + 3][x + 3] == 0) ||	//  대각선 < 검사

		(xy[y - 2][x - 2] == 1 && xy[y - 1][x - 1] == 1 && xy[y][x] == 1 && xy[y + 1][x + 1] == 1 && xy[y + 2][x + 2] == 1 && xy[y - 3][x - 3] == 0 && xy[y + 3][x + 3] == 0) ||	//	대각선 검사  ↘

		(xy[y - 2][x + 2] == 1 && xy[y - 1][x + 1] == 1 && xy[y][x] == 1 && xy[y + 1][x - 1] == 1 && xy[y + 2][x - 2] == 1 && xy[y - 3][x + 3] == 0 && xy[y + 3][x - 3] == 0) ||	//	반대 대각선 검사  ↙

		(xy[y][x - 3] == 0 && xy[y][x - 2] == 1 && xy[y][x - 1] == 1 && xy[y][x] == 1 && xy[y][x + 1] == 0 && ((xy[y - 1][x + 1] == 1 && xy[y - 2][x + 2] == 1) || (xy[y + 1][x + 1] == 1 && xy[y + 2][x + 2] == 1)) && xy[y - 3][x + 3] == 0 && xy[y + 3][x + 3] == 0) ||		//  -< 검사

		(xy[y][x - 3] == 0 && xy[y][x - 2] == 1 && xy[y][x - 1] == 1 && xy[y][x] == 1 && xy[y][x + 1] == 0 && ((xy[y - 1][x - 1] == 1 && xy[y - 2][x - 2] == 1) || (xy[y + 1][x - 1] == 1 && xy[y + 2][x - 2] == 1)) && xy[y - 3][x - 3] == 0 && xy[y + 3][x - 3] == 0) ||		//  -> 검사

		(xy[y][x - 1] == 0 && xy[y][x] == 1 && xy[y][x + 1] == 1 && xy[y][x + 2] == 1 && xy[y][x + 3] == 0 && ((xy[y - 1][x - 1] == 1 && xy[y - 2][x - 2] == 1) || (xy[y + 1][x - 1] == 1 && xy[y + 2][x - 2] == 1)) && xy[y - 3][x - 3] == 0 && xy[y + 3][x - 3] == 0) ||		//  >- 검사

		(xy[y][x - 1] == 0 && xy[y][x] == 1 && xy[y][x + 1] == 1 && xy[y][x + 2] == 1 && xy[y][x + 3] == 0 && ((xy[y - 1][x + 1] == 1 && xy[y - 2][x + 2] == 1) || (xy[y + 1][x + 1] == 1 && xy[y + 2][x + 2] == 1)) && xy[y - 3][x + 3] == 0 && xy[y + 3][x + 3] == 0) ||		//  <- 검사

		(xy[y + 3][x] == 0 && xy[y + 2][x] == 1 && xy[y + 1][x] == 1 && xy[y][x] == 1 && xy[y - 1][x] == 0 && ((xy[y - 1][x - 1] == 1 && xy[y - 2][x - 2] == 1) || (xy[y - 1][x + 1] == 1 && xy[y - 2][x + 2] == 1)) && xy[y - 3][x - 3] == 0 && xy[y - 3][x + 3] == 0) ||		//  ↑ 윗 꺽세 뒤집은 것 검사 (키보드로 표시할 수가..없..)

		(xy[y + 3][x] == 0 && xy[y + 2][x] == 1 && xy[y + 1][x] == 1 && xy[y][x] == 1 && xy[y - 1][x] == 0 && ((xy[y + 1][x - 1] == 1 && xy[y + 2][x - 2] == 1) || (xy[y + 1][x + 1] == 1 && xy[y + 2][x + 2] == 1)) && xy[y + 3][x - 3] == 0 && xy[y + 3][x + 3] == 0) ||		//  ↑ 검사

		(xy[y - 3][x] == 0 && xy[y - 2][x] == 1 && xy[y - 1][x] == 1 && xy[y][x] == 1 && xy[y + 1][x] == 0 && ((xy[y + 1][x - 1] == 1 && xy[y + 2][x - 2] == 1) || (xy[y + 1][x + 1] == 1 && xy[y + 2][x + 2] == 1)) && xy[y + 3][x - 3] == 0 && xy[y + 3][x + 3] == 0) ||		//  ↓ 아랫 꺽세 뒤집은 것 검사 (키보드로 표시할 수가..없..)

		(xy[y - 3][x] == 0 && xy[y - 2][x] == 1 && xy[y - 1][x] == 1 && xy[y][x] == 1 && xy[y + 1][x] == 0 && ((xy[y - 1][x - 1] == 1 && xy[y - 2][x - 2] == 1) || (xy[y - 1][x + 1] == 1 && xy[y - 2][x + 2] == 1)) && xy[y - 3][x - 3] == 0 && xy[y - 3][x + 3] == 0) ||		//  ↓ 검사


		(xy[y - 3][x] == 0 && xy[y - 2][x] == 1 && xy[y - 1][x] == 1 && xy[y][x] == 1 && xy[y + 1][x] == 0 && ((xy[y][x + 1] == 1 && xy[y][x + 2] == 1) || (xy[y][x - 1] == 1 && xy[y][x - 2] == 1)) && xy[y][x + 3] == 0 && xy[y][x - 3] == 0) ||	//  가로 세로 ㅗ 검사
		(xy[y + 3][x] == 0 && xy[y + 2][x] == 1 && xy[y + 1][x] == 1 && xy[y][x] == 1 && xy[y - 1][x] == 0 && ((xy[y][x + 1] == 1 && xy[y][x + 2] == 1) || (xy[y][x - 1] == 1 && xy[y][x - 2] == 1)) && xy[y][x + 3] == 0 && xy[y][x - 3] == 0))	//  가로 세로 ㅜ 검사 
		c = 1;


	//	흑돌의 4*4 금수 규칙 지정	( 뒤에 != 1 을 쓴 이유는 4*5나 5*4까지 금수로 취급하는 것을 방지하기 위해서이다. )
	//  3*3 과 다른 이유: 가로, 세로, 대각선이 일렬로 나열된 것은 4*4에서 이미 8목으로 장목 금수에 속하기 때문에 쓸 필요가 없다.

	if ((xy[y - 2][x - 2] == 1 && xy[y - 1][x - 1] == 1 && xy[y][x] == 1 && xy[y - 1][x + 1] == 1 && xy[y - 2][x + 2] == 1 && xy[y - 3][x - 3] == 1 && xy[y - 3][x + 3] == 1 && xy[y - 3][x - 3] != 1 && xy[y - 3][x + 3] != 1) ||	//	대각선 V 검사

		(xy[y + 2][x - 2] == 1 && xy[y + 1][x - 1] == 1 && xy[y][x] == 1 && xy[y + 1][x + 1] == 1 && xy[y + 2][x + 2] == 1 && xy[y + 3][x - 3] == 1 && xy[y + 3][x + 3] == 1 && xy[y + 3][x - 3] != 1 && xy[y + 3][x + 3] != 1) ||	//	대각선Λ 검사

		(xy[y - 2][x - 2] == 1 && xy[y - 1][x - 1] == 1 && xy[y][x] == 1 && xy[y + 1][x - 1] == 1 && xy[y + 2][x - 2] == 1 && xy[y - 3][x - 3] == 1 && xy[y + 3][x - 3] == 1 && xy[y - 3][x - 3] != 1 && xy[y + 3][x - 3] != 1) ||	//	대각선 > 검사	

		(xy[y - 2][x + 2] == 1 && xy[y - 1][x + 1] == 1 && xy[y][x] == 1 && xy[y + 1][x + 1] == 1 && xy[y + 2][x + 2] == 1 && xy[y - 3][x + 3] == 1 && xy[y + 3][x + 3] == 1 && xy[y - 3][x + 3] != 1 && xy[y + 3][x + 3] != 1) ||	//  대각선 < 검사

		(xy[y][x - 4] != 1 && xy[y][x - 3] == 1 && xy[y][x - 2] == 1 && xy[y][x - 1] == 1 && xy[y][x] == 1 && xy[y][x + 1] != 1 &&
			((xy[y - 1][x + 1] == 1 && xy[y - 2][x + 2] == 1 && xy[y - 3][x + 3] == 1) || (xy[y + 1][x + 1] == 1 && xy[y + 2][x + 2] == 1 && xy[y + 3][x + 3] == 1)) && xy[y - 4][x + 4] != 1 && xy[y + 4][x + 4] != 1) ||		//  -< 검사

		(xy[y][x - 4] != 1 && xy[y][x - 3] == 1 && xy[y][x - 2] == 1 && xy[y][x - 1] == 1 && xy[y][x] == 1 && xy[y][x + 1] != 1 &&
			((xy[y - 1][x - 1] == 1 && xy[y - 2][x - 2] == 1 && xy[y - 3][x - 3] == 1) || (xy[y + 1][x - 1] == 1 && xy[y + 2][x - 2] == 1 && xy[y + 3][x - 3] == 1)) && xy[y - 4][x - 4] != 1 && xy[y + 4][x - 4] != 1) ||		//  -> 검사

		(xy[y][x - 1] != 1 && xy[y][x] == 1 && xy[y][x + 1] == 1 && xy[y][x + 2] == 1 && xy[y][x + 3] == 1 && xy[y][x + 4] != 1 &&
			((xy[y - 1][x - 1] == 1 && xy[y - 2][x - 2] == 1 && xy[y - 3][x - 3] == 1) || (xy[y + 1][x - 1] == 1 && xy[y + 2][x - 2] == 1 && xy[y + 3][x - 3] == 1)) && xy[y - 4][x - 4] != 1 && xy[y + 4][x - 4] != 1) ||		//  >- 검사

		(xy[y][x - 1] != 1 && xy[y][x] == 1 && xy[y][x + 1] == 1 && xy[y][x + 2] == 1 && xy[y][x + 3] == 1 && xy[y][x + 4] != 1 &&
			((xy[y - 1][x + 1] == 1 && xy[y - 2][x + 2] == 1 && xy[y - 3][x + 3] == 1) || (xy[y + 1][x + 1] == 1 && xy[y + 2][x + 2] == 1 && xy[y + 3][x + 3] == 1)) && xy[y - 4][x + 4] != 1 && xy[y + 4][x + 4] != 1) ||		//  <- 검사

		(xy[y + 4][x] != 1 && xy[y + 3][x] == 1 && xy[y + 2][x] == 1 && xy[y + 1][x] == 1 && xy[y][x] == 1 && xy[y - 1][x] != 1 &&
			((xy[y - 1][x - 1] == 1 && xy[y - 2][x - 2] == 1 && xy[y - 3][x - 3] == 1) || (xy[y - 1][x + 1] == 1 && xy[y - 2][x + 2] == 1 && xy[y - 3][x + 3] == 1)) && xy[y - 4][x - 4] != 1 && xy[y - 4][x + 4] != 1) ||		//  ↑ 윗 꺽세 뒤집은 것 검사 (키보드로 표시할 수가..없..)

		(xy[y + 4][x] != 1 && xy[y + 3][x] == 1 && xy[y + 2][x] == 1 && xy[y + 1][x] == 1 && xy[y][x] == 1 && xy[y - 1][x] != 1 &&
			((xy[y + 1][x - 1] == 1 && xy[y + 2][x - 2] == 1 && xy[y + 3][x - 3] == 1) || (xy[y + 1][x + 1] == 1 && xy[y + 2][x + 2] == 1 && xy[y + 3][x + 3] == 1)) && xy[y + 4][x - 4] != 1 && xy[y + 4][x + 4] != 1) ||		//  ↑ 검사

		(xy[y - 4][x] != 1 && xy[y - 3][x] == 1 && xy[y - 2][x] == 1 && xy[y - 1][x] == 1 && xy[y][x] == 1 && xy[y + 1][x] != 1 &&
			((xy[y + 1][x - 1] == 1 && xy[y + 2][x - 2] == 1 && xy[y + 3][x - 3] == 1) || (xy[y + 1][x + 1] == 1 && xy[y + 2][x + 2] == 1 && xy[y + 3][x + 3] == 1)) && xy[y + 3][x - 3] != 1 && xy[y + 3][x + 3] != 1) ||		//  ↓ 아랫 꺽세 뒤집은 것 검사 (키보드로 표시할 수가..없..)

		(xy[y - 4][x] != 1 && xy[y - 3][x] == 1 && xy[y - 2][x] == 1 && xy[y - 1][x] == 1 && xy[y][x] == 1 && xy[y + 1][x] != 1 &&
			((xy[y - 1][x - 1] == 1 && xy[y - 2][x - 2] == 1 && xy[y - 3][x - 3] == 1) || (xy[y - 1][x + 1] == 1 && xy[y - 2][x + 2] == 1 && xy[y - 3][x + 3] == 1)) && xy[y - 4][x - 4] != 1 && xy[y - 4][x + 4] != 1) ||		//  ↓ 검사

		(xy[y - 4][x] != 1 && xy[y - 3][x] == 1 && xy[y - 2][x] == 1 && xy[y - 1][x] == 1 && xy[y][x] == 1 && ((xy[y][x + 1] == 1 && xy[y][x + 2] == 1 && xy[y][x + 3] == 1) || (xy[y][x - 1] == 1 && xy[y][x - 2] == 1 && xy[y][x - 3] == 1)) && xy[y][x + 4] != 1 && xy[y][x - 4] != 1) ||//  가로 세로 ㅗ 검사	
		(xy[y + 4][x] != 1 && xy[y + 3][x] == 1 && xy[y + 2][x] == 1 && xy[y + 1][x] == 1 && xy[y][x] == 1 && ((xy[y][x + 1] == 1 && xy[y][x + 2] == 1 && xy[y][x + 3] == 1) || (xy[y][x - 1] == 1 && xy[y][x - 2] == 1 && xy[y][x - 3] == 1)) && xy[y][x + 4] != 1 && xy[y][x - 4] != 1))	//  가로 세로 ㅜ 검사 
		c = 2;

	if (jangmok(c) == 3)
		return 3;	//	장목이면 3리턴
	else
		return c;	//	아니면 C리턴
}
int jangmok(int c)
{
	int count = 0;	// 연속된 돌 카운트

	for (int j = 0; j < 19; j++) {		//	가로 장목 검사
		for (int k = 0; k < 19; k++) {
			if (xy[j][k] == 1)
				count++;
			else
				count = 0;
			if (count == 6) return 3;	//	장목이면 3을 리턴
		}
		count = 0;	// 가로 한 줄 끝내고 다시 카운트
	}
	for (int j = 0; j < 19; j++) {		//	세로 장목 검사
		for (int k = 0; k < 19; k++) {
			if (xy[k][j] == 1)
				count++;
			else
				count = 0;
			if (count == 6) return 3;
		}
		count = 0;	// 세로 한 줄 끝내고 다시 카운트
	}
	for (int j = -5; j <= 5; j++) {		//	대각선 장목 검사
		if (x + j < 0)continue;
		if (y + j < 0)continue;
		if (xy[y + j][x + j] == 1)
		{
			count++;
			if (count == 6) return 3;
		}
		else
			count = 0;	// 연속되지 않을 때, 0으로 초기화
	}
	for (int j = -5; j <= 5; j++) {		//	반대 대각선 장목 검사
		if (x - j < 0)continue;
		if (y + j < 0)continue;
		if (xy[y + j][x - j] == 1)
		{
			count++;
			if (count == 6) return 3;
		}
		else
			count = 0;	// 연속되지 않을 때, 0으로 초기화
	}

	return c;			// 장목이 아니면 c를 리턴
}

int omok_check(int stone)	// 오목이 되면 0, 아니면 1을 리턴
{
	int j, count = 0;		// count는 연속된 돌의 갯수

		// 백돌은 3*3, 4*4, 장목이 가능하므로 금수 규칙을 적용하지 않음.

	for (j = -4; j <= 4; j++) {			// 좌우 오목 검사
		if (x + j < 0) continue;
		if (xy[y][x + j] == stone) {
			count++;			// 값 일치시 1증가
			if (count == 5)return 0;	// 오목이 완성되면 0 리턴
		}
		else count = 0;		// 일치하지 않을 시, 0으로 초기화
	}

	for (j = -4; j <= 4; j++) {			// 상하 오목 검사
		if (y + j < 0)continue;
		if (xy[y + j][x] == stone) {
			count++;
			if (count == 5)return 0;
		}
		else count = 0;
	}


	for (j = -4; j <= 4; j++) {		// 대각선 오목 검사
		if (x + j < 0)continue;
		if (y + j < 0)continue;
		if (xy[y + j][x + j] == stone) {
			count++;
			if (count == 5)return 0;
		}
		else count = 0;
	}
	count = 0;
	for (j = -4; j <= 4; j++) {		// 반대 대각선 오목 검사
		if (x - j < 0)continue;
		if (y + j < 0)continue;
		if (xy[y + j][x - j] == stone) {
			count++;

			if (count == 5)return 0;
		}
		else count = 0;
	}

	return 1;				// 오목이 아니면 1 리턴
}

void gotoxy(int x, int y)	// 커서 이동
{
	COORD Pos = { x,y };
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Pos);
}

void victory(void)		// 승리자 출력
{
	gotoxy(43, 15);
	if (stone == 1) {
		black_score++;
		printf("○ [%s]님의 승리", black_player);
	}
	else {
		white_score++;
		printf("● [%s]님의 승리", white_player);
	}
}

원본 소스 출처: 제대로 배우는 C언어 프로그래밍 ( 저자: 한성현)

반응형