利用C语言实现五子棋游戏

本文实例为大家分享了C语言实现五子棋游戏的具体代码,供大家参考,具体内容如下

一、前言

本文将先介绍五子棋运行所需要的函数,最后串联成完整代码。

我们需要实现的功能有:1.菜单menu函数

2.初始化棋盘Initboard函数

3.显示棋盘Displayboard函数

4.实现人机、人人模式的选择

5.落子函数 playermove computermove

6.判断输赢ifwin函数

先来看看运行效果吧!

二、头文件

#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <string.h>#include<time.h>#include<stdlib.h>#include<windows.h>#define ROW 10  //定义棋盘的宽#define COL 10  //定义棋盘的长                //定义常量方便全局的修改void Initboard(char board[ROW][COL], int row, int col);//初始化棋盘void Displayboard(char board[ROW][COL], int row, int col);//展示棋盘void Playermove_1(char board[ROW][COL], int row, int col,int*px,int *py);//玩家一下棋void Playermove_2(char board[ROW][COL], int row, int col,int*px, int *py);//玩家二下棋void computermove(char board[ROW][COL], int row, int col);//电脑下棋void game1(char board[ROW][COL], int row, int col);//人机模式void game2(char board[ROW][COL], int row, int col);//人人模式int Ifwin(char board[ROW][COL], int row, int col, int x, int y);//判断输赢int check_x(char board[ROW][COL], int row, int col, int x, int y);//判断竖直五子int check_y(char board[ROW][COL], int row, int col, int x, int y);//判断水平五子int check_xy_up(char board[ROW][COL], int row, int col, int x, int y);//判断斜上五子int check_xy_down(char board[ROW][COL], int row, int col, int x, int y);//判断斜下五子

三、menu菜单函数

void menu(){   //完成菜单的初始化 printf("***********************\n"); printf("***********************\n"); printf("*****1.play  0.exit****\n"); printf("***********************\n"); printf("***********************\n"); printf("请输入:");}

很简单,就不多说了

四、初始化棋盘Initboard函数

初始化棋盘,为数组一一存入空格

void Initboard(char board[ROW][COL], int row, int col){ int i = 0; int j = 0; for (i = 0; i < row; i++) {  for (j = 0; j < col; j++)  {   board[i][j] = ' ';  } }}

五、显示棋盘Displayboard函数

打印简单的方格线,并打印数据内容

void Displayboard(char board[ROW][COL], int row, int col){ int i = 0; int j = 0; for (j = 0; j < col; j++)//打印横向y坐标 {  if (j == 0)//考虑到x轴所占的一格  {   printf("  %d  ", j + 1);     }  else  {   printf(" %d  ", j + 1);     } } printf("\n"); for (i = 0; i < row; i++)//打印数据 {   for (j = 0; j < col; j++)  {      if (j == 0)//顺带打印竖向x坐标   {    printf("%2d",i+1);//%md表示域宽为m    printf("  %c ",board[i][j]);       }   else   {    printf(" %c ", board[i][j]);   }      if (j < col - 1)    printf("|");  }  printf("\n");   //打印分割行  if (i < row - 1)  {   for (j = 0; j < col; j++)   {    if (j == 0)//同样考虑到y轴     printf("   ---");    else     printf("---");      if (j < col - 1)     printf("|");    }   printf("\n");   } } }

六、落子函数

玩家一落子——playermove_1

void Playermove_1(char board[ROW][COL], int row, int col, int *px, int*py)//ROW可以省,COL不行{ int x = *px; int y = *py; while (1) {    if (x >= 1 && x <= row && y >= 1 && y <= col)//判断输入坐标的合法性  {   if (board[x -1][y- 1] == ' ')//保证落子点为空   {            board[x-1 ][y -1] = '*';    *px = x; *py = y;//如果开始xy输入不合法,则要对外部xy修改,所以选择传址操作    break;   }   else   {    printf("你不能在此处落子\n");    printf("玩家1落子,请重新输入x y坐标: ");    scanf("%d%d", &x, &y);   }  }  else  {   printf("输入坐标不合法\n");   printf("玩家落子,请重新输入x y坐标: ");   scanf("%d%d", &x, &y);  } } }

玩家2落子完全相同,就不赘叙了

电脑落子

void computermove(char board[ROW][COL], int row, int col){ int x = 0; int y = 0;     //rand函数的使用需要srand函数的初始化,但srand不可以被重复调用,所以放在外部 while (1) {  x = rand() % ROW;  y = rand() % COL;  if (board[x][y] == ' ')//x的范围在0~row-1,所以这里x不用-1了  {   board[x][y] = '#';   break;  } } }

七、判断输赢ifwin

根据我们下五子棋的经验,能获胜的地方必定是最后落子的水平线、竖直线、和两个斜对角线,我们只需对其进行检索即可。ifwin的返回值决定之后的switch语句

弱弱的说一句,虽然看起来多,但很多都是重复的。

int Ifwin(char board[ROW][COL], int row, int col, int x, int y){ int ret; {  ret = check_x(board, row, col, x, y);  if (ret >= 5)   return 0;   ret = check_y(board, row, col, x, y);  if (ret >= 5)   return 0;  ret = check_xy_up(board, row, col, x, y);  if (ret >= 5)   return 0;  ret = check_xy_down(board, row, col, x, y);  if (ret >= 5)   return 0; }   return 3;}  int check_x(char board[ROW][COL], int row, int col, int x, int y)//检查x轴竖直方向{ int sum = 1; int old_x = x; while (x < row  && board[x - 1][y - 1] == board[x][y - 1]) {  sum++;  x++; } x = old_x; while (x-2>= 0 && board[x - 1][y - 1] == board[x - 2][y - 1] ) {  sum++;  x--; } return sum;}  int check_y(char board[ROW][COL], int row, int col, int x, int y)//检查y轴水平方向{ int sum = 1; int old_y = y; while (y<col && board[x-1][y-1] == board[x-1][y]  ) {  sum++;  y++; } y = old_y; while (y-2 >= 0 && board[x-1][y-1] == board[x-1][y -2]  ) {  sum++;  y--; } return sum;}  int check_xy_up(char board[ROW][COL], int row, int col, int x, int y)//检查斜上45度{ int sum = 1; int old_x = x; int old_y = y; while (x<row &&  y - 2 >= 0 && board[x - 1][y - 1] == board[x][y - 2]) {  sum++;  x++;  y--; } x = old_x; y = old_y; while (x - 2 >= 0 && y <col && board[x - 1][y - 1] == board[x - 2][y]) {  sum++;  x--;  y++; } return sum;}  int check_xy_down(char board[ROW][COL], int row, int col, int x, int y)//检查斜下45度{ int sum = 1; int old_x = x; int old_y = y; while (x<row && y <col && board[x - 1][y - 1] == board[x][y]) {  sum++;  x++;  y++; } x = old_x; y = old_y; while (board[x-1][y-1] == board[x -2][y-2 ] && x-2>=0  && y-2 >=0) {  sum++;  x--;  y--; } return sum;}

八、人机、人人模式的选择

初始选择界面

void game(){ int input; char board[ROW][COL] = { 0 }; Initboard(board, ROW, COL); //初始化棋盘 Displayboard(board, ROW, COL); //展示棋盘 printf("请选择模式:1.人机;2.玩家对战\n"); printf("请选择:");   do{  scanf("%d", &input);  printf("\n");  switch (input)  {  case 1:printf("游戏模式1开始!(注意:竖为x轴,横为y轴)\n");  game1(board, ROW, COL); break;  case 2:printf("游戏模式2开始!(注意:竖为x轴,横为y轴)\n"); ; game2(board, ROW, COL); break;  default:printf("请重新输入\n"); break;  } } while (input != 1 && input != 2);//do while语句在输入错误时反复输入}

game1的具体实现

void game1(char board[ROW][COL], int row, int col){ srand((unsigned int)time(NULL));//srand只要设置一次就可以,所以要放在while循环外 while (1) {  int ret;  int count = 0;  int flag = 0;  //判读玩家的下棋  int x; int y;  printf("玩家落子,请依次输入x y坐标: ");  scanf("%d%d", &x, &y);  Playermove_1(board, row, col,&x, &y);  count++;  Displayboard(board, ROW, COL);  if (count == ROW*COL)//全下满则认为平局   ret = 1;  else       ret = Ifwin(board, ROW, COL, x, y);  switch (ret)  {  case 0:printf("玩家获胜\n"); flag = 1; break;  case  1:printf("平局\n"); flag = 1; break;  default: break;  }  if (flag == 1)//用flag跳出while循环   break;    //判断计算机的下棋  computermove(board, row, col);  count++;  Displayboard(board, ROW, COL);  if (count == ROW*COL)   ret = 1;  else   ret = Ifwin(board, ROW, COL, x, y);  switch (ret)  {  case 0:printf("电脑获胜\n"); flag = 1; break;  case  1:printf("平局\n"); flag = 1; break;  default: break;   }  if (flag == 1)   break;  }  }

作者觉得写的是挺啰嗦,欢迎留言建议。game2和game1玩家一的内容很相近,就不赘述

九、作者遇到的坑点

1.输入的坐标和存在数组里的下标有减一的关系,在写的时候不要写忘记了

2.传址操作才能改变函数外的变量值

十、完整的代码

头文件就省了

int main(){ int input; do{  system("cls");//清屏  menu();  scanf("%d", &input);  switch (input)  {  case 1:   printf("游戏开始\n\n");  game(); break;  case 0:   printf("退出游戏\n"); break;  default:   printf("请重新输入\n"); break;  }    Sleep(3000);//暂停3秒 } while (input);//do while语句实现可以反复玩   return 0;}   void menu(){   //完成菜单的初始化 printf("***********************\n"); printf("***********************\n"); printf("*****1.play  0.exit****\n"); printf("***********************\n"); printf("***********************\n"); printf("请输入:");} void Initboard(char board[ROW][COL], int row, int col){ int i = 0; int j = 0; for (i = 0; i < row; i++) {  for (j = 0; j < col; j++)  {   board[i][j] = ' ';  } }}  void Displayboard(char board[ROW][COL], int row, int col){ int i = 0; int j = 0; for (j = 0; j < col; j++)//打印横向y坐标 {  if (j == 0)//考虑到x轴所占的一格  {   printf("  %d  ", j + 1);     }  else  {   printf(" %d  ", j + 1);     } } printf("\n"); for (i = 0; i < row; i++)//打印数据 {   for (j = 0; j < col; j++)  {      if (j == 0)//顺带打印竖向x坐标   {    printf("%2d",i+1);//%md表示域宽为m    printf("  %c ",board[i][j]);       }   else   {    printf(" %c ", board[i][j]);   }   //数字表示坐标   if (j < col - 1)    printf("|");  }  printf("\n");  //打印分割行  if (i < row - 1)  {   for (j = 0; j < col; j++)   {    if (j == 0)//同样考虑到y轴     printf("   ---");    else     printf("---");      if (j < col - 1)     printf("|");    }   printf("\n");//别忘记这里也要换行   } } }   void game(){ int input; char board[ROW][COL] = { 0 }; Initboard(board, ROW, COL); //初始化棋盘 Displayboard(board, ROW, COL); //展示棋盘 printf("请选择模式:1.人机;2.玩家对战\n"); printf("请选择:");   do{  scanf("%d", &input);  printf("\n");  switch (input)  {  case 1:printf("游戏模式1开始!(注意:竖为x轴,横为y轴)\n");  game1(board, ROW, COL); break;  case 2:printf("游戏模式2开始!(注意:竖为x轴,横为y轴)\n"); ; game2(board, ROW, COL); break;  default:printf("请重新输入\n"); break;  } } while (input != 1 && input != 2);//do while语句在输入错误时反复输入} void game1(char board[ROW][COL], int row, int col){ srand((unsigned int)time(NULL));//srand只要设置一次就可以,所以要放在while循环外 while (1) {  int ret;  int count = 0;  int flag = 0;  //判读玩家的下棋  int x; int y;  printf("玩家落子,请依次输入x y坐标: ");  scanf("%d%d", &x, &y);  Playermove_1(board, row, col,&x, &y);  count++;  Displayboard(board, ROW, COL);  if (count == ROW*COL)//全下满则认为平局   ret = 1;  else       ret = Ifwin(board, ROW, COL, x, y);  switch (ret)  {  case 0:printf("玩家获胜\n"); flag = 1; break;  case  1:printf("平局\n"); flag = 1; break;  default: break;  }  if (flag == 1)//用flag跳出while循环   break;    //判断计算机的下棋  computermove(board, row, col);  count++;  Displayboard(board, ROW, COL);  if (count == ROW*COL)   ret = 1;  else   ret = Ifwin(board, ROW, COL, x, y);  switch (ret)  {  case 0:printf("电脑获胜\n"); flag = 1; break;  case  1:printf("平局\n"); flag = 1; break;  default: break;   }  if (flag == 1)   break;  }  }  void game2(char board[ROW][COL], int row, int col){ while (1) {  int ret;  int count = 0;  int flag = 0;  int x; int y;  //判读玩家1的下棋  printf("玩家1落子,请输入坐标:(注意:竖为x轴,横为y轴)");  scanf("%d%d", &x, &y);  Playermove_1(board, row, col, &x, &y);  count++;  Displayboard(board, ROW, COL);  if (count == ROW*COL)   ret = 1;  else   ret = Ifwin(board, ROW, COL, x, y);  switch (ret)  {  case 0:printf("玩家1获胜\n"); flag = 1; break;  case  1:printf("平局\n"); flag = 1; break;  default: break;  }  if (flag == 1)   break;    //判断玩家2的下棋  printf("玩家2落子,请输入坐标:(注意:竖为x轴,横为y轴)");  scanf("%d%d", &x, &y);  Playermove_2(board, row, col, &x, &y);  count++;  Displayboard(board, ROW, COL);  if (count == ROW*COL)   ret = 1;  else   ret = Ifwin(board, ROW, COL, x, y);  switch (ret)  {  case 0:printf("玩家2获胜\n"); flag = 1; break;  case  1:printf("平局\n"); flag = 1; break;  default: break;  }  if (flag == 1)   break;   }  } void Playermove_1(char board[ROW][COL], int row, int col, int *px, int*py)//ROW可以省,COL不行{ int x = *px; int y = *py; while (1) {    if (x >= 1 && x <= row && y >= 1 && y <= col)//判断输入坐标的合法性  {   if (board[x -1][y- 1] == ' ')//保证落子点为空   {            board[x-1 ][y -1] = '*';    *px = x; *py = y;//如果开始xy输入不合法,要对外部xy修改,所以要传址操作    break;   }   else   {    printf("你不能在此处落子\n");    printf("玩家1落子,请重新输入x y坐标: ");    scanf("%d%d", &x, &y);   }  }  else  {   printf("输入坐标不合法\n");   printf("玩家落子,请重新输入x y坐标: ");   scanf("%d%d", &x, &y);  } } }  void Playermove_2(char board[ROW][COL], int row, int col, int *px, int*py){ int x = *px; int y = *py; while (1) {    if (x >= 1 && x <= row && y >= 1 && y <= col)//判断输入坐标的合法性  {   if (board[x - 1][y - 1] == ' ')//保证落子点为空   {    board[x - 1][y - 1] = '#';    *px = x; *py = y;    break;   }   else   {    printf("你不能在此处落子\n");    printf("玩家2落子,请重新输入x y坐标: ");    scanf("%d%d", &x, &y);   }  }  else  {   printf("输入坐标不合法\n");   printf("玩家落子,请重新输入x y坐标: ");   scanf("%d%d", &x, &y);  } } }  void computermove(char board[ROW][COL], int row, int col){ int x = 0; int y = 0;   while (1) {  x = rand() % ROW;  y = rand() % COL;  if (board[x][y] == ' ')  {   board[x][y] = '#';   break;  } } } int Ifwin(char board[ROW][COL], int row, int col, int x, int y){ int ret; {  ret = check_x(board, row, col, x, y);  if (ret >= 5)   return 0;   ret = check_y(board, row, col, x, y);  if (ret >= 5)   return 0;  ret = check_xy_up(board, row, col, x, y);  if (ret >= 5)   return 0;  ret = check_xy_down(board, row, col, x, y);  if (ret >= 5)   return 0; }   return 3;} int check_x(char board[ROW][COL], int row, int col, int x, int y)//检查x轴竖直方向{ int sum = 1; int old_x = x; while (x < row  && board[x - 1][y - 1] == board[x][y - 1]) {  sum++;  x++; } x = old_x; while (x-2>= 0 && board[x - 1][y - 1] == board[x - 2][y - 1] ) {  sum++;  x--; } return sum;} int check_y(char board[ROW][COL], int row, int col, int x, int y)//检查y轴水平方向{ int sum = 1; int old_y = y; while (y<col && board[x-1][y-1] == board[x-1][y]  ) {  sum++;  y++; } y = old_y; while (y-2 >= 0 && board[x-1][y-1] == board[x-1][y -2]  ) {  sum++;  y--; } return sum;}   int check_xy_up(char board[ROW][COL], int row, int col, int x, int y)//检查斜上45度{ int sum = 1; int old_x = x; int old_y = y; while (x<row &&  y - 2 >= 0 && board[x - 1][y - 1] == board[x][y - 2]) {  sum++;  x++;  y--; } x = old_x; y = old_y; while (x - 2 >= 0 && y <col && board[x - 1][y - 1] == board[x - 2][y]) {  sum++;  x--;  y++; } return sum;}   int check_xy_down(char board[ROW][COL], int row, int col, int x, int y)//检查斜下45度{ int sum = 1; int old_x = x; int old_y = y; while (x<row && y <col && board[x - 1][y - 1] == board[x][y]) {  sum++;  x++;  y++; } x = old_x; y = old_y; while (board[x-1][y-1] == board[x -2][y-2 ] && x-2>=0  && y-2 >=0) {  sum++;  x--;  y--; } return sum;}

如果对你有帮助和启发,作者感到很高兴。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

把艰辛的劳作看作是生命的必然,

利用C语言实现五子棋游戏

相关文章:

你感兴趣的文章:

标签云: