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

Python09

用C语言编写一个五子棋的游戏程序,第1张

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

/* 程序中用到的库函数所在头文件应用 #include 命令包含进来 */

#include <stdio.h>

#include <bios.h>

#include <ctype.h>

#include <conio.h>

#include <dos.h>

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

/* 定义符号常量 */

/*定义画棋盘所需的制表符*/

#define CROSSRU 0xbf /*右上角点*/

#define CROSSLU 0xda /*左上角点*/

#define CROSSLD 0xc0 /*左下角点*/

#define CROSSRD 0xd9 /*右下角点*/

#define CROSSL 0xc3 /*左边*/

#define CROSSR 0xb4 /*右边*/

#define CROSSU 0xc2 /*上边*/

#define CROSSD 0xc1 /*下边*/

#define CROSS 0xc5 /*十字交叉点*/

/*定义棋盘左上角点在屏幕上的位置*/

#define MAPXOFT 5

#define MAPYOFT 2

/*定义1号玩家的操作键键码*/

#define PLAY1UP 0x1157/*上移--'W'*/

#define PLAY1DOWN 0x1f53/*下移--'S'*/

#define PLAY1LEFT 0x1e41/*左移--'A'*/

#define PLAY1RIGHT 0x2044/*右移--'D'*/

#define PLAY1DO 0x3920/*落子--空格键*/

/*定义2号玩家的操作键键码*/

#define PLAY2UP 0x4800/*上移--方向键up*/

#define PLAY2DOWN 0x5000/*下移--方向键down*/

#define PLAY2LEFT 0x4b00/*左移--方向键left*/

#define PLAY2RIGHT 0x4d00/*右移--方向键right*/

#define PLAY2DO 0x1c0d/*落子--回车键Enter*/

/*若想在游戏中途退出, 可按 Esc 键*/

#define ESCAPE 0x011b

/*定义棋盘上交叉点的状态, 即该点有无棋子 */

/*若有棋子, 还应能指出是哪个玩家的棋子 */

#define CHESSNULL 0 //没有棋子

#define CHESS1 'O'//一号玩家的棋子

#define CHESS2 'X'//二号玩家的棋子

/*定义按键类别*/

#define KEYEXIT0/*退出键*/

#define KEYFALLCHESS 1/*落子键*/

#define KEYMOVECURSOR 2/*光标移动键*/

#define KEYINVALID 3/*无效键*/

/*定义符号常量: 真, 假 --- 真为1, 假为0 */

#define TRUE1

#define FALSE 0

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

/* 定义数据结构 */

/*棋盘交叉点坐标的数据结构*/

struct point

{

int x,y

}

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

/*自定义函数原型说明 */

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/*指示当前行棋方 */

struct point gCursor /*光标在棋盘上的位置 */

char gChessBoard[19][19]/*用于记录棋盘上各点的状态*/

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

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

/*主函数*/

void main()

{

int press

int bOutWhile=FALSE/*退出循环标志*/

Init()/*初始化图象,数据*/

while(1)

{

press=GetKey()/*获取用户的按键值*/

switch(CheckKey(press))/*判断按键类别*/

{

/*是退出键*/

case KEYEXIT:

clrscr()/*清屏*/

bOutWhile = TRUE

break

/*是落子键*/

case KEYFALLCHESS:

if(ChessGo(gPlayOrder,gCursor)==FALSE)/*走棋*/

DoError()/*落子错误*/

else

{

DoOK()/*落子正确*/

/*如果当前行棋方赢棋*/

if(JudgeWin(gPlayOrder,gCursor)==TRUE)

{

DoWin(gPlayOrder)

bOutWhile = TRUE/*退出循环标志置为真*/

}

/*否则*/

else

/*交换行棋方*/

ChangeOrder()

}

break

/*是光标移动键*/

case KEYMOVECURSOR:

MoveCursor(gPlayOrder,press)

break

/*是无效键*/

case KEYINVALID:

break

}

if(bOutWhile==TRUE)

break

}

/*游戏结束*/

EndGame()

}

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

/*界面初始化,数据初始化*/

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号玩家*/

gPlayOrder = CHESS1

/*棋盘数据清零, 即棋盘上各点开始的时候都没有棋子*/

for(i=0i<19i++)

for(j=0j<19j++)

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++

}

/*显示当前行棋方*/

ShowOrderMsg(gPlayOrder)

/*光标移至棋盘的左上角点处*/

gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT)

}

/*画棋盘*/

void DrawMap(void)

{

int i,j

clrscr()

for(i=0i<19i++)

for(j=0j<19j++)

DrawCross(i,j)

}

/*画棋盘上的交叉点*/

void DrawCross(int x,int y)

{

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)

}

/*交换行棋方*/

int ChangeOrder(void)

{

if(gPlayOrder==CHESS1)

gPlayOrder=CHESS2

else

gPlayOrder=CHESS1

return(gPlayOrder)

}

/*获取按键值*/

int GetKey(void)

{

char lowbyte

int press

while (bioskey(1) == 0)

/*如果用户没有按键,空循环*/

press=bioskey(0)

lowbyte=press&0xff

press=press&0xff00 + toupper(lowbyte)

return(press)

}

/*落子错误处理*/

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)

{

/*判断交叉点上有无棋子*/

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

}

/*判断当前行棋方落子后是否赢棋*/

int JudgeWin(int Order,struct point Cursor)

{

int i

for(i=0i<4i++)

/*判断在指定方向上是否有连续5个行棋方的棋子*/

if(JudgeWinLine(Order,Cursor,i))

return TRUE

return FALSE

}

/*判断在指定方向上是否有连续5个行棋方的棋子*/

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=0i<testnum*2+1i++)

{

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

}

/*移动光标*/

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)

}

/*游戏结束处理*/

void EndGame(void)

{

textmode(C80)

}

/*显示当前行棋方*/

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/*是光标移动键*/

else

return KEYINVALID/*按键无效*/

}

#include <stdio.h>

#include <bios.h>

#include <ctype.h>

#include <conio.h>

#include <dos.h>

#define CROSSRU 0xbf /*右上角点*/

#define CROSSLU 0xda /*左上角点*/

#define CROSSLD 0xc0 /*左下角点*/

#define CROSSRD 0xd9 /*右下角点*/

#define CROSSL 0xc3 /*左边*/

#define CROSSR 0xb4 /*右边*/

#define CROSSU 0xc2 /*上边*/

#define CROSSD 0xc1 /*下边*/

#define CROSS 0xc5 /*十字交叉点*/

/*定义棋盘左上角点在屏幕上的位置*/

#define MAPXOFT 5

#define MAPYOFT 2

/*定义1号玩家的操作键键码*/

#define PLAY1UP 0x1157/*上移--'W'*/

#define PLAY1DOWN 0x1f53/*下移--'S'*/

#define PLAY1LEFT 0x1e41/*左移--'A'*/

#define PLAY1RIGHT 0x2044/*右移--'D'*/

#define PLAY1DO 0x3920/*落子--空格键*/

/*定义2号玩家的操作键键码*/

#define PLAY2UP 0x4800/*上移--方向键up*/

#define PLAY2DOWN 0x5000/*下移--方向键down*/

#define PLAY2LEFT 0x4b00/*左移--方向键left*/

#define PLAY2RIGHT 0x4d00/*右移--方向键right*/

#define PLAY2DO 0x1c0d/*落子--回车键Enter*/

/*若想在游戏中途退出, 可按 Esc 键*/

#define ESCAPE 0x011b

/*定义棋盘上交叉点的状态, 即该点有无棋子 */

/*若有棋子, 还应能指出是哪个玩家的棋子 */

#define CHESSNULL 0 /*没有棋子*/

#define CHESS1 'O'/*一号玩家的棋子*/

#define CHESS2 'X'/*二号玩家的棋子*/

/*定义按键类别*/

#define KEYEXIT0/*退出键*/

#define KEYFALLCHESS 1/*落子键*/

#define KEYMOVECURSOR 2/*光标移动键*/

#define KEYINVALID 3/*无效键*/

/*定义符号常量: 真, 假 --- 真为1, 假为0 */

#define TRUE1

#define FALSE 0

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

/* 定义数据结构 */

/*棋盘交叉点坐标的数据结构*/

struct point

{

int x,y

}

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

/*自定义函数原型说明 */

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/*指示当前行棋方 */

struct point gCursor /*光标在棋盘上的位置 */

char gChessBoard[19][19]/*用于记录棋盘上各点的状态*/

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

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

/*主函数*/

void main()

{

int press

int bOutWhile=FALSE/*退出循环标志*/

Init()/*初始化图象,数据*/

while(1)

{

press=GetKey()/*获取用户的按键值*/

switch(CheckKey(press))/*判断按键类别*/

{

/*是退出键*/

case KEYEXIT:

clrscr()/*清屏*/

bOutWhile = TRUE

break

/*是落子键*/

case KEYFALLCHESS:

if(ChessGo(gPlayOrder,gCursor)==FALSE)/*走棋*/

DoError()/*落子错误*/

else

{

DoOK()/*落子正确*/

/*如果当前行棋方赢棋*/

if(JudgeWin(gPlayOrder,gCursor)==TRUE)

{

DoWin(gPlayOrder)

bOutWhile = TRUE/*退出循环标志置为真*/

}

/*否则*/

else

/*交换行棋方*/

ChangeOrder()

ShowOrderMsg(gPlayOrder)

}

break

/*是光标移动键*/

case KEYMOVECURSOR:

MoveCursor(gPlayOrder,press)

break

/*是无效键*/

case KEYINVALID:

break

}

if(bOutWhile==TRUE)

break

}

/*游戏结束*/

EndGame()

}

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

/*界面初始化,数据初始化*/

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号玩家 */

gPlayOrder = CHESS1

/* 棋盘数据清零, 即棋盘上各点开始的时候都没有棋子 */

for(i=0i<19i++)

for(j=0j<19j++)

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++

}

/*显示当前行棋方*/

ShowOrderMsg(gPlayOrder)

/*光标移至棋盘的左上角点处*/

gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT)

}

/*画棋盘*/

void DrawMap(void)

{

int i,j

clrscr()

for(i=0i<19i++)

for(j=0j<19j++)

DrawCross(i,j)

}

/*画棋盘上的交叉点*/

void DrawCross(int x,int y)

{

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)

}

/*交换行棋方*/

int ChangeOrder(void)

{

if(gPlayOrder==CHESS1)

gPlayOrder=CHESS2

else

gPlayOrder=CHESS1

return(gPlayOrder)

}

/*获取按键值*/

int GetKey(void)

{

char lowbyte

int press

while (bioskey(1) == 0)

/*如果用户没有按键,空循环*/

press=bioskey(0)

lowbyte=press&0xff

press=press&0xff00 + toupper(lowbyte)

return(press)

}

/*落子错误处理*/

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("\n")

getch()

}

/*走棋*/

int ChessGo(int Order,struct point Cursor)

{

/*判断交叉点上有无棋子*/

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

}

/*判断当前行棋方落子后是否赢棋*/

int JudgeWin(int Order,struct point Cursor)

{

int i

for(i=0i<4i++)

/*判断在指定方向上是否有连续5个行棋方的棋子*/

if(JudgeWinLine(Order,Cursor,i))

return TRUE

return FALSE

}

/*判断在指定方向上是否有连续5个行棋方的棋子*/

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=0i<testnum*2+1i++)/*????????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

}

/*移动光标*/

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)

}

/*游戏结束处理*/

void EndGame(void)

{

textmode(C80)

}

/*显示当前行棋方*/

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/*是光标移动键*/

else

return KEYINVALID/*按键无效*/

}

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

加分才能得到更多的回答呀!

游戏说明

1.本五子棋规则遵循一般五子棋游戏规则。

2.'W',',S','A','D'分别对应与光标的上、下、左、右。“Enter”为落子键.且在

游戏当中双方必须分时复用。

3.本代码在Turboc 2.0 SMALL模式下调试通过。

4.如果要单独运行该代码生成的EXE文件,请确保Turboc 2.0系统自带的*.BGI与

该EXE在同一目录下,以便图形系统的正常运行。

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

#include <graphics.h>

#include <stdio.h>

#include <dos.h>

/*******************************全程变量****************************************/

#define HORIZON 150

#define VERTICAL 30

#define MAXX 15

#define MAXY 15

int curx=HORIZON,cury=VERTICAL

char C=''

int AOrB=0

int state[MAXY][MAXX]/*state[][]为红白方状态:1为红方,2为白方.*/

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

struct Offset

{

int abs

int array

int offset

int state

}

struct XYPoint

{

int x

int y

}

struct WinPoint

{

struct XYPoint pointXY[5]

char win

}

char getkey()

{

union REGS regs

regs.h.ah=0

return int86(0x16,®s,®s)

}

void DrawRectangle(int color)

{

int tmpcolor=0,i=0

tmpcolor=getcolor()

setcolor(color)

for(i=0i<16i++)

line(20,190+i,100,190+i)

setcolor(tmpcolor)

}

void PutCharADSW(char ch)

{

setcolor(WHITE)

outtextxy(20,50,"W")

outtextxy(20,80,"S")

outtextxy(20,110,"A")

outtextxy(20,140,"D")

setcolor(LIGHTBLUE)

switch(ch)

{

case 'A':

case 'a':

outtextxy(20,110,"A")

break

case 'D':

case 'd':

outtextxy(20,140,"D")

break

case 'S':

case 's':

outtextxy(20,80,"S")

break

case 'W':

case 'w':

outtextxy(20,50,"W")

break

}

}

void InterFace(void)

{

int i

char *tp=NULL

tp="W:up"

outtextxy(20,50,tp)

tp="S: down"

outtextxy(20,80,tp)

tp="A: left"

outtextxy(20,110,tp)

tp="D: Right"

outtextxy(20,140,tp)

tp="Current:"

outtextxy(20,170,tp)

DrawRectangle(WHITE)

for(i=0i<MAXXi++)

line(HORIZON,i*30+VERTICAL,HORIZON+420,i*30+VERTICAL)

for(i=0i<MAXYi++)

line(HORIZON+i*30,VERTICAL,HORIZON+i*30,420+VERTICAL)

}

void DrawCircle(int x,int y,int radius,int colour)

{

int i

setcolor(colour)

for(i=0i<radiusi++)

circle(x,y,i)

}

void DrawLine(int x,int y,int xx,int yy,int col)

{

int tmpcolour=0

tmpcolour=getcolor()

setcolor(col)

line(x,y,xx,yy)

setcolor(tmpcolour)

}

void SetCursor(int x1,int y1,int col)

{

DrawLine(curx-14+x1,cury-14+y1,curx-4+x1,cury-14+y1,col)

DrawLine(curx+4+x1,cury-14+y1,curx+14+x1,cury-14+y1,col)

DrawLine(curx-14+x1,cury-14+y1,curx-14+x1,cury-4+y1,col)

DrawLine(curx+14+x1,cury-14+y1,curx+14+x1,cury-4+y1,col)

DrawLine(curx-14+x1,cury+14+y1,curx-4+x1,cury+14+y1,col)

DrawLine(curx+4+x1,cury+14+y1,curx+14+x1,cury+14+y1,col)

DrawLine(curx-14+x1,cury+4+y1,curx-14+x1,cury+14+y1,col)

DrawLine(curx+14+x1,cury+4+y1,curx+14+x1,cury+14+y1,col)

}

/*struct Offset

{

int abs curx,cury

int array x,y

int offset x1,y1

int state 0表示:无空位1表示:有空位

}*/

/*Test Vertical*/

/*Test x Y Or N Space*/

int TestxYOrNSpace(int y)

{

int i=0,sum=1

for(i=0i<MAXYi++)

{

sum&=(1==state[i][y]||2==state[i][y])

if(!sum)break

}

return(sum)

/*sum==0表示该行列没有空位*/

}

/*Go Left*/

struct Offset * TestMoveCursorLeft(int y,struct Offset * pointer)

{

int i=0,sum=1

for(i=y-1i>=0i--)

{

sum=TestxYOrNSpace(i)

if(!sum)break

}

if(sum)

{/*表示该点左边已没有空位*/

pointer->abs=0

pointer->array=0

pointer->offset=0

pointer->state=0/*若为0,表示无空位*/

}

else

{

pointer->abs=(30)*(y-i)

pointer->array=y-i

pointer->offset=(30)*(y-i)

pointer->state=1/*若为1,表示有空位*/

}

return(pointer)

}

/*Go Right*/

struct Offset * TestMoveCursorRight(int y,struct Offset * pointer)

{

int i=0,sum=1

for(i=y+1i<MAXXi++)

{

sum=TestxYOrNSpace(i)

if(!sum)break

}

if(sum)

{

pointer->abs=0

pointer->array=0

pointer->offset=0

pointer->state=0/*若为0,表示无空位*/

}

else

{

pointer->abs=(30)*(i-y)

pointer->array=i-y

pointer->offset=(30)*(i-y)

pointer->state=1/*若为1,表示有空位*/

}

return(pointer)

}

/*Test y Y Or N Space*/

int TestyYOrNSpace(int x)

{

int i=0,sum=1

for(i=0i<MAXXi++)

{

sum&=(1==state[x][i]||2==state[x][i])

if(!sum)break

}

return(sum)

}

/*Go Up*/

struct Offset * TestMoveCursorUp(int x,struct Offset * pointer)

{

int i=0,sum=1

for(i=x-1i>=0i--)

{

sum=TestyYOrNSpace(i)

if(!sum)break

}

if(sum)

{

pointer->abs=0

pointer->array=0

pointer->offset=0

pointer->state=0/*若为0,表示无空位*/

}

else

{

pointer->abs=(30)*(x-i)

pointer->array=x-i

pointer->offset=(30)*(x-i)

pointer->state=1/*若为1,表示有空位*/

}

return(pointer)

}

/*Go Down*/

struct Offset * TestMoveCursorDown(int x,struct Offset * pointer)

{

int i=0,sum=1

for(i=x+1i<MAXYi++)

{

sum=TestyYOrNSpace(i)

if(!sum)break

}

if(sum)

{

pointer->abs=0

pointer->array=0

pointer->offset=0

pointer->state=0/*若为0,表示无空位*/

}

else

{

pointer->abs=(30)*(i-x)

pointer->array=i-x

pointer->offset=(30)*(i-x)

pointer->state=1/*若为1,表示有空位*/

}

return(pointer)

}

void ClearPoint(struct Offset * pointer)

{

pointer->abs=0

pointer->array=0

pointer->offset=0

pointer->state=0

}

void Delay(int n)

{

int i,j

for(i=0i<ni++)

for(j=0j<32767j++)

}

/*Move Cursor*/

void MoveCursor(struct XYPoint *PointXY)

{

int x1=0,y1=0,lop=1,x=0,y=0 /*x1,y1为光标在各方向的偏移量*/

struct Offset InfoOffset,*point=NULL

point=&InfoOffset

ClearPoint(point)

x=(curx-HORIZON)/30 /*(x,y)为STATE[][]数组坐标*/

y=(cury-VERTICAL)/30

while(lop)

{

C=getkey()

switch(C)

{

case 'A':

case 'a':

PutCharADSW(C)

if(curx>HORIZON)

{

point=TestMoveCursorLeft(x,point)

if(point->state)

{

curx-=point->abs

x-=point->array

x1+=point->offset

ClearPoint(point)

}

}

break

case 'D':

case 'd':

PutCharADSW(C)

if(curx<420+HORIZON)

{

point=TestMoveCursorRight(x,point)

if(point->state)

{

curx+=point->abs

x+=point->array

x1-=point->offset

ClearPoint(point)

}

}

break

case 'W':

case 'w':

PutCharADSW(C)

if(cury>VERTICAL)

{

point=TestMoveCursorUp(y,point)

if(point->state)

{

cury-=point->abs

y-=point->array

y1+=point->offset

ClearPoint(point)

}

}

break

case 'S':

case 's':

PutCharADSW(C)

if(cury<VERTICAL+420)

{

point=TestMoveCursorDown(y,point)

if(point->state)

{

cury+=point->abs

y+=point->array

y1-=point->offset

ClearPoint(point)

}

}

break

case 13 : /*落子:AOrB==0 REDAOrB==1 WHITE*/

if(!(state[y][x]&0x3))

{

if(1==AOrB)

{

state[y][x]|=0x1

DrawCircle(curx,cury,15,RED)

AOrB=0

DrawRectangle(WHITE)

}

else

{

state[y][x]|=0x2

DrawCircle(curx,cury,15,WHITE)

AOrB=1

DrawRectangle(RED)

}

lop=0

PointXY->x=x

PointXY->y=y

}

break

}

SetCursor(x1,y1,getbkcolor())/*clear old*/

x1=0

y1=0

SetCursor(0,0,BLUE)

}

}

/*Example: MoveCircle(60+cou*30,20,'H',30,WHITE)*/

void MoveCircle(int x,int y,char way,int offset,int colour)

{

int tmp=0

for(tmp=0tmp<15tmp++)

DrawCircle(x,y,15,getbkcolor())

DrawLine(x-15,y,x+15,y,WHITE)

DrawLine(x,y,x,y+15,WHITE)

switch(way)

{

case 'h':

case 'H':

DrawCircle(x+offset,y,15,colour)

break

case 'v':

case 'V':

DrawCircle(x,y+offset,15,colour)

}

}

void DrawRLine(int x,int y)

{

if(x>HORIZON)

DrawLine(x-15,y,x,y,WHITE) /*Left*/

if(x<30*14+HORIZON)

DrawLine(x,y,x+15,y,WHITE) /*Right*/

if(y>VERTICAL)

DrawLine(x,y-15,x,y,WHITE) /*Up*/

if(y<30*14+VERTICAL)

DrawLine(x,y,x,y+15,WHITE) /*Down*/

}

void FlashCircle(struct WinPoint win)

{

int i=0,color=0,count=0,EXIT=0

/*DrawCircle(curx,cury,15,RED)*/

switch(AOrB)

{

case 0: /*AOrB==0 RED*/

color=RED

break

case 1: /*AOrB==1 WHITE*/

color=WHITE

break

}

while(1)

{

if(count)

{

DrawCircle(HORIZON+30*win.pointXY[0].x,VERTICAL+30*win.pointXY[0].y,15,getbkcolor())

DrawRLine( HORIZON+30*win.pointXY[0].x,VERTICAL+30*win.pointXY[0].y)

DrawCircle(HORIZON+30*win.pointXY[1].x,VERTICAL+30*win.pointXY[1].y,15,getbkcolor())

DrawRLine( HORIZON+30*win.pointXY[1].x,VERTICAL+30*win.pointXY[1].y)

DrawCircle(HORIZON+30*win.pointXY[2].x,VERTICAL+30*win.pointXY[2].y,15,getbkcolor())

DrawRLine( HORIZON+30*win.pointXY[2].x,VERTICAL+30*win.pointXY[2].y)

DrawCircle(HORIZON+30*win.pointXY[3].x,VERTICAL+30*win.pointXY[3].y,15,getbkcolor())

DrawRLine( HORIZON+30*win.pointXY[3].x,VERTICAL+30*win.pointXY[3].y)

DrawCircle(HORIZON+30*win.pointXY[4].x,VERTICAL+30*win.pointXY[4].y,15,getbkcolor())

DrawRLine( HORIZON+30*win.pointXY[4].x,VERTICAL+30*win.pointXY[4].y)

}

else

{

DrawCircle(HORIZON+30*win.pointXY[0].x,VERTICAL+30*win.pointXY[0].y,15,color)

DrawCircle(HORIZON+30*win.pointXY[1].x,VERTICAL+30*win.pointXY[1].y,15,color)

DrawCircle(HORIZON+30*win.pointXY[2].x,VERTICAL+30*win.pointXY[2].y,15,color)

DrawCircle(HORIZON+30*win.pointXY[3].x,VERTICAL+30*win.pointXY[3].y,15,color)

DrawCircle(HORIZON+30*win.pointXY[4].x,VERTICAL+30*win.pointXY[4].y,15,color)

}

Delay(1000)

if(5==i)

{

i=0

if(count)

count=0

else

count=1

}

i++

EXIT++

if(105==EXIT)break

}

}

void InitializationState(int pointer[MAXY][MAXX])

{

int i,j

for(i=0i<MAXYi++)

for(j=0j<MAXXj++)

{

*(*(pointer+i)+j)=0

}

}

/*Test WIN*/

struct WinPoint TestWIN(int Tmp,struct WinPoint TmpWinPoint,struct XYPoint * PointXY)

{

int i=0,j=0,s=Tmp

TmpWinPoint.win=0

for(i=0i<5i++)

{

if(PointXY->x+i>=4 &&PointXY->x+i <15)

{

for(Tmp=s,j=4j>=0j--)/*0度*/

{

TmpWinPoint.pointXY[j].x=PointXY->x+i-j

TmpWinPoint.pointXY[j].y=PointXY->y

Tmp&=state[PointXY->y][PointXY->x+i-j]

}

if(Tmp)

{

TmpWinPoint.win=1

break

}

}

if(PointXY->x-i>=0 &&PointXY->x-i <11 &&PointXY->y+i>=4 &&PointXY->y+i <15)

{

for(Tmp=s,j=4j>=0j--)/*45度*/

{

TmpWinPoint.pointXY[j].x=PointXY->x-i+j

TmpWinPoint.pointXY[j].y=PointXY->y+i-j

Tmp&=state[PointXY->y+i-j][PointXY->x-i+j]

/*printf(" %d",state[PointXY->y+i-j][PointXY->x+i+j])*/

}

if(Tmp)

{

TmpWinPoint.win=1

break

}

}

if(PointXY->y+i>=4 &&PointXY->y+i <15)

{

for(Tmp=s,j=4j>=0j--)/*90度*/

{

TmpWinPoint.pointXY[j].x=PointXY->x

TmpWinPoint.pointXY[j].y=PointXY->y+i-j

Tmp&=state[PointXY->y+i-j][PointXY->x]

}

if(Tmp)

{

TmpWinPoint.win=1

break

}

}

if(PointXY->x+i>=4 &&PointXY->x+i <15 &&PointXY->y+i>=4 &&PointXY->y+i <15)

{

for(Tmp=s,j=4j>=0j--)/*135度*/

{

TmpWinPoint.pointXY[j].x=PointXY->x+i-j

TmpWinPoint.pointXY[j].y=PointXY->y+i-j

Tmp&=state[PointXY->y+i-j][PointXY->x+i-j]

}

if(Tmp)

{

TmpWinPoint.win=1

break

}

}

}

return(TmpWinPoint)

}

/*Test Win Y or N*/

struct WinPoint Test_Win_YorN(struct XYPoint * PointXY)

{

struct WinPoint TmpWinPoint

TmpWinPoint.win=0

switch(AOrB)

{

case 0: /*AOrB==0 RED*/

TmpWinPoint=TestWIN(1,TmpWinPoint,PointXY)

break

case 1: /*AOrB==1 WHITE*/

TmpWinPoint=TestWIN(2,TmpWinPoint,PointXY)

break

}

return(TmpWinPoint)

}

main()

{

int driver,mode,NoWiner=1

struct XYPoint CurrentXY

struct WinPoint WIN

START:

driver=DETECT

mode=0

detectgraph(&driver,&mode)

initgraph(&driver,&mode,"")

InterFace()

InitializationState(state)

CurrentXY.x=0

CurrentXY.y=0

SetCursor(0,0,BLUE)

while(NoWiner)

{

MoveCursor(&CurrentXY)

WIN=Test_Win_YorN(&CurrentXY)

if(WIN.win)break

}

FlashCircle(WIN)

setcolor(WHITE)

outtextxy(280,215,"CONTINUE ?[Y/N]")

C=getkey()

if('Y'==C ||'y'==C)

{

C=''

goto START

}

}