2019C语言课程设计

八,五子棋游戏
程序应用C语言编写程序,可以在计算机上实现二人对弈五子棋功能。
功能要求:
(1)欢迎界面生成、游戏界面生成;
(2)光标移动和落子显示;
(3)判断胜负、悔棋功能,提供音效;
(4)综合应用结构体、数组、按键处理和图形编程等编程方法。

#include <stdio.h> 
#include<windows.h> 
#include <stdlib.h> 
#include<conio.h> 
int s;
int winner;
int player;
int Q[200][200] = { 0 };
char button;
struct Point
{
 int x;
 int y;
} point, game;
struct Pieces
{
 struct Point coord;
 struct Pieces *fore;
};
struct Pieces *p, *ptr, *ptr1, *head;
void goto_xy(int x, int);
void init();
void welcome();
void showwho();
void draw();
void clean();
void menu(char press);
void go_back(int x1, int y1);
void record();
void putdown();
void play(char ch);
int judge();
int main();
void goto_xy(int x, int y)          //光标移动函数 
{
 COORD c;
 c.X = 2 * x;
 c.Y = y;
 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
 //使光标 到(x,y)位置的函数//调用 COORD 需要#include<windows.h>.
}
void init()//初始化函数,将记录棋子的数组初始化 
{
 for (int i = 0; i < 200; i++)
  for (int j = 0; j < 200; j++)
   Q[i][j] = 0;
 s = 0;
 player = 1;
 p = (struct Pieces *)malloc(sizeof(struct Pieces)); 
 //  动态声明了一个pieces结构体的内存空间, 并将这块空间的指针保存给p变量                                                                    
 head = p;
}
void welcome()
{
 system("color 2F");
 goto_xy(17, 1);
 printf("\n\t\t*****************欢迎来到五子棋小游戏******************\n");
 goto_xy(13, 3);
 printf("\n\t\t\t********主菜单***********\n");
 goto_xy(13, 4);
 printf("\n\t\t\t\t***人人对战***\n");
 printf("\n\t\t\t\t\t退出");
 point.x = 12;
 point.y = 3;
 goto_xy(0, 0);
}
void showwho()
{
 goto_xy(17, 22);
 if (player == 0)
  printf("轮到甲方落子");
 else
  printf("轮到乙方落子");
 goto_xy(point.x, point.y);
}
void draw()
{
 game.x = 10;
 game.y = 3;
 system("cls");
 system("color 3F");
 goto_xy(15, 1);
 printf("欢迎进入五子棋小游戏!!\n");
 goto_xy(29, 22);
 printf("重新开始请输入r\n");
 goto_xy(1, 22);
 printf("悔棋请输入b\n");
 goto_xy(1, 23);
 printf("退出请按ESC\n");
 const int i = 8;    //const 定义的数据不可以被改变 而且修改数据比较方便     
 const int j = 19;
 const int k = 3;
 goto_xy(game.x - i, game.y + k);  //甲光标的初始化位置
 printf("甲方:●\n");
 goto_xy(game.x - i, game.y + k + 2);
 printf("向上移动:↑\n");
 goto_xy(game.x - i, game.y + k + 4);
 printf("向下移动:↓\n");
 goto_xy(game.x - i, game.y + k + 6);
 printf("向左移动:←\n");
 goto_xy(game.x - i, game.y + k + 8);
 printf("向右移动:→\n");
 goto_xy(game.x - i, game.y + k + 10);
 printf("落子: Enter\n");
 goto_xy(game.x + j, game.y + k);
 printf("乙方:○\n");
 goto_xy(game.x + j, game.y + k + 2);
 printf("向上移动:↑\n");
 goto_xy(game.x + j, game.y + k + 4);
 printf("向下移动:↓\n");
 goto_xy(game.x + j, game.y + k + 6);
 printf("向左移动:←\n");
 goto_xy(game.x + j, game.y + k + 8);
 printf("向右移动:→\n");
 goto_xy(game.x + j, game.y + k + 10);
 printf("落子: Enter\n");
 for (int k1 = 0; k1 < 200; k1++)     
  //初始化棋子记录,在第二局时有明确的作用         
  for (int k2 = 0; k2 < 200; k2++)
   Q[k1][k2] = 0;
 for (int i = 0; i < 18; i++)
 {
  if (i == 0)
  {
   goto_xy(10, i + 3);
   printf("┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐");
  }
  if (i != 0 && i != 17)
  {
   goto_xy(10, i + 3);
   printf("├┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┤");
  }
  if (i == 17)
  {
   goto_xy(10, i + 3);
   printf("└┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┘");
  }
 }
 point.x = 19;
 point.y = 12;
 goto_xy(19, 12);
}
void clean()
{
 goto_xy(10, 3);
 printf(" ");
 goto_xy(24, 3);
 printf(" ");
 goto_xy(10, 4);
 printf(" ");
 goto_xy(24, 4);
 printf(" ");
}
void menu(char press)
{
 if (press == 72)    //↑的ASCLL码     
 {
  if (point.y == 3)
   point.y = 4;
  else
   point.y = 3;
  clean();
  goto_xy(10, point.y);
  printf("—→");
 }
 if (press == 80)   //↓的ASCLL码     
 {
  if (point.y == 4)
   point.y = 3;
  else
   point.y = 4;
  clean();
  goto_xy(10, point.y);
  printf("—→");
 }
 if (press == 13)  // 13:回车键的ASCLL码     
 {
  s = point.y - 2;    //s 为1或2    
 }
}
void go_back(int x1, int y1)     //悔棋函数 
{
 goto_xy(x1, y1);
 if (x1 == 10)
 {
  if (y1 == 3)
  {
   printf("┌");
  }
  else
   if (y1 == 20)
   {
    printf("└");
   }
   else
   {
    printf("├");
   }
 }
 else if (x1 == 27)
 {
  if (y1 == 3)
  {
   printf("┐");
  }
  else
   if (y1 == 20)
   {
    printf("┘");
   }
   else
   {
    printf("┤");
   }
 }
 else
 {
  if (y1 == 3)
  {
   printf("┬");
  }
  else
   if (y1 == 20)
   {
    printf("┴");
   }
   else
   {
    printf("┼");
   }
 }
 Q[point.x][point.y] = 0;
 goto_xy(x1, y1);
}
void record()    //记录棋子的情况 
{
 p->coord.x = point.x;
 p->coord.y = point.y;
 ptr = p;
 p = (struct Pieces *)malloc(sizeof(struct Pieces));
 p->fore = ptr;
 showwho();
 Q[point.x][point.y] = player + 1;
 if (player)
 {
  player = 0;
  return;
 }
 player = 1;
 goto_xy(point.x, point.y);
}
void putdown()
{
 if (Q[point.x][point.y] == 0)    //先判断该位置是否有棋子    
 {
  if (player)
  {
   printf("●");
   printf("\a");     //'\a'表示蜂鸣声             
   record();
  }
  else
  {
   printf("○");
   printf("\a");
   record();
  }
  goto_xy(point.x, point.y);
 }
}
void play(char ch)
{
 if (ch == 72)
 {
  if (point.y <= 3)
   point.y = 20;
  else
   point.y--;
  goto_xy(point.x, point.y);
 }
 if (ch == 75)      //←的ASCLL码    光标左移     
 {
  if (point.x <= 10)
   point.x = 27;
  else
   point.x--;
  goto_xy(point.x, point.y);
 }
 if (ch == 77)      //→的ASCLL码  光标右移     
 {
  if (point.x >= 27)
   point.x = 10;
  else
   point.x++;
  goto_xy(point.x, point.y);
 }
 if (ch == 80)      //↓的ASCLL码   光标下移    
 {
  if (point.y >= 20)
   point.y = 3;
  else
   point.y++;
  goto_xy(point.x, point.y);
 }
 if (ch == 13)    //回车键的ASCLL码  下棋     
 {
  putdown();
 }
 if (button == 'b' || button == 'B')       //悔棋的操作    
 {
  ptr1 = p;
  if (p != head)
  {
   p = p->fore;
   free(ptr1);
   point.x = p->coord.x;
   point.y = p->coord.y;
   go_back(point.x, point.y);
  }
 }
}
int judge()
{
 int count = 0;
 int pp = player == 0 ? 2 : 1;
 int c = 0;
 int r = 0;
 int rr = r;
 int cc = c;
 for (c = 0; c < 200; c++)
 {
  for (r = 0; r < 200; r++)
  {
   if (Q[r][c] != pp)
    continue;
   while (--cc >= 3 && Q[rr][cc] == pp)
    count++;
   cc = c;
   while (++cc < 23 && Q[rr][cc] == pp)
    count++;
   cc = c;
   if (count >= 4)
    return pp;
   count = 0;
   while (--rr >= 10 && Q[rr][cc] == pp)
    count++;
   rr = r;
   while (++rr < 30 && Q[rr][cc] == pp)
    count++;
   rr = r;
   if (count >= 4)
    return pp;
   count = 0;
   cc--;
   rr--;
   while ((cc >= 3 || rr >= 10) && Q[rr][cc] == pp)
   {
    count++;
    cc--;
    rr--;
   }
   rr = r;
   cc = c;
   cc++;
   rr++;
   while ((cc < 23 || rr < 30) && Q[rr][cc] == pp)
   {
    count++;
    cc++;
    rr++;
   }
   rr = r;
   cc = c;
   if (count + 1 >= 5)
    return pp;
   count = 0;
   cc++;
   rr--;
   while ((cc < 23 || rr >= 10) && Q[rr][cc] == pp)
   {
    count++;
    cc++;
    rr--;
   }
   rr = r;
   cc = c;
   cc--;
   rr++;
   while ((cc >= 3 || rr < 30) && Q[rr][cc] == pp)
   {
    count++;
    cc--;
    rr++;
   }
   rr = r;
   cc = c;
   if (count + 1 >= 5)
    return pp;
   count = 0;
  }
 }     return 0;
}
int main(void)
{
 system("color 4E");
 printf("\n欢迎来到五子棋小游戏\n");
 welcome();
 Sleep(3000);
 system("cls");
 while (1)
 {
  init();
  int winner = 0;
  welcome();
  while (1)     //读取菜单选项         
  {
   char choice = getch();
   menu(choice);
   if (s != 0)
    break;
  }
  if (s == 1)    //选择人人对战        
  {
   draw();
   goto_xy(17, 22);
   printf("轮到甲方落子");
   goto_xy(point.x, point.y);
   while (1)
   {
    button = getch();
    play(button);
    if (button == 27)   //ESC的ASCLL码                
    {
     if (MessageBox(NULL, TEXT("确定退出?"), TEXT(""), MB_ICONQUESTION | MB_OKCANCEL) == IDOK)
     {
      system("cls");
      printf("\n    谢谢使用!\n");
      return 0;
     }
    }
    if (button == 13)    //回车键ASCLL码  开始判断输赢                    
     winner = judge();
    if (winner != 0)
    {
     goto_xy(15, 24);
     if (winner == 2)
     {
      printf("恭喜!甲方赢!\n");
     }
     if (winner == 1)
     {
      printf("恭喜!乙方赢!\n");
     }
    }
    if (winner != 1 && winner != 2)
    {
     continue;
    }
    goto_xy(13, 22);
    printf("   继续游戏?(Y/N):    ");
    while (1)
    {
     button = getch();
     if (button == 'n' || button == 'N' || button == 'y' || button == 'Y')
      break;
    }
    if (button == 'n' || button == 'N')
    {
     if (MessageBox(NULL, TEXT("  确定退出"), TEXT(""), MB_ICONQUESTION | MB_OKCANCEL) == IDOK)
     {
      system("cls");
      printf("\n    谢谢使用!\n");
      return 0;
     }
    }
    if (button == 'y' || button == 'Y')
    {
     winner = 0;
     system("cls");
     break;
    }
   }
  }
  if (s == 2)
  {
   if (MessageBox(NULL, TEXT("  确定"), TEXT(""), MB_ICONQUESTION | MB_OKCANCEL) == IDOK)
   {
    printf("\n\n    谢谢使用!\n");
    return 0;
   }
  }
 }
 return 0;
}

不足之处,请多指教!!

目录 摘 要..............................................................1 1设计内容、任务及具体要求.........................................2 1.1设计内容.....................................................2 1.2设计任务及具体要求...........................................2 2概要设计.........................................................3 2.1该系统的功能简介.............................................3 2.2 总体程序框图.................................................3 2.3各个模块之间的主要关系........................................4 3系统功能模块的具体设计............................................5 3.1各个模块的程序流程图及运行界面................................5 3.2对关键代码加以分析说明.......................................15 4程序调试分析.....................................................23 5程序使用说明.....................................................24 6总结.............................................................25 致谢...........................................................26 参考文献...........................................................27 附:源程序..........................................................28 摘 要 工资管理系统是针对企业的工资管理业务进行计算机处理而开发的应用软件。该系统由系统维护、输入、查询、修改、输出、统计等子模块组成,功能基本涵盖普通企业的工资管理业务范围。企业应用本系统后,可以有效的提高工资管理水平。本文从需求分析、开发平台选择、系统模块建立、数据库设计、功能模块编程实现及软件测试等方面阐述了本应用系统的设计过程。为便于说明,文中绘制了程序结构框图、数据流程图和部分界面图。最后附有主要的源程序代码清单。 关键词:工资管理 系统维护 数据汇总 管理系统 软件开发
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值