/* ALEX_LEE五子棋C語言小程序*/
/* o(∩_∩)o...可以用來復習C語言的小程序*/
/*我的博客:hi . Baidu . com/Alex lee 321 */
/******************************************************************/
/**********************************************************/
# include & ltstdio.h & gt
# include & ltbios.h & gt
# include & ltctype.h & gt
# include & ltconio.h & gt
# include & ltdos.h & gt
/**********************************************************/
/*定義符號常量*/
/*定義繪制棋盤所需的選項卡*/
#define CROSSRU 0xbf /*右上角*/
#define CROSSLU 0xda /*左上角點*/
#定義交叉0xc0 /*左下角點*/
#define CROSSRD 0xd9 /*右下角*/
#定義交叉0xc3 /* left */
#define CROSSR 0xb4 /* Right */
#define CROSSU 0xc2 /* Above */
#定義下面的cross d 0xc 1/*/
#定義交叉點0xc5 /*交叉點*/
/*定義棋盤左上角在屏幕上的位置*/
#定義MAPXOFT 5
#定義MAPYOFT 2
/*定義播放器1的操作鍵碼*/
# define play 1up 0x 1157/*上移-'w' */
# define play 1 down 0x 1f 53/*下移-'s' */
# define play 1 left 0x 1e 41/*左移-'a' */
# define play 1 right 0x 2044/* Move right-' d ' */
# define play 1DO 0x 3920/* Move-space bar */
/*定義播放器2的操作鍵碼*/
#define PLAY2UP 0x4800/*上移方向鍵上移*/
#define PLAY2DOWN 0x5000/*向下移動-方向鍵down*/
#define PLAY2LEFT 0x4b00/*向左移動方向鍵left*/
#define PLAY2RIGHT 0x4d00/*向右移動-方向鍵右*/
# define play 2 do 0x 1c0d/* move-Enter */
/*如果妳想在遊戲中途退出,按Esc */
#定義轉義0x011b
/*定義棋盤上交叉點的狀態,即該點是否有棋子*/
/*如果有棋子,妳也應該能指出是哪個玩家的棋子*/
#define CHESSNULL 0 //無棋子。
# define ches 1 ' O '//壹號玩家的棋子
#定義棋子2 'X'//玩家2的棋子
/*定義關鍵類別*/
#define鍵EXIT 0/* exit鍵*/
# define keyfallches 1/* drop key */
#define KEYMOVECURSOR 2/*光標鍵*/
#define KEYINVALID 3/*無效鍵*/
/*定義符號常量:true,false-true是1,false是0 */
#定義真1
#定義假0
/**********************************************************/
/*定義數據結構*/
/*棋盤交點坐標的數據結構*/
結構點
{
int x,y;
};
/**********************************************************/
/*自定義函數原型的描述*/
void Init(void);
int GetKey(void);
int check key(int press);
int change order(void);
int ChessGo(int Order,struct point Cursor);
void do error(void);
void DoOK(無效);
void DoWin(int Order);
void MoveCursor(int Order,int press);
void DrawCross(int x,int y);
void draw map(void);
int JudgeWin(int Order,struct point Cursor);
int JudgeWinLine(int Order,struct point遊標,int direction);
void ShowOrderMsg(int Order);
void殘局(void);
/**********************************************************/
/**********************************************************/
/*定義全局變量*/
int gPlayOrder/*表示當前棋手*/
結構點gCursor/*光標在棋盤上的位置*/
char gChessBoard[19][19];/*用於記錄棋盤上每個點的狀態*/
/**********************************************************/
/**********************************************************/
/*主函數*/
void main()
{
int press
int bOutWhile = FALSE/*退出循環標誌*/
init();/*初始化圖像,數據*/
while(1)
{
press = GetKey();/*獲取用戶的密鑰值*/
開關(CheckKey(press))/*確定按鍵類型*/
{
/*是退出鍵*/
案例密鑰退出:
clr SCR();/*清空屏幕*/
bOutWhile = TRUE
打破;
/*是下降鍵*/
case KEYFALLCHESS:
If (chess go (gplayorder,gcursor) = = false)/* chess */
do error();/*運動中的錯誤*/
其他
{
DoOK();/*正確移動*/
/*如果當前棋手贏了*/
if(JudgeWin(gPlayOrder,gCursor)==TRUE)
{
DoWin(gPlayOrder);
bOutWhile = TRUE/*退出循環標誌設置為真*/
}
/*否則*/
其他
/*交換棋手*/
change order();
}
打破;
/*是光標移動鍵*/
case KEYMOVECURSOR:
MoveCursor(gPlayOrder,press);
打破;
/*是無效的鍵*/
案例密鑰無效:
打破;
}
if(bOutWhile==TRUE)
打破;
}
/*遊戲結束*/
EndGame();
}
/**********************************************************/
/*界面初始化,數據初始化*/
void初始化(void)
{
int i,j;
char *Msg[]=
{
" Player1鍵:",
“上-下”,
“唐- s”,
“左- a”,
“右-d”,
“DO - space”,
"",
" Player2鍵:",
“向上向上”,
“向下-向下”,
“左-左”,
“右-右”,
“DO - ENTER”,
"",
"退出遊戲:",
“ESC”,
空,
};
/*第壹個玩家是玩家1 */
gPlayOrder = ches 1;
/*棋盤數據清零,即棋盤上每個點的開頭都沒有棋子*/
for(I = 0;我& lt19;i++)
for(j = 0;j & lt19;j++)
gChessBoard[I][j]= chess null;
/*初始光標位置*/
gcursor . x = gcursor . y = 0;
/*畫壹個棋盤*/
text mode(C40);
draw map();
/*顯示操作鍵描述*/
I = 0;
textcolor(棕色);
while(Msg[i]!=空)
{
gotoxy(25,3+I);
cputs(Msg[I]);
i++;
}
/*顯示當前的棋手*/
ShowOrderMsg(gPlayOrder);
/*將光標移動到棋盤的左上角*/
gotoxy(gCursor.x+MAPXOFT,gcursor . y+mapy oft);
}
/*畫壹個棋盤*/
void繪制地圖(void)
{
int i,j;
clr SCR();
for(I = 0;我& lt19;i++)
for(j = 0;j & lt19;j++)
DrawCross(i,j);
}
/*在棋盤上畫出交叉點*/
void DrawCross(int x,int y)
{
gotoxy(x+MAPXOFT,y+mapy oft);
/*交叉點是1號玩家的棋子*/
if(gChessBoard[x][y]= = chess 1)
{
textcolor(淺藍色);
putch(ches 1);
返回;
}
/*交點處是參與人2的棋子*/
if(gChessBoard[x][y]==CHESS2)
{
textcolor(淺藍色);
putch(chess 2);
返回;
}
textcolor(綠色);
/*左上角的交叉點*/
if(x = = 0 & amp;& ampy==0)
{
普特奇(克羅斯魯);
返回;
}
/*左下角的交叉點*/
if(x = = 0 & amp;& ampy==18)
{
putch(cross LD);
返回;
}
/*右上角交叉點*/
if(x = = 18 & amp;& ampy==0)
{
putch(克羅斯魯);
返回;
}
/*右下角交叉點*/
if(x = = 18 & amp;& ampy==18)
{
putch(cross rd);
返回;
}
/*左邊界交點*/
如果(x==0)
{
putch(cross l);
返回;
}
/*右邊界交點*/
如果(x==18)
{
putch(CROSSR);
返回;
}
/*上邊界交點*/
如果(y==0)
{
putch(CROSSU);
返回;
}
/*下邊界交點*/
if(y==18)
{
putch(CROSSD);
返回;
}
/*棋盤中間的交點*/
putch(十字);
}
/*交換棋手*/
int ChangeOrder(void)
{
if(gPlayOrder = = ches 1)
gPlayOrder = CHESS2
其他
gPlayOrder = ches 1;
return(gPlayOrder);
}
/*獲取鍵值*/
int GetKey(void)
{
char lowbyte
int press
while (bioskey(1) == 0)
;/*如果用戶不按鍵,循環為空*/
按= BIOS key(0);
低字節=按下& amp0xff
新聞=新聞& amp0x ff 00+toupper(low byte);
返回(按);
}
/*錯誤處理*/
void錯誤(void)
{
聲音(1200);
延遲(50);
nosound();
}
/*贏棋處理*/
void DoWin(整數順序)
{
聲音(1500);延時(100);
聲音(0);延遲(50);
聲音(800);延時(100);
聲音(0);延遲(50);
聲音(1500);延時(100);
聲音(0);延遲(50);
聲音(800);延時(100);
聲音(0);延遲(50);
nosound();
textcolor(紅色+閃爍);
gotoxy(25,20);
if(Order = = ches 1)
cputs("PLAYER1贏!");
其他
cputs("PLAYER2贏了!");
gotoxy(25,21);
cputs(" \ \ & lt;^+^>;/");
getch();
}
/*圍棋*/
int ChessGo(int Order,結構指針光標)
{
/*判斷交叉點是否有棋子*/
if(gChessBoard[cursor . x][cursor . y]= = chess null)
{
/*如果沒有棋子,可以移動*/
gotoxy(Cursor.x+MAPXOFT,cursor . y+mapy oft);
textcolor(淺藍色);
putch(訂單);
gotoxy(Cursor.x+MAPXOFT,cursor . y+mapy oft);
gChessBoard[cursor . x][cursor . y]= Order;
返回TRUE
}
其他
返回FALSE
}
/*下壹步棋後判斷當前棋手是否贏*/
int JudgeWin(int Order,struct point遊標)
{
int I;
for(I = 0;我& lt4;i++)
/*判斷指定方向是否有五個連續的棋子*/
if(JudgeWinLine(Order,Cursor,I))
返回TRUE
返回FALSE
}
/*判斷指定方向是否有五個連續的棋子*/
int判斷線(int順序,結構點光標,int方向)
{
int I;
結構點位置;
const int testnum = 5;
int計數;
開關(方向)
{
情況0:/*在水平方向*/
pos . x = cursor . x-(testnum-1);
pos . y = cursor . y;
dpos . x = 1;
dpos . y = 0;
打破;
案例1:/*垂直方向*/
pos . x = cursor . x;
pos . y = cursor . y-(testnum-1);
dpos . x = 0;
dpos . y = 1;
打破;
情況2:/*從左向右傾斜方向*/
pos . x = cursor . x-(testnum-1);
pos . y = cursor . y+(testnum-1);
dpos . x = 1;
dpos . y =-1;
打破;
情況3:/*從左上到右下的傾斜方向*/
pos . x = cursor . x-(testnum-1);
pos . y = cursor . y-(testnum-1);
dpos . x = 1;
dpos . y = 1;
打破;
}
count = 0;
for(I = 0;我& lttestnum * 2+1;i++)
{
如果(位置& gt= 0 & amp& amppos.x & lt=18。& amppos.y & gt= 0 & amp& amp位置& lt=18)
{
if(gChessBoard[位置x][位置y]= =順序)
{
count++;
if(count & gt;=testnum)
返回TRUE
}
其他
count = 0;
}
pos . x+= dpos . x;
pos . y+= dpos . y;
}
返回FALSE
}
/*移動光標*/
void MoveCursor(int Order,int press)
{
開關(按下)
{
案例分析1以上:
if(Order = = ches 1 & amp;& ampgCursor.y & gt0)
gcursor . y-;
打破;
案例分析1下載:
if(Order = = ches 1 & amp;& ampgCursor.y & lt18)
gcursor . y++;
打破;
案例分析1左側:
if(Order = = ches 1 & amp;& ampgCursor.x & gt0)
gcursor . x-;
打破;
案例分析1右:
if(Order = = ches 1 & amp;& ampgCursor.x & lt18)
gcursor . x++;
打破;
案例演示2:
if(Order = = chess 2 & amp;& ampgCursor.y & gt0)
gcursor . y-;
打破;
案例播放2下載:
if(Order = = chess 2 & amp;& ampgCursor.y & lt18)
gcursor . y++;
打破;
案例分析2左側:
if(Order = = chess 2 & amp;& ampgCursor.x & gt0)
gcursor . x-;
打破;
案例分析2正確:
if(Order = = chess 2 & amp;& ampgCursor.x & lt18)
gcursor . x++;
打破;
}
gotoxy(gCursor.x+MAPXOFT,gcursor . y+mapy oft);
}
/*遊戲結束處理*/
void殘局(void)
{
text mode(C80);
}
/*顯示當前的棋手*/
void ShowOrderMsg(int Order)
{
gotoxy(6,MAPYOFT+20);
textcolor(淺紅色);
if(Order = = ches 1)
cputs("Player1 go!");
其他
cputs("Player2 go!");
gotoxy(gCursor.x+MAPXOFT,gcursor . y+mapy oft);
}
/*正確操作機芯*/
void DoOK(無效)
{
聲音(500);
延遲(70);
聲音(600);
延遲(50);
聲音(1000);
延時(100);
nosound();
}
/*檢查用戶的按鍵類別*/
int CheckKey(int press)
{
if(按==ESCAPE)
回車鍵exit;/*是退出鍵*/
其他
如果
((press = = play 1DO & amp;& ampgPlayOrder = = ches 1)| |
(press = = PLAY2DO & amp& ampgPlayOrder==CHESS2)
)
返回KEYFALLCHESS/*是下降鍵*/
其他
如果
(press = = play 1 up | | press = = play 1 down | |
press==PLAY1LEFT ||
press = = play 2 up | | press = = play 2 down | |
press = = play 2左| | press = = play 2右
)
返回KEYMOVECURSOR/*是光標移動鍵*/
其他
return鍵無效;/*無效密鑰*/
}