컴공과컴맹효묘의블로그

[c언어 오목] 세상 간단한 오목 만들기 본문

개발/짧

[c언어 오목] 세상 간단한 오목 만들기

효묘 2020. 5. 10. 21:20
반응형

 

저번에 gotoxy함수를 설명한 포스팅과 c언어로 할만한 프로젝트를 작성했었습니다. 그 예시를 직접 포스팅하면 좋을 것 같아서 포스팅해봅니다.

 

개인적으로 가장 만만하다고 생각하는 것은 오목입니다. 물론 33규칙 알고리즘을 적용하면 복잡해지지만, 33규칙을 빼고 구현하면 굉장히 쉽습니다. 이 글에서 나오는 오목은 최대한 단순화시켜서 오목의 필수적인 요소들만 가져와서 간단하게 오목을 둘 수 있는 게임을 만들어봤습니다.

 

헤더파일

  • stdio.h // 기본 입출력
  • windows.h // 좌표 설정
  • conio.h // 입력
  • string.h // 입력 문자열 처리

전처리

  • MAX_N 19 // 바둑(오목)판의 크기
  • DRAW_BLACK printf("○") // 검은 돌 출력 (cmd에서는 색반전이기 때문)
  • DRAW_WHITE printf("●") // 하얀 돌 출력
  • BLACK 1 // 검은 돌 정의
  • WHITE 2 // 하얀 돌 정의

 

drawInit()함수

초기 19x19 오목판을 만들어주는 함수입니다.

void drawInit() {
	gotoxy(0, 0);
	for (int i = 0; i < MAX_N; i++) {
		for (int j = 0; j < MAX_N; j++) {
			gotoxy(j, i);
			if (i == 0) {
				if (j == 0)
					printf("┌");
				else if (j == MAX_N - 1)
					printf("┐");
				else
					printf("┬");
			}
			else if (j == 0) {
				if (i == MAX_N - 1)
					printf("└");
				else
					printf("├");
			}
			else if (j == MAX_N - 1) {
				if (i == MAX_N - 1)
					printf("┘");
				else
					printf("┤");
			}
			else if (i == MAX_N - 1) {
				printf("┴");
			}
			else
				printf("┼");
		}
		printf("\n");
	}
	for (int i = 0; i < MAX_N; i++) {
		gotoxy(MAX_N, i);
		printf("%d", i + 1);
		gotoxy(i, MAX_N);
		printf("%c", i + 'A');
	}
	gotoInput();
	printf("fin.");
}

 

drawStone(int y, int x, int stone)함수

stone의 값에 따라 주어진 좌표에 돌을 둡니다.

돌을 둘 수 없는 상황이거나 stone이 흑, 백이 아닌 잘못된 값이면 0을 리턴, 성공적으로 돌을 두면 1을 리턴한다.

int drawStone(int y, int x, int stone) { // stone이 1이면 흑, 2면 백
	if (board[y][x] || x<0 || x>=MAX_N || y<0 || y>=MAX_N)
		return 0;
	gotoxy(x, y);
	if (stone == BLACK) {
		DRAW_BLACK; 
		board[y][x] = BLACK;
	}
	else if (stone == WHITE) {
		DRAW_WHITE;
		board[y][x] = WHITE;
	}
	else
		return 0;
	return 1;
}

 

inputCode(int *x, int*y) 함수

좌표를 문자열로 받고 좌표를 넘겨주는 함수. 잘못된 문자열(좌표)가 입력되면 x와 y는 -1로 준다.

void inputCode(int* y, int* x) {
	gotoInput();
	printf("Input Coordinate (A19): ");
	char s[10];
	gets_s(s, sizeof(s));
	*x = s[0] - 'A';
	if (strlen(s) > 3)
		return ;
	if (strlen(s) == 3)
		*y = (s[1] - '0') * 10 + s[2] - '0' - 1;
	else if (strlen(s) == 2)
		*y = s[1] - '0' - 1;
	else
		*y = *x = -1;
	gotoInput(); printf("Input Coordinate (A19): \t\t\t");
	return;
}

 

checkFinish(int t) 함수

매개변수가 좌표인데, x와 y로 받는게 아니라 t로 받는다. t를 x와 y로 변환시켜 계산한다.

0,0 부터 MAX_N, MAX_N 미만까지 모든 좌표를 이동하며 게임이 끝났는지 확인한다.

게임이 끝났으면,(5개의 돌이 연속으로 한 줄) 해당 color를 리턴한다. 아니면 0을 리턴.

int checkFinish(int t) {
	if (t == MAX_N * MAX_N)
		return 0;
	int x = t % MAX_N;
	int y = t / MAX_N;
	int color = board[y][x];
	int dir[3] = { 0 };
	for (int i = 0; i < 5 && color != 0; i++) {
		if (x + i < MAX_N && color == board[y][x + i])
			dir[0]++;
		if (y + i < MAX_N && color == board[y + i][x])
			dir[1]++;
		if (x + i < MAX_N && y + i < MAX_N && color == board[y + i][x + i])
			dir[2]++;
	}
	for (int i = 0; i < 3; i++)
		if (dir[i] == 5)
			return color;
	return checkFinish(t + 1);
}

 

 gotoInput() 함수

입력받을 좌표로 이동한다.

void gotoInput() {
	gotoxy(21, 20);
}

 

gotoxy()함수

이전 글 참고.

 

c언어로 게임을, c언어 좌표계 gotoxy()함수

C언어 콘솔창으로 테트리스, 오목을 만들 수 있다. c언어를 처음 배우는 분들이 c언어 콘솔창으로 게임을 만들고 싶을 때가 있을겁니다. 테트리스, 스네이크게임, 오목, 바둑 등 여러 게임을 만들때는 보통 좌표계..

hyomyo.tistory.com

 

 

전체 코드

#include<stdio.h>
#include<Windows.h>
#include<conio.h>
#include<string.h>

#define MAX_N 19
#define DRAW_BLACK printf("○")
#define DRAW_WHITE printf("●")
#define WHITE 2
#define BLACK 1

void gotoxy(int x, int y);

int board[MAX_N][MAX_N] = { 0 };

void drawInit();
int drawStone(int y, int x, int stone);
void inputCode(int *y, int *x);
int checkFinish(int t);
void gotoInput();

int main() {
	CONSOLE_CURSOR_INFO cursorInfo = { 0, };
	cursorInfo.bVisible = 0;
	cursorInfo.dwSize = 1;
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);

	drawInit();
	int x, y, i = 1;
	for (;;) {
		inputCode(&y, &x);
		i += drawStone(y, x, (i) % 2 + 1);
		if (int c = checkFinish(0)) {
			gotoInput();
			printf("GAME OVER.. ");
			if (c == WHITE)
				printf("WHITE "), DRAW_WHITE;
			else if (c == BLACK)
				printf("BLACK "), DRAW_BLACK;
			printf(" WIN!!! ");
			break;
		}
	}

	_getch();
	return 0;
}

int checkFinish(int t) {
	if (t == MAX_N * MAX_N)
		return 0;
	int x = t % MAX_N;
	int y = t / MAX_N;
	int color = board[y][x];
	int dir[3] = { 0 };
	for (int i = 0; i < 5 && color != 0; i++) {
		if (x + i < MAX_N && color == board[y][x + i])
			dir[0]++;
		if (y + i < MAX_N && color == board[y + i][x])
			dir[1]++;
		if (x + i < MAX_N && y + i < MAX_N && color == board[y + i][x + i])
			dir[2]++;
	}
	for (int i = 0; i < 3; i++)
		if (dir[i] == 5)
			return color;
	return checkFinish(t + 1);
}

void inputCode(int* y, int* x) {
	gotoInput();
	printf("Input Coordinate (A19): ");
	char s[10];
	gets_s(s, sizeof(s));
	*x = s[0] - 'A';
	if (strlen(s) > 3)
		return ;
	if (strlen(s) == 3)
		*y = (s[1] - '0') * 10 + s[2] - '0' - 1;
	else if (strlen(s) == 2)
		*y = s[1] - '0' - 1;
	else
		*y = *x = -1;
	gotoInput(); printf("Input Coordinate (A19): \t\t\t");
	return;
}

int drawStone(int y, int x, int stone) { // stone이 1이면 흑, 2면 백
	if (board[y][x] || x<0 || x>=MAX_N || y<0 || y>=MAX_N)
		return 0;
	gotoxy(x, y);
	if (stone == BLACK) {
		DRAW_BLACK; 
		board[y][x] = BLACK;
	}
	else if (stone == WHITE) {
		DRAW_WHITE;
		board[y][x] = WHITE;
	}
	else
		return 0;
	return 1;
}

void drawInit() {
	gotoxy(0, 0);
	for (int i = 0; i < MAX_N; i++) {
		for (int j = 0; j < MAX_N; j++) {
			gotoxy(j, i);
			if (i == 0) {
				if (j == 0)
					printf("┌");
				else if (j == MAX_N - 1)
					printf("┐");
				else
					printf("┬");
			}
			else if (j == 0) {
				if (i == MAX_N - 1)
					printf("└");
				else
					printf("├");
			}
			else if (j == MAX_N - 1) {
				if (i == MAX_N - 1)
					printf("┘");
				else
					printf("┤");
			}
			else if (i == MAX_N - 1) {
				printf("┴");
			}
			else
				printf("┼");
		}
		printf("\n");
	}
	for (int i = 0; i < MAX_N; i++) {
		gotoxy(MAX_N, i);
		printf("%d", i + 1);
		gotoxy(i, MAX_N);
		printf("%c", i + 'A');
	}
	gotoInput();
	printf("fin.");
}

void gotoxy(int x, int y) {
	COORD pos = { x * 2,y };
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

void gotoInput() {
	gotoxy(21, 20);
}

 

 

반응형
Comments