**********************************************************/
/*程序中用到的庫函數(shù)所在頭文件應(yīng)用#include命令包含進來*/
#include
#include
#include
#include
#include
/**********************************************************/
/*定義符號常量*/
/*定義畫棋盤所需的制表符*/
#defineCROSSRU0xbf/*右上角點*/
#defineCROSSLU0xda/*左上角點*/
#defineCROSSLD0xc0/*左下角點*/
#defineCROSSRD0xd9/*右下角點*/
#defineCROSSL0xc3/*左邊*/
#defineCROSSR0xb4/*右邊*/
#defineCROSSU0xc2/*上邊*/
#defineCROSSD0xc1/*下邊*/
#defineCROSS0xc5/*十字交叉點*/
/*定義棋盤左上角點在屏幕上的位置*/
#defineMAPXOFT5
#defineMAPYOFT2
/*定義1號玩家的操作鍵鍵碼*/
#definePLAY1UP0x1157/*上移--'W'*/
#definePLAY1DOWN0x1f53/*下移--'S'*/
#definePLAY1LEFT0x1e41/*左移--'A'*/
#definePLAY1RIGHT0x2044/*右移--'D'*/
#definePLAY1DO0x3920/*落子--空格鍵*/
/*定義2號玩家的操作鍵鍵碼*/
#definePLAY2UP0x4800/*上移--方向鍵up*/
#definePLAY2DOWN0x5000/*下移--方向鍵down*/
#definePLAY2LEFT0x4b00/*左移--方向鍵left*/
#definePLAY2RIGHT0x4d00/*右移--方向鍵right*/
#definePLAY2DO0x1c0d/*落子--回車鍵Enter*/
/*若想在游戲中途退出,可按Esc鍵*/
#defineESCAPE0x011b
/*定義棋盤上交叉點的狀態(tài),即該點有無棋子*/
/*若有棋子,還應(yīng)能指出是哪個玩家的棋子*/
#defineCHESSNULL0//沒有棋子
#defineCHESS1'O'//一號玩家的棋子
#defineCHESS2'X'//二號玩家的棋子
/*定義按鍵類別*/
#defineKEYEXIT0/*退出鍵*/
#defineKEYFALLCHESS1/*落子鍵*/
#defineKEYMOVECURSOR2/*光標移動鍵*/
#defineKEYINVALID3/*無效鍵*/
/*定義符號常量:真,假---真為1,假為0*/
#defineTRUE1
#defineFALSE0
/**********************************************************/
/*定義數(shù)據(jù)結(jié)構(gòu)*/
/*棋盤交叉點坐標的數(shù)據(jù)結(jié)構(gòu)*/
structpoint
{
intx,y;
};
/**********************************************************/
/*自定義函數(shù)原型說明*/
voidInit(void);
intGetKey(void);
intCheckKey(intpress);
intChangeOrder(void);
intChessGo(intOrder,structpointCursor);
voidDoError(void);
voidDoOK(void);
voidDoWin(intOrder);
voidMoveCursor(intOrder,intpress);
voidDrawCross(intx,inty);
voidDrawMap(void);
intJudgeWin(intOrder,structpointCursor);
intJudgeWinLine(intOrder,structpointCursor,intdirection);
voidShowOrderMsg(intOrder);
voidEndGame(void);
/**********************************************************/
/**********************************************************/
/*定義全局變量*/
intgPlayOrder;/*指示當(dāng)前行棋方*/
structpointgCursor;/*光標在棋盤上的位置*/
chargChessBoard[19][19];/*用于記錄棋盤上各點的狀態(tài)*/
/**********************************************************/
/**********************************************************/
/*主函數(shù)*/
voidmain()
{
intpress;
intbOutWhile=FALSE;/*退出循環(huán)標志*/
Init();/*初始化圖象,數(shù)據(jù)*/
while(1)
{
press=GetKey();/*獲取用戶的按鍵值*/
switch(CheckKey(press))/*判斷按鍵類別*/
{
/*是退出鍵*/
caseKEYEXIT:
clrscr();/*清屏*/
bOutWhile=TRUE;
break;
/*是落子鍵*/
caseKEYFALLCHESS:
if(ChessGo(gPlayOrder,gCursor)==FALSE)/*走棋*/
DoError();/*落子錯誤*/
else
{
DoOK();/*落子正確*/
/*如果當(dāng)前行棋方贏棋*/
if(JudgeWin(gPlayOrder,gCursor)==TRUE)
{
DoWin(gPlayOrder);
bOutWhile=TRUE;/*退出循環(huán)標志置為真*/
}
/*否則*/
else
/*交換行棋方*/
ChangeOrder();
}
break;
/*是光標移動鍵*/
caseKEYMOVECURSOR:
MoveCursor(gPlayOrder,press);
break;
/*是無效鍵*/
caseKEYINVALID:
break;
}
if(bOutWhile==TRUE)
break;
}
/*游戲結(jié)束*/
EndGame();
}
/**********************************************************/
/*界面初始化,數(shù)據(jù)初始化*/
voidInit(void)
{
inti,j;
char*Msg[]=
{
Player1key:,
UP----w,
DOWN--s,
LEFT--a,
RIGHT-d,
DO----space,
,
Player2key:,
UP----up,
DOWN--down,
LEFT--left,
RIGHT-right,
DO----ENTER,
,
exitgame:,
ESC,
NULL,
};
/*先手方為1號玩家*/
gPlayOrder=CHESS1;
/*棋盤數(shù)據(jù)清零,即棋盤上各點開始的時候都沒有棋子*/
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++;
}
/*顯示當(dāng)前行棋方*/
ShowOrderMsg(gPlayOrder);
/*光標移至棋盤的左上角點處*/
gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT);
}
/*畫棋盤*/
voidDrawMap(void)
{
inti,j;
clrscr();
for(i=0;i<19;i++)
for(j=0;j<19;j++)
DrawCross(i,j);
}
/*畫棋盤上的交叉點*/
voidDrawCross(intx,inty)
{
gotoxy(x+MAPXOFT,y+MAPYOFT);
/*交叉點上是一號玩家的棋子*/
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;
}
/*右上角交叉點*/
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;
}
/*棋盤中間的交叉點*/
putch(CROSS);
}
/*交換行棋方*/
intChangeOrder(void)
{
if(gPlayOrder==CHESS1)
gPlayOrder=CHESS2;
else
gPlayOrder=CHESS1;
return(gPlayOrder);
}
/*獲取按鍵值*/
intGetKey(void)
{
charlowbyte;
intpress;
while(bioskey(1)==0)
;/*如果用戶沒有按鍵,空循環(huán)*/
press=bioskey(0);
lowbyte=press&0xff;
press=press&0xff00+toupper(lowbyte);
return(press);
}
/*落子錯誤處理*/
voidDoError(void)
{
sound(1200);
delay(50);
nosound();
}
/*贏棋處理*/
voidDoWin(intOrder)
{
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(PLAYER1WIN!);
else
cputs(PLAYER2WIN!);
gotoxy(25,21);
cputs(\\/);
getch();
}
/*走棋*/
intChessGo(intOrder,structpointCursor)
{
/*判斷交叉點上有無棋子*/
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;
returnTRUE;
}
else
returnFALSE;
}
/*判斷當(dāng)前行棋方落子后是否贏棋*/
intJudgeWin(intOrder,structpointCursor)
{
inti;
for(i=0;i<4;i++)
/*判斷在指定方向上是否有連續(xù)5個行棋方的棋子*/
if(JudgeWinLine(Order,Cursor,i))
returnTRUE;
returnFALSE;
}
/*判斷在指定方向上是否有連續(xù)5個行棋方的棋子*/
intJudgeWinLine(intOrder,structpointCursor,intdirection)
{
inti;
structpointpos,dpos;
constinttestnum=5;
intcount;
switch(direction)
{
case0:/*在水平方向*/
pos.x=Cursor.x-(testnum-1);
pos.y=Cursor.y;
dpos.x=1;
dpos.y=0;
break;
case1:/*在垂直方向*/
pos.x=Cursor.x;
pos.y=Cursor.y-(testnum-1);
dpos.x=0;
dpos.y=1;
break;
case2:/*在左下至右上的斜方向*/
pos.x=Cursor.x-(testnum-1);
pos.y=Cursor.y+(testnum-1);
dpos.x=1;
dpos.y=-1;
break;
case3:/*在左上至右下的斜方向*/
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++)
{
if(pos.x>=0&&pos.x=0&&pos.y<=18)
{
if(gChessBoard[pos.x][pos.y]==Order)
{
count++;
if(count>=testnum)
returnTRUE;
}
else
count=0;
}
pos.x+=dpos.x;
pos.y+=dpos.y;
}
returnFALSE;
}
/*移動光標*/
voidMoveCursor(intOrder,intpress)
{
switch(press)
{
casePLAY1UP:
if(Order==CHESS1&&gCursor.y>0)
gCursor.y--;
break;
casePLAY1DOWN:
if(Order==CHESS1&&gCursor.y<18)
gCursor.y++;
break;
casePLAY1LEFT:
if(Order==CHESS1&&gCursor.x>0)
gCursor.x--;
break;
casePLAY1RIGHT:
if(Order==CHESS1&&gCursor.x<18)
gCursor.x++;
break;
casePLAY2UP:
if(Order==CHESS2&&gCursor.y>0)
gCursor.y--;
break;
casePLAY2DOWN:
if(Order==CHESS2&&gCursor.y<18)
gCursor.y++;
break;
casePLAY2LEFT:
if(Order==CHESS2&&gCursor.x>0)
gCursor.x--;
break;
casePLAY2RIGHT:
if(Order==CHESS2&&gCursor.x<18)
gCursor.x++;
break;
}
gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT);
}
/*游戲結(jié)束處理*/
voidEndGame(void)
{
textmode(C80);
}
/*顯示當(dāng)前行棋方*/
voidShowOrderMsg(intOrder)
{
gotoxy(6,MAPYOFT+20);
textcolor(LIGHTRED);
if(Order==CHESS1)
cputs(Player1go!);
else
cputs(Player2go!);
gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT);
}
/*落子正確處理*/
voidDoOK(void)
{
sound(500);
delay(70);
sound(600);
delay(50);
sound(1000);
delay(100);
nosound();
}
/*檢查用戶的按鍵類別*/
intCheckKey(intpress)
{
if(press==ESCAPE)
returnKEYEXIT;/*是退出鍵*/
else
if
((press==PLAY1DO&&gPlayOrder==CHESS1)||
(press==PLAY2DO&&gPlayOrder==CHESS2)
)
returnKEYFALLCHESS;/*是落子鍵*/
else
if
(press==PLAY1UP||press==PLAY1DOWN||
press==PLAY1LEFT||press==PLAY1RIGHT||
press==PLAY2UP||press==PLAY2DOWN||
press==PLAY2LEFT||press==PLAY2RIGHT
)
returnKEYMOVECURSOR;/*是光標移動鍵*/
else
returnKEYINVALID;/*按鍵無效*/
}