C語(yǔ)言實(shí)現(xiàn)五子棋游戲
更新時(shí)間:2020年02月05日 14:58:01 作者:lishuangqiao
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
本文實(shí)例為大家分享了C語(yǔ)言實(shí)現(xiàn)五子棋的具體代碼,供大家參考,具體內(nèi)容如下
#include <stdio.h> #include <bios.h> #include <ctype.h> #include <conio.h> #include <dos.h> #define CROSSRU 0xbf /*右上角點(diǎn)*/ #define CROSSLU 0xda /*左上角點(diǎn)*/ #define CROSSLD 0xc0 /*左下角點(diǎn)*/ #define CROSSRD 0xd9 /*右下角點(diǎn)*/ #define CROSSL 0xc3 /*左邊*/ #define CROSSR 0xb4 /*右邊*/ #define CROSSU 0xc2 /*上邊*/ #define CROSSD 0xc1 /*下邊*/ #define CROSS 0xc5 /*十字交叉點(diǎn)*/ /*定義棋盤左上角點(diǎn)在屏幕上的位置*/ #define MAPXOFT 5 #define MAPYOFT 2 /*定義1號(hào)玩家的操作鍵鍵碼*/ #define PLAY1UP 0x1157/*上移--'W'*/ #define PLAY1DOWN 0x1f53/*下移--'S'*/ #define PLAY1LEFT 0x1e41/*左移--'A'*/ #define PLAY1RIGHT 0x2044/*右移--'D'*/ #define PLAY1DO 0x3920/*落子--空格鍵*/ /*定義2號(hào)玩家的操作鍵鍵碼*/ #define PLAY2UP 0x4800/*上移--方向鍵up*/ #define PLAY2DOWN 0x5000/*下移--方向鍵down*/ #define PLAY2LEFT 0x4b00/*左移--方向鍵left*/ #define PLAY2RIGHT 0x4d00/*右移--方向鍵right*/ #define PLAY2DO 0x1c0d/*落子--回車鍵Enter*/ /*若想在游戲中途退出, 可按 Esc 鍵*/ #define ESCAPE 0x011b /*定義棋盤上交叉點(diǎn)的狀態(tài), 即該點(diǎn)有無(wú)棋子 */ /*若有棋子, 還應(yīng)能指出是哪個(gè)玩家的棋子 */ #define CHESSNULL 0 /*沒有棋子*/ #define CHESS1 'O'/*一號(hào)玩家的棋子*/ #define CHESS2 'X'/*二號(hào)玩家的棋子*/ /*定義按鍵類別*/ #define KEYEXIT 0/*退出鍵*/ #define KEYFALLCHESS 1/*落子鍵*/ #define KEYMOVECURSOR 2/*光標(biāo)移動(dòng)鍵*/ #define KEYINVALID 3/*無(wú)效鍵*/ /*定義符號(hào)常量: 真, 假 --- 真為1, 假為0 */ #define TRUE 1 #define FALSE 0 /**********************************************************/ /* 定義數(shù)據(jù)結(jié)構(gòu) */ /*棋盤交叉點(diǎn)坐標(biāo)的數(shù)據(jù)結(jié)構(gòu)*/ struct point { int x,y; }; /**********************************************************/ /*自定義函數(shù)原型說(shuō)明 */ 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 direction); void ShowOrderMsg(int Order); void EndGame(void); /**********************************************************/ /**********************************************************/ /* 定義全局變量 */ int gPlayOrder; /*指示當(dāng)前行棋方 */ struct point gCursor; /*光標(biāo)在棋盤上的位置 */ char gChessBoard[19][19];/*用于記錄棋盤上各點(diǎn)的狀態(tài)*/ /**********************************************************/ /**********************************************************/ /*主函數(shù)*/ void main() { int press; int bOutWhile=FALSE;/*退出循環(huán)標(biāo)志*/ printf("Welcome [url]www.schoolhacker.com[/url]"); Init();/*初始化圖象,數(shù)據(jù)*/ while(1) { press=GetKey();/*獲取用戶的按鍵值*/ switch(CheckKey(press))/*判斷按鍵類別*/ { /*是退出鍵*/ case KEYEXIT: clrscr();/*清屏*/ bOutWhile = TRUE; break; /*是落子鍵*/ case KEYFALLCHESS: if(ChessGo(gPlayOrder,gCursor)==FALSE)/*走棋*/ DoError();/*落子錯(cuò)誤*/ else { DoOK();/*落子正確*/ /*如果當(dāng)前行棋方贏棋*/ if(JudgeWin(gPlayOrder,gCursor)==TRUE) { DoWin(gPlayOrder); bOutWhile = TRUE;/*退出循環(huán)標(biāo)志置為真*/ } /*否則*/ else /*交換行棋方*/ ChangeOrder(); ShowOrderMsg(gPlayOrder); } break; /*是光標(biāo)移動(dòng)鍵*/ case KEYMOVECURSOR: MoveCursor(gPlayOrder,press); break; /*是無(wú)效鍵*/ case KEYINVALID: break; } if(bOutWhile==TRUE) break; } /*游戲結(jié)束*/ EndGame(); } /**********************************************************/ /*界面初始化,數(shù)據(jù)初始化*/ void Init(void) { int i,j; char *Msg[]= { "Player1 key:", " UP----w", " DOWN--s", " LEFT--a", " RIGHT-d", " DO----space", "", "Player2 key:", " UP----up", " DOWN--down", " LEFT--left", " RIGHT-right", " DO----ENTER", "", "exit game:", " ESC", NULL, }; /* 先手方為1號(hào)玩家 */ gPlayOrder = CHESS1; /* 棋盤數(shù)據(jù)清零, 即棋盤上各點(diǎn)開始的時(shí)候都沒有棋子 */ for(i=0;i<19;i++) for(j=0;j<19;j++) gChessBoard[i][j]=CHESSNULL; /*光標(biāo)初始位置*/ gCursor.x=gCursor.y=0; /*畫棋盤*/ textmode(C40); DrawMap(); /*顯示操作鍵說(shuō)明*/ i=0; textcolor(BROWN); while(Msg[i]!=NULL) { gotoxy(25,3+i); cputs(Msg[i]); i++; } /*顯示當(dāng)前行棋方*/ ShowOrderMsg(gPlayOrder); /*光標(biāo)移至棋盤的左上角點(diǎn)處*/ 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); } /*畫棋盤上的交叉點(diǎn)*/ void DrawCross(int x,int y) { gotoxy(x+MAPXOFT,y+MAPYOFT); /*交叉點(diǎn)上是一號(hào)玩家的棋子*/ if(gChessBoard[x][y]==CHESS1) { textcolor(LIGHTBLUE); putch(CHESS1); return; } /*交叉點(diǎn)上是二號(hào)玩家的棋子*/ if(gChessBoard[x][y]==CHESS2) { textcolor(LIGHTBLUE); putch(CHESS2); return; } textcolor(GREEN); /*左上角交叉點(diǎn)*/ if(x==0&&y==0) { putch(CROSSLU); return; } /*左下角交叉點(diǎn)*/ if(x==0&&y==18) { putch(CROSSLD); return; } /*右上角交叉點(diǎn)*/ if(x==18&&y==0) { putch(CROSSRU); return; } /*右下角交叉點(diǎn)*/ if(x==18&&y==18) { putch(CROSSRD); return; } /*左邊界交叉點(diǎn)*/ if(x==0) { putch(CROSSL); return; } /*右邊界交叉點(diǎn)*/ if(x==18) { putch(CROSSR); return; } /*上邊界交叉點(diǎn)*/ if(y==0) { putch(CROSSU); return; } /*下邊界交叉點(diǎn)*/ if(y==18) { putch(CROSSD); return; } /*棋盤中間的交叉點(diǎn)*/ putch(CROSS); } /*交換行棋方*/ int ChangeOrder(void) { if(gPlayOrder==CHESS1) gPlayOrder=CHESS2; else gPlayOrder=CHESS1; return(gPlayOrder); } /*獲取按鍵值*/ int GetKey(void) { char lowbyte; int press; while (bioskey(1) == 0) ;/*如果用戶沒有按鍵,空循環(huán)*/ press=bioskey(0); lowbyte=press&0xff; press=press&0xff00 + toupper(lowbyte); return(press); } /*落子錯(cuò)誤處理*/ void DoError(void) { sound(1200); delay(50); nosound(); } /*贏棋處理*/ void DoWin(int Order) { sound(1500);delay(100); sound(0); delay(50); sound(800); delay(100); sound(0); delay(50); sound(1500);delay(100); sound(0); delay(50); sound(800); delay(100); sound(0); delay(50); nosound(); textcolor(RED+BLINK); gotoxy(25,20); if(Order==CHESS1) cputs("PLAYER1 WIN!"); else cputs("PLAYER2 WIN!"); gotoxy(25,21); cputs(" \\<^+^>/"); getch(); } /*走棋*/ int ChessGo(int Order,struct point Cursor) { /*判斷交叉點(diǎn)上有無(wú)棋子*/ 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 return FALSE; } /*判斷當(dāng)前行棋方落子后是否贏棋*/ int JudgeWin(int Order,struct point Cursor) { int i; for(i=0;i<4;i++) /*判斷在指定方向上是否有連續(xù)5個(gè)行棋方的棋子*/ if(JudgeWinLine(Order,Cursor,i)) return TRUE; return FALSE; } /*判斷在指定方向上是否有連續(xù)5個(gè)行棋方的棋子*/ int JudgeWinLine(int Order,struct point Cursor,int direction) { int i; struct point pos,dpos; const int testnum = 5; int count; switch(direction) { case 0:/*在水平方向*/ pos.x=Cursor.x-(testnum-1); pos.y=Cursor.y; dpos.x=1; dpos.y=0; break; case 1:/*在垂直方向*/ pos.x=Cursor.x; pos.y=Cursor.y-(testnum-1); dpos.x=0; dpos.y=1; break; case 2:/*在左下至右上的斜方向*/ pos.x=Cursor.x-(testnum-1); pos.y=Cursor.y+(testnum-1); dpos.x=1; dpos.y=-1; break; case 3:/*在左上至右下的斜方向*/ pos.x=Cursor.x-(testnum-1); pos.y=Cursor.y-(testnum-1); dpos.x=1; dpos.y=1; break; } count=0; for(i=0;i<testnum*2+1;i++)/*????????i<testnum*2-1*/ { 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; } return FALSE; } /*移動(dòng)光標(biāo)*/ void MoveCursor(int Order,int press) { switch(press) { 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); } /*游戲結(jié)束處理*/ void EndGame(void) { textmode(C80); } /*顯示當(dāng)前行棋方*/ 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); sound(600); delay(50); sound(1000); delay(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 || press==PLAY1LEFT || press==PLAY1RIGHT || press==PLAY2UP || press==PLAY2DOWN || press==PLAY2LEFT || press==PLAY2RIGHT ) return KEYMOVECURSOR;/*是光標(biāo)移動(dòng)鍵*/ else return KEYINVALID;/*按鍵無(wú)效*/ }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
您可能感興趣的文章:
相關(guān)文章
淺談C++中虛函數(shù)實(shí)現(xiàn)原理揭秘
下面小編就為大家?guī)?lái)一篇淺談C++中虛函數(shù)實(shí)現(xiàn)原理揭秘。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2016-06-06C++實(shí)現(xiàn) 單例模式實(shí)例詳解
這篇文章主要介紹了C++實(shí)現(xiàn) 單例模式實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-05-05C++算術(shù)運(yùn)算符與類型轉(zhuǎn)換
這篇文章主要介紹了C++算術(shù)運(yùn)算符與類型轉(zhuǎn)換,C++當(dāng)中提供5種基礎(chǔ)的算術(shù)運(yùn)算符,分別是加法、減法、乘法、除法和取模。下main我們就一起來(lái)看看下面文章得具體舉例與說(shuō)明,需要的朋友可以參考一下,希望對(duì)你有所幫助2021-11-11C++如何實(shí)現(xiàn)定長(zhǎng)內(nèi)存池詳解
內(nèi)存池根據(jù)存儲(chǔ)的元素的長(zhǎng)度是否可變,分為變長(zhǎng),與定長(zhǎng)兩種內(nèi)存池,這篇文章主要給大家介紹了關(guān)于C++如何實(shí)現(xiàn)定長(zhǎng)內(nèi)存池的相關(guān)資料,需要的朋友可以參考下2021-09-09