用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键无效;/*无效密钥*/
}