C언어로 된 작은 프로그램(백개먼)의 소스코드를 찾는 중입니다.
********************************************* *** ************************/
/* ALEX_LEE Gomoku C 언어 애플릿*/
/ * o(∩_∩)o... C 언어를 복습하는 데 사용할 수 있는 작은 프로그램 */
/* 내 블로그: hi.baidu.com/alexlee321 */
/********************************************* *** ******************/
/******************** **** *************************************/
# include
#include
#include
#include #에는 /****************************** ****** **********************/ /* 기호 상수 정의*/ /*체스판을 그릴 위치 정의 필수 탭 문자*/ #define CROSSRU 0xbf /*오른쪽 위 모서리 점*/ #define CROSSLU 0xda /*왼쪽 위 모서리 점* / #define CROSSLD 0xc0 /*왼쪽 아래 모서리 점*/ #define CROSSRD 0xd9 /*오른쪽 아래 모서리 점*/ #define CROSSL 0xc3 /*왼쪽*/ #define CROSSR 0xb4 /*오른쪽*/ #define CROSSU 0xc2 /*top*/ #define CROSSD 0xc1 / *bottom*/ #define CROSS 0xc5 /*교차점*/ /*화면에서 체스판의 왼쪽 상단 모서리 위치를 정의합니다*/ #define MAPXOFT 5 #define MAPYOFT 2 /*플레이어 1의 작동 키 코드 정의*/ #define PLAY1UP 0x1157/* 위로 이동--'W'*/ #define PLAY1DOWN 0x1f53/*아래로 이동--'S'*/ #define PLAY1LEFT 0x1e41/*왼쪽으로 이동--'A '*/ #define PLAY1RIGHT 0x2044/*오른쪽으로 이동--'D'*/ #define PLAY1DO 0x3920/*이동--스페이스 바*/ /*2번 플레이어의 조작 키 코드를 정의합니다 */ #define PLAY2UP 0x4800/*위로 이동--화살표 키를 위로 이동*/ #define PLAY2DOWN 0x5000/ *아래로 이동- -아래 방향 키*/ #define PLAY2LEFT 0x4b00/*왼쪽으로 이동--방향 키 왼쪽*/ #define PLAY2RIGHT 0x4d00/*오른쪽으로 이동--방향 키 오른쪽*/ #define PLAY2DO 0x1c0d/*Place--Enter 키*/ /*게임 도중에 종료하려면 Esc 키를 누르세요*/ #define ESCAPE 0x011b /*체스판의 교차점 상태, 즉 해당 지점에 체스 말이 있는지 정의합니다*/ /* 체스 말이 있으면 어떤 플레이어인지도 나타낼 수 있어야 합니다. 체스 말*/ #define CHESSNULL 0 //체스 말이 없음 #define CHESS1 'O'//1번 플레이어의 체스 말 #define CHESS2 ' X'// 2번 플레이어의 플레이어 /*핵심 카테고리 정의*/ #Define Keyexit 0/*종료 키*/ #Define KeyFallChess 1/*드롭 키*/ #define KEYMOVECURSOR 2/*커서 이동 키* / #define KEYINVALID 3/*잘못된 키*/ / *기호 상수 정의: true, false---true는 1, false는 0 */ #define TRUE 1 #define FALSE 0 / ************************ *************************** ********/ /* 데이터 구조 정의*/ /*체스판 교차 좌표의 데이터 구조*/ struct point { int x,y; }; /******************** ******************* **************************/ /*사용자 정의 함수 프로토타입 설명*/ void Init(void); int GetKey(void); int CheckKey(int press ); int ChangeOrder(void); int ChessGo(int Order,struct point Cursor); void DoError(void); void DoOK(void); void DoWin(int Order); void MoveCursor(int Order,int press); void DrawCross( int x,int y); void DrawMap(void); int JudgeWin(int Order,struct point Cursor); int JudgeWinLine(int Order ,struct point Cursor,int 방향); void ShowOrderMsg(int 주문); 무효 종료 게임(무효); /************************************* ***** *********************/ /**************** ********* ***************************************** */ /* 전역 변수 정의*/ int gPlayOrder; /*현재 체스 플레이어를 나타냅니다.*/ struct point gCursor; 체스판에 있는 커서의 위치*/ char gChessBoard[19][19];/*체스판에 있는 각 지점의 상태를 기록하는 데 사용됩니다*/ /*** ***************** ********************************* ***/ /*** *********************************** **************** *****/ /*주요 기능*/ void main() { int press; p> int bOutWhile=FALSE;/*루프 종료 플래그*/ Init();/*이미지, 데이터 초기화 */ while(1) p> { press=GetKey();/*사용자의 키 값 가져오기*/ switch(CheckKey(press))/*키 종류를 판단하세요*/ { /*종료 키입니다*/ case KEYEXIT: clrscr();/*화면 지우기*/ p> bOutWhile = TRUE; break; /*드롭 키입니다 */ 케이스 KEYFALLCHESS: if (ChessGo(gPlayOrder,gCursor)==FALSE)/*체스 이동*/ DoError();/* 배치 오류*/ else { DoOK();/*이동이 정확합니다*/ /* 현재 플레이어 승리*/ if(JudgeWin(gPlayOrder,gCursor) ==TRUE) { DoWin(gPlayOrder); bOutWhile = TRUE;/*종료 루프 플래그를 true로 설정*/ } /*그렇지 않으면*/ else /*플레이어 교환*/ ChangeOrder(); } break; /*커서 이동 키입니다 */ case KEYMOVECURSOR: MoveCursor( gPlayOrder,press); break; /* is None 유효한 키*/ 케이스 KEYINVALID: break; } if(bOutWhile==TRUE) break; } /*게임 종료*/ EndGame(); } /************************************************ **********/ /*인터페이스 초기화, 데이터 초기화*/ void Init(void) { int i,j; char *Msg[]= { "Player1 키:", " UP----w", " DOWN--s", " LEFT--a", " RIGHT-d", " DO--space", "", "Player2 키:", " UP-- --위", " DOWN--아래", " LEFT--왼쪽", " 오른쪽-오른쪽", " DO--ENTER", "", "게임 종료:", "ESC", NULL, }; /*첫 번째 무버는 플레이어 1입니다*/ gPlayOrder = CHESS1; / *체스판 데이터가 지워집니다. 즉, 체스판의 각 지점 시작 부분에 체스 말이 없습니다*/ for(i=0;i<19;i++) for(j=0 ;j<19;j++) gChessBoard[i][j]=CHESSNULL; /*초기 커서 위치*/ gCursor.x=gCursor .y=0; /*체스판 그리기*/ textmode(C40); DrawMap(); /* 조작 키 설명 표시*/ i=0; textcolor(BROWN); while(Msg[i] !=NULL) { gotoxy(25,3+i); cputs(Msg[i]); i++; } /*체스 플레이어의 현재 행 표시*/ ShowOrderMsg(gPlayOrder); /*이동 체스판의 왼쪽 상단에 커서를 놓습니다*/ gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT); } / *체스판 그리기*/ void DrawMap(void) { int i,j; clrscr(); for(i=0;i <19;i++) for(j=0;j<19;j++) DrawCross(i,j) ; } /*체스판에 교차점 그리기*/ void DrawCross(int x,int y) { gotoxy(x+MAPXOFT,y+MAPYOFT); /*교차점은 1번 플레이어의 체스 말입니다*/ p> if(gChessBoard[x][y]==CHESS1) { textcolor(LIGHTBLUE); putch(CHESS1 ); return; } /*교차점은 두 번째 플레이어의 체스 말입니다*/ if(gChessBoard [x] [y]==CHESS2) { textcolor(LIGHTBLUE); putch(CHESS2); return ; } textcolor(GREEN); /*왼쪽 위 모서리 교차점*/ if(x== 0&&y==0) { putch(CROSSLU); return; } / *왼쪽 하단 교차로 */ if(x==0&&y==18) { putch(CROSSLD); return; p> } /*오른쪽 상단 교차로*/ if(x==18&&y==0) { putch(CROSSRU); return; } /*오른쪽 하단 교차로*/ if(x ==18&&y==18) { putch(CROSSRD); return; } /*왼쪽 경계 교차점*/ if(x==0) { putch(CROSSL); return; } /*오른쪽 경계 교차점*/ if(x==18) { putch(CROSSR); return; } /*상위 경계 교차점*/ if( y==0) { putch(CROSSU); return; } / *하위 경계 교차점*/ if(y==18) { putch(CROSSD); return ; } /*보드 중앙의 교차점*/ patch(CROSS); } p> /*플레이어 교환*/ int ChangeOrder(void) { if(gPlayOrder==CHESS1) gPlayOrder=CHESS2; else gPlayOrder=CHESS1; return(gPlayOrder); } /*키 값 가져오기*/ int GetKey(void) { char lowbyte; int press; 동안 (bioskey(1) == 0) ;/*사용자가 키를 누르지 않으면 빈 루프*/ press=bioskey(0); lowbyte =press&0xff; press=press&0xff00 + toupper(lowbyte); return(press); } /*잘못된 이동 처리 중*/ void DoError(void) { sound(1200); Delay(50) ; nosound(); } /*Win 체스 처리*/ void DoWin(int Order) { 사운드(1500);지연(100); 사운드(0) 지연(50); 사운드(800) ; 지연(100 ); 사운드(0); 지연(50); 사운드(1500);지연(100); 사운드(0 ); 지연(50); 사운드(800); 지연(100); 지연(50); nosound( ); textcolor(RED+BLINK); gotoxy(25,20); if(Order==CHESS1) cputs("PLAYER1 WIN!"); else cputs("PLAYER2 WIN!"); gotoxy(25,21); cputs(" \\<^+^>/"); getch(); } /*이동 chess*/ int ChessGo(int Order,struct point Cursor) { /*교차점에 체스 말이 있는지 판단*/ p> if(gChessBoard [Cursor.x][Cursor.y]==CHESSNULL) { /*체스 말이 없으면 체스 말을 놓을 수 있습니다. 조각*/ gotoxy(Cursor .x+MAPXOFT,Cursor.y+MAPYOFT); textcolor(LIGHTBLUE); putch(Order); gotoxy(Cursor.x+MAPXOFT ,Cursor.y+MAPYOFT); gChessBoard[Cursor.x][Cursor.y]=Order; return TRUE; } else FALSE를 반환; } /*현재 플레이어가 조각을 배치한 후 승리합니다*/ int JudgeWin(int Order,struct point Cursor) { int i; for(i=0;i<4;i++) /*지정된 방향으로 5개의 연속 체스 말이 있는지 확인*/ if(JudgeWinLine(Order,Cursor,i)) return TRUE ; FALSE를 반환; } /*지정된 방향으로 5개의 연속 체스 말이 있는지 확인*/ p> int JudgeWinLine(int 순서, 구조체 포인트 커서, int 방향) { int i; 구조체 포인트 pos,dpos; const int testnum = 5; int count; 스위치(방향) { 케이스 0 :/*가로에서 방향*/ pos.x=Cursor.x-(testnum-1); pos.y=Cursor.y; dpos.x= 1; dpos.y=0; break; 사례 1:/*세로 방향*/ pos .x=Cursor.x; pos.y=Cursor.y-(testnum-1); dpos.x=0; dpos. y=1; break; 사례 2:/*왼쪽 아래에서 오른쪽 위로 대각선 방향으로*/ pos.x=Cursor . x-(테스트 번호-1); pos.y=Cursor.y+(테스트 번호-1); dpos.x=1; dpos . y=-1; break; 사례 3:/*왼쪽 위에서 오른쪽 아래로 대각선 방향*/ pos.x=Cursor .x-(테스트 번호-1); pos.y=Cursor.y-(테스트 번호-1); dpos.x=1; dpos .y=1; break; } count=0; for(i=0;i { if(pos.x>=0&&pos.x<=18&&pos.y>=0&&pos.y<=18) { if(gChessBoard[pos.x][pos.y]==Order) { count++; if(count>=testnum) return TRUE; } else count=0; } pos.x+=dpos.x; pos.y+=dpos.y; } FALSE 반환; } /*커서 이동*/ void MoveCursor(int Order,int press) p> { 스위치(누르기) { case PLAY1UP: if(Order==CHESS1&&gCursor.y >0) gCursor.y--; break; case PLAY1DOWN: if(Order==CHESS1&&gCursor.y <18) gCursor.y++; break; case PLAY1LEFT: if(Order==CHESS1&&gCursor.x>0 ) gCursor.x--; break; case PLAY1RIGHT: if(Order==CHESS1&&gCursor.x<18 ) gCursor.x++; break; case PLAY2UP: if(Order==CHESS2&&gCursor.y>0) gCursor.y--; break; case PLAY2DOWN: if(Order==CHESS2&&gCursor.y<18) gCursor.y++; break; case PLAY2LEFT: if(Order==CHESS2&&gCursor.x>0) gCursor.x--; break; case PLAY2RIGHT: if(Order==CHESS2&&gCursor.x<18) gCursor.x++; break; } gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT); } /*게임 종료 처리*/ void EndGame(void) { textmode(C80) ; } /*현재 플레이어 표시*/ void ShowOrderMsg(int Order) { gotoxy(6,MAPYOFT+20); textcolor(LIGHTRED); if(Order==CHESS1) cputs("Player1 go ! "); else cputs("Player2 go!"); gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT); } /*올바른 이동 처리* / void DoOK(void) { sound(500); Delay(70); 소리(600); 지연(50); 소리(1000); 지연(100); nosound(); } /*사용자의 키 유형 확인*/ int CheckKey(int press) { if(press==ESCAPE) return KEYEXIT;/*는 종료 키입니다*/ else if ( ( press==PLAY1DO && gPlayOrder==CHESS1) || ( press==PLAY2DO && gPlayOrder==CHESS2) ) return KEYFALLCHESS;/*드롭 키입니다*/ else if ( press==PLAY1UP || press==PLAY1DOWN || p> press==PLAY1LEFT || press==PLAY1RIGHT || press==PLAY2UP || press==PLAY2LEFT || == PLAY2RIGHT ) return KEYMOVECURSOR;/*커서 이동 키입니다*/ else return KEYINVALID;/ *키가 유효하지 않습니다* / }