w490978025 发表于 2007-6-6 18:40

五子棋的流图

<P>#include 命令包含进来 */</P>
<P>#include &lt;stdio.h&gt;<BR>#include &lt;bios.h&gt;<BR>#include &lt;ctype.h&gt;<BR>#include &lt;conio.h&gt;<BR>#include &lt;dos.h&gt;</P>
<P>/**********************************************************/<BR>/* 定义符号常量                                           */</P>
<P>/*定义画棋盘所需的制表符*/<BR>#define CROSSRU     0xbf  /*右上角点*/<BR>#define CROSSLU     0xda  /*左上角点*/<BR>#define CROSSLD     0xc0  /*左下角点*/<BR>#define CROSSRD     0xd9  /*右下角点*/<BR>#define CROSSL      0xc3  /*左边*/<BR>#define CROSSR      0xb4  /*右边*/<BR>#define CROSSU      0xc2  /*上边*/<BR>#define CROSSD      0xc1  /*下边*/<BR>#define CROSS       0xc5  /*十字交叉点*/</P>
<P>/*定义棋盘左上角点在屏幕上的位置*/<BR>#define MAPXOFT     5<BR>#define MAPYOFT     2</P>
<P>/*定义1号玩家的操作键键码*/<BR>#define PLAY1UP     0x1157/*上移--'W'*/<BR>#define PLAY1DOWN   0x1f53/*下移--'S'*/<BR>#define PLAY1LEFT   0x1e41/*左移--'A'*/<BR>#define PLAY1RIGHT  0x2044/*右移--'D'*/<BR>#define PLAY1DO     0x3920/*落子--空格键*/</P>
<P>/*定义2号玩家的操作键键码*/<BR>#define PLAY2UP     0x4800/*上移--方向键up*/<BR>#define PLAY2DOWN   0x5000/*下移--方向键down*/<BR>#define PLAY2LEFT   0x4b00/*左移--方向键left*/<BR>#define PLAY2RIGHT  0x4d00/*右移--方向键right*/<BR>#define PLAY2DO     0x1c0d/*落子--回车键Enter*/</P>
<P>/*若想在游戏中途退出, 可按 Esc 键*/<BR>#define ESCAPE      0x011b</P>
<P>/*定义棋盘上交叉点的状态, 即该点有无棋子 */<BR>/*若有棋子, 还应能指出是哪个玩家的棋子   */<BR>#define CHESSNULL   0  /*没有棋子*/<BR>#define CHESS1      'O'/*一号玩家的棋子*/<BR>#define CHESS2      'X'/*二号玩家的棋子*/</P>
<P>/*定义按键类别*/<BR>#define KEYEXIT        0/*退出键*/<BR>#define KEYFALLCHESS   1/*落子键*/<BR>#define KEYMOVECURSOR  2/*光标移动键*/<BR>#define KEYINVALID     3/*无效键*/</P>
<P>/*定义符号常量: 真, 假 --- 真为1, 假为0 */<BR>#define TRUE        1<BR>#define FALSE       0</P>
<P>/**********************************************************/<BR>/* 定义数据结构                                           */</P>
<P>/*棋盘交叉点坐标的数据结构*/<BR>struct point<BR>{<BR>   int x,y;<BR>};</P>
<P>/**********************************************************/<BR>/*自定义函数原型说明                                      */<BR>void Init(void);<BR>int  GetKey(void);<BR>int CheckKey(int press);<BR>int  ChangeOrder(void);<BR>int  ChessGo(int Order,struct point Cursor);<BR>void DoError(void);<BR>void DoOK(void);<BR>void DoWin(int Order);<BR>void MoveCursor(int Order,int press);<BR>void DrawCross(int x,int y);<BR>void DrawMap(void);<BR>int  JudgeWin(int Order,struct point Cursor);<BR>int  JudgeWinLine(int Order,struct point Cursor,int direction);<BR>void ShowOrderMsg(int Order);<BR>void EndGame(void);<BR>/**********************************************************/</P>
<P>/**********************************************************/<BR>/* 定义全局变量                                           */<BR>int  gPlayOrder;         /*指示当前行棋方          */<BR>struct point gCursor;    /*光标在棋盘上的位置      */<BR>char gChessBoard[19][19];/*用于记录棋盘上各点的状态*/<BR>/**********************************************************/</P>
<P>/**********************************************************/<BR>/*主函数*/<BR>void main()<BR>{<BR>  int press;<BR>  int bOutWhile=FALSE;/*退出循环标志*/</P>
<P>  Init();/*初始化图象,数据*/</P>
<P>  while(1)<BR>  {<BR>    press=GetKey();/*获取用户的按键值*/<BR>    switch(CheckKey(press))/*判断按键类别*/<BR>    {<BR>    /*是退出键*/<BR>    case KEYEXIT:<BR>      clrscr();/*清屏*/<BR>      bOutWhile = TRUE;<BR>      break;</P>
<P>    /*是落子键*/<BR>    case KEYFALLCHESS:<BR>      if(ChessGo(gPlayOrder,gCursor)==FALSE)/*走棋*/<BR>        DoError();/*落子错误*/<BR>      else<BR>      {<BR>        DoOK();/*落子正确*/</P>
<P>        /*如果当前行棋方赢棋*/<BR>        if(JudgeWin(gPlayOrder,gCursor)==TRUE)<BR>        {<BR>          DoWin(gPlayOrder);<BR>          bOutWhile = TRUE;/*退出循环标志置为真*/<BR>        }<BR>        /*否则*/<BR>        else<BR>          /*交换行棋方*/<BR>          ChangeOrder();<BR>      }<BR>      break;</P>
<P>    /*是光标移动键*/<BR>    case KEYMOVECURSOR:<BR>      MoveCursor(gPlayOrder,press);<BR>      break;</P>
<P>    /*是无效键*/<BR>    case KEYINVALID:<BR>      break;<BR>    }</P>
<P>    if(bOutWhile==TRUE)<BR>      break;<BR>  }</P>
<P>  /*游戏结束*/<BR>  EndGame();<BR>}<BR>/**********************************************************/</P>
<P>/*界面初始化,数据初始化*/<BR>void Init(void)<BR>{<BR>  int i,j;<BR>  char *Msg[]=<BR>  {<BR>    "Player1 key:",<BR>    "  UP----w",<BR>    "  DOWN--s",<BR>    "  LEFT--a",<BR>    "  RIGHT-d",<BR>    "  DO----space",<BR>    "",<BR>    "Player2 key:",<BR>    "  UP----up",<BR>    "  DOWN--down",<BR>    "  LEFT--left",<BR>    "  RIGHT-right",<BR>    "  DO----ENTER",<BR>    "",<BR>    "exit game:",<BR>    "  ESC",<BR>    NULL,<BR>  };</P>
<P>  /*先手方为1号玩家*/<BR>  gPlayOrder = CHESS1;<BR>  /*棋盘数据清零, 即棋盘上各点开始的时候都没有棋子*/<BR>  for(i=0;i&lt;19;i++)<BR>    for(j=0;j&lt;19;j++)<BR>      gChessBoard[i][j]=CHESSNULL;<BR>  /*光标初始位置*/<BR>  gCursor.x=gCursor.y=0;</P>
<P>  /*画棋盘*/<BR>  textmode(C40);<BR>  DrawMap();</P>
<P>  /*显示操作键说明*/<BR>  i=0;<BR>  textcolor(BROWN);<BR>  while(Msg[i]!=NULL)<BR>  {<BR>    gotoxy(25,3+i);<BR>    cputs(Msg[i]);<BR>    i++;<BR>  }</P>
<P>  /*显示当前行棋方*/<BR>  ShowOrderMsg(gPlayOrder);<BR>  /*光标移至棋盘的左上角点处*/<BR>  gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT);<BR>}</P>
<P>/*画棋盘*/<BR>void DrawMap(void)<BR>{<BR>  int i,j;</P>
<P>  clrscr();</P>
<P>  for(i=0;i&lt;19;i++)<BR>    for(j=0;j&lt;19;j++)<BR>      DrawCross(i,j);</P>
<P>}<BR>/*画棋盘上的交叉点*/<BR>void DrawCross(int x,int y)<BR>{<BR>  gotoxy(x+MAPXOFT,y+MAPYOFT);<BR>  /*交叉点上是一号玩家的棋子*/<BR>  if(gChessBoard[x][y]==CHESS1)<BR>  {<BR>    textcolor(LIGHTBLUE);<BR>    putch(CHESS1);<BR>    return;<BR>  }<BR>  /*交叉点上是二号玩家的棋子*/<BR>  if(gChessBoard[x][y]==CHESS2)<BR>  {<BR>    textcolor(LIGHTBLUE);<BR>    putch(CHESS2);<BR>    return;<BR>  }</P>
<P>  textcolor(GREEN);</P>
<P>  /*左上角交叉点*/<BR>  if(x==0&amp;&amp;y==0)<BR>  {<BR>    putch(CROSSLU);<BR>    return;<BR>  }</P>
<P>  /*左下角交叉点*/<BR>  if(x==0&amp;&amp;y==18)<BR>  {<BR>    putch(CROSSLD);<BR>    return;<BR>  }</P>
<P>  /*右上角交叉点*/<BR>  if(x==18&amp;&amp;y==0)<BR>  {<BR>    putch(CROSSRU);<BR>    return;<BR>  }</P>
<P>  /*右下角交叉点*/<BR>  if(x==18&amp;&amp;y==18)<BR>  {<BR>    putch(CROSSRD);<BR>    return;<BR>  }</P>
<P>  /*左边界交叉点*/<BR>  if(x==0)<BR>  {<BR>    putch(CROSSL);<BR>    return;<BR>  }</P>
<P>  /*右边界交叉点*/<BR>  if(x==18)<BR>  {<BR>    putch(CROSSR);<BR>    return;<BR>  }</P>
<P>  /*上边界交叉点*/<BR>  if(y==0)<BR>  {<BR>    putch(CROSSU);<BR>    return;<BR>  }</P>
<P>  /*下边界交叉点*/<BR>  if(y==18)<BR>  {<BR>    putch(CROSSD);<BR>    return;<BR>  }</P>
<P>  /*棋盘中间的交叉点*/<BR>  putch(CROSS);<BR>}</P>
<P>/*交换行棋方*/<BR>int ChangeOrder(void)<BR>{<BR>  if(gPlayOrder==CHESS1)<BR>    gPlayOrder=CHESS2;<BR>  else<BR>    gPlayOrder=CHESS1;</P>
<P>  return(gPlayOrder);<BR>}</P>
<P>/*获取按键值*/<BR>int GetKey(void)<BR>{<BR>   char lowbyte;<BR>   int press;</P>
<P>   while (bioskey(1) == 0)<BR>      ;/*如果用户没有按键,空循环*/</P>
<P>   press=bioskey(0);<BR>   lowbyte=press&amp;0xff;<BR>   press=press&amp;0xff00 + toupper(lowbyte);<BR>   return(press);<BR>}</P>
<P>/*落子错误处理*/<BR>void DoError(void)<BR>{<BR>   sound(1200);<BR>   delay(50);<BR>   nosound();<BR>}</P>
<P>/*赢棋处理*/<BR>void DoWin(int Order)<BR>{<BR>   sound(1500);delay(100);<BR>   sound(0);   delay(50);<BR>   sound(800); delay(100);<BR>   sound(0);   delay(50);<BR>   sound(1500);delay(100);<BR>   sound(0);   delay(50);<BR>   sound(800); delay(100);<BR>   sound(0);   delay(50);<BR>   nosound();</P>
<P>   textcolor(RED+BLINK);<BR>   gotoxy(25,20);<BR>   if(Order==CHESS1)<BR>     cputs("PLAYER1 WIN!");<BR>   else<BR>     cputs("PLAYER2 WIN!");<BR>   gotoxy(25,21);<BR>   cputs("  <a>\\&lt;^+^&gt;/</A>");<BR>   getch();<BR>}</P>
<P>/*走棋*/<BR>int  ChessGo(int Order,struct point Cursor)<BR>{<BR>   /*判断交叉点上有无棋子*/<BR>   if(gChessBoard[Cursor.x][Cursor.y]==CHESSNULL)<BR>   {<BR>     /*若没有棋子, 则可以落子*/<BR>     gotoxy(Cursor.x+MAPXOFT,Cursor.y+MAPYOFT);<BR>     textcolor(LIGHTBLUE);<BR>     putch(Order);<BR>     gotoxy(Cursor.x+MAPXOFT,Cursor.y+MAPYOFT);<BR>     gChessBoard[Cursor.x][Cursor.y]=Order;<BR>     return TRUE;<BR>   }<BR>   else<BR>     return FALSE;<BR>}</P>
<P>/*判断当前行棋方落子后是否赢棋*/<BR>int  JudgeWin(int Order,struct point Cursor)<BR>{<BR>  int i;<BR>  for(i=0;i&lt;4;i++)<BR>    /*判断在指定方向上是否有连续5个行棋方的棋子*/<BR>    if(JudgeWinLine(Order,Cursor,i))<BR>      return TRUE;<BR>  return FALSE;<BR>}</P>
<P>/*判断在指定方向上是否有连续5个行棋方的棋子*/<BR>int  JudgeWinLine(int Order,struct point Cursor,int direction)<BR>{<BR>   int i;<BR>   struct point pos,dpos;<BR>   const int testnum = 5;<BR>   int count;</P>
<P>   switch(direction)<BR>   {<BR>   case 0:/*在水平方向*/<BR>     pos.x=Cursor.x-(testnum-1);<BR>     pos.y=Cursor.y;<BR>     dpos.x=1;<BR>     dpos.y=0;<BR>     break;<BR>   case 1:/*在垂直方向*/<BR>     pos.x=Cursor.x;<BR>     pos.y=Cursor.y-(testnum-1);<BR>     dpos.x=0;<BR>     dpos.y=1;<BR>     break;<BR>   case 2:/*在左下至右上的斜方向*/<BR>     pos.x=Cursor.x-(testnum-1);<BR>     pos.y=Cursor.y+(testnum-1);<BR>     dpos.x=1;<BR>     dpos.y=-1;<BR>     break;<BR>   case 3:/*在左上至右下的斜方向*/<BR>     pos.x=Cursor.x-(testnum-1);<BR>     pos.y=Cursor.y-(testnum-1);<BR>     dpos.x=1;<BR>     dpos.y=1;<BR>     break;<BR>   }</P>
<P>   count=0;<BR>   for(i=0;i&lt;testnum*2+1;i++)<BR>   {<BR>     if(pos.x&gt;=0&amp;&amp;pos.x&lt;=18&amp;&amp;pos.y&gt;=0&amp;&amp;pos.y&lt;=18)<BR>     {<BR>       if(gChessBoard[pos.x][pos.y]==Order)<BR>       {<BR>             count++;<BR>             if(count&gt;=testnum)<BR>             return TRUE;<BR>       }<BR>       else<BR>         count=0;<BR>     }<BR>     pos.x+=dpos.x;<BR>     pos.y+=dpos.y;<BR>   }</P>
<P>   return FALSE;<BR>}</P>
<P>/*移动光标*/<BR>void MoveCursor(int Order,int press)<BR>{<BR>  switch(press)<BR>  {<BR>  case PLAY1UP:<BR>    if(Order==CHESS1&amp;&amp;gCursor.y&gt;0)<BR>      gCursor.y--;<BR>    break;<BR>  case PLAY1DOWN:<BR>    if(Order==CHESS1&amp;&amp;gCursor.y&lt;18)<BR>      gCursor.y++;<BR>    break;<BR>  case PLAY1LEFT:<BR>    if(Order==CHESS1&amp;&amp;gCursor.x&gt;0)<BR>      gCursor.x--;<BR>    break;<BR>  case PLAY1RIGHT:<BR>    if(Order==CHESS1&amp;&amp;gCursor.x&lt;18)<BR>      gCursor.x++;<BR>    break;</P>
<P>  case PLAY2UP:<BR>    if(Order==CHESS2&amp;&amp;gCursor.y&gt;0)<BR>      gCursor.y--;<BR>    break;<BR>  case PLAY2DOWN:<BR>    if(Order==CHESS2&amp;&amp;gCursor.y&lt;18)<BR>      gCursor.y++;<BR>    break;<BR>  case PLAY2LEFT:<BR>    if(Order==CHESS2&amp;&amp;gCursor.x&gt;0)<BR>      gCursor.x--;<BR>    break;<BR>  case PLAY2RIGHT:<BR>    if(Order==CHESS2&amp;&amp;gCursor.x&lt;18)<BR>      gCursor.x++;<BR>    break;<BR>  }</P>
<P>  gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT);<BR>}</P>
<P>/*游戏结束处理*/<BR>void EndGame(void)<BR>{<BR>   textmode(C80);<BR>}</P>
<P>/*显示当前行棋方*/<BR>void ShowOrderMsg(int Order)<BR>{<BR>  gotoxy(6,MAPYOFT+20);<BR>  textcolor(LIGHTRED);<BR>  if(Order==CHESS1)<BR>     cputs("Player1 go!");<BR>  else<BR>     cputs("Player2 go!");</P>
<P>  gotoxy(gCursor.x+MAPXOFT,gCursor.y+MAPYOFT);<BR>}</P>
<P>/*落子正确处理*/<BR>void DoOK(void)<BR>{<BR>   sound(500);<BR>   delay(70);<BR>   sound(600);<BR>   delay(50);<BR>   sound(1000);<BR>   delay(100);<BR>   nosound();<BR>}</P>
<P>/*检查用户的按键类别*/<BR>int CheckKey(int press)<BR>{<BR>    if(press==ESCAPE)<BR>      return KEYEXIT;/*是退出键*/</P>
<P>    else<BR>    if<BR>    ( ( press==PLAY1DO &amp;&amp; gPlayOrder==CHESS1) ||<BR>      ( press==PLAY2DO &amp;&amp; gPlayOrder==CHESS2)<BR>    )<BR>      return KEYFALLCHESS;/*是落子键*/</P>
<P>    else<BR>    if<BR>    ( press==PLAY1UP   || press==PLAY1DOWN  ||<BR>      press==PLAY1LEFT || press==PLAY1RIGHT ||<BR>      press==PLAY2UP   || press==PLAY2DOWN  ||<BR>      press==PLAY2LEFT || press==PLAY2RIGHT<BR>    )<BR>      return KEYMOVECURSOR;/*是光标移动键*/</P>
<P>    else<BR>      return KEYINVALID;/*按键无效*/<BR>}</P>
<P>帮朋友搜一流图.</P>
<P>帮忙写一N-S流图!!!!!<BR>谢谢了!!!<BR></P>[attach]22031[/attach]<BR>

zinking 发表于 2007-6-7 22:45

<BR><BR>支持一下

viky 发表于 2007-6-13 21:49

[em03][em03]看不明白

boboarts 发表于 2007-6-21 21:11

强悍!<img>

页: [1]

编程论坛