用C语言写一个五子棋游戏程序

**********************************************************/

/*程序中使用的库函数的头文件包含在#include命令中*/

# 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 */

#定义交叉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键无效;/*无效密钥*/

}