利用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;
}

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

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

(0)

相关推荐

  • C语言实现五子棋游戏

    本文实例为大家分享了C语言实现五子棋的具体代码,供大家参考,具体内容如下 #include <stdio.h> #include <bios.h> #include <ctype.h> #include <conio.h> #include <dos.h> #define CROSSRU 0xbf /*右上角点*/ #define CROSSLU 0xda /*左上角点*/ #define CROSSLD 0xc0 /*左下角点*/ #defin

  • C语言实现五子棋人人对战

    利用简单的c语言基础实现最简单的功能,界面比较丑陋主要是刚学完c的一个小实践,未使用MFC所以界面没有很好看 ,主要目的加强对c语言的理解与运用,同时增加自己的代码量. 首先要学一些头文件可以看我的博客前面的文章 要用到到的头文件stdio.h stdlib.h windows.h time.h conio.h 思路就是 1.画个棋盘,使用数组来代替初始化出* 2.使用循环使双方轮流下棋,使用数组存放棋子的位置 3.判断是否有一方获胜 首先打印棋盘 #include<stdio.h> #inc

  • C语言实现简易五子棋

    本文实例为大家分享了C语言实现简易五子棋的具体代码,供大家参考,具体内容如下 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<time.h> #define ROW 5 #define COL 5 char g_broad[ROW][COL]; void menu(); void menu() { printf("--------------------

  • C语言实现简单五子棋小游戏

    五子棋简单功能实现,供大家参考,具体内容如下 游戏功能演示 代码如下: #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <getch.h> // 棋盘 char board[15][15]; // 棋子坐标 char kx = 7 , ky = 7; // 角色 char role = '@'; // 显示棋盘 void show_board(void) { syste

  • 纯C语言实现五子棋

    正在考虑增加一个MFC界面.不是人机对战的. 五子棋.c //date 2014年7月7日09:53:24 //willows //五子棋 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <assert.h> //棋盘初始化函数 //Chessboard棋盘数组,ln=棋盘大小,成功返回Chessboard,不成功NULL void init_Chessboa

  • C语言编写五子棋游戏

    本文实例为大家分享了C语言编写五子棋游戏的具体代码,供大家参考,具体内容如下 一.构建棋盘 首先可以用一个二维数组来构建棋盘,下标表示位置,内容表示黑子白子或者空位.当数组内容为1时,该位置为白字,当数组为0时,该位置为白子,空位输出+ int w[11][11], flag = 0; int a, b; for (int k = 0; k < 11; k++) printf("第%d列\t", k); printf("\n"); for (int i = 0

  • 基于C语言实现五子棋游戏

    采用二维数组制作五子棋,用坐标下棋. 请看代码. include<stdio.h> #include<string.h> #include<stdlib.h> #include<windows.h> #include<conio.h> #include<time.h> void menu()//目录 { char xuanze = 0,xuanze2; printf("\n"); printf("\n&q

  • C语言实现五子棋小游戏

    首先我们先来看一个稍微简单些的实现方式: #include <stdio.h> #include <stdlib.h> #define N 15 int chessboard[N + 1][N + 1] = { 0 }; int whoseTurn = 0; void initGame(void); void printChessboard(void); void playChess(void); int judge(int, int); int main(void) { init

  • C语言实现简易五子棋小游戏

    本文实例为大家分享了C语言实现简单五子棋小游戏的具体代码,供大家参考,具体内容如下 效果图如下: 设计思路: 棋盘设计为15×15格,初始状态光标在棋盘的中央,白棋先走,轮流落子,当一方连成五子或下满棋盘时,游戏结束(连成五子的一方获胜,下满棋盘为和棋).当游戏一方胜利后显示胜利信息,提示信息利用汉字点阵输出.程序游戏是一个二维平面图,可用二维数组来实现,数组两个下标可以表示棋盘上的位置,数组元素的值代表棋格上的状态,共有三种情况,分别是0代表空格,1代表白棋,2代表黑棋.程序的主要工作是接收棋

  • 基于C语言实现五子棋游戏完整实例代码

    本文实例讲述了基于C语言实现五子棋游戏的方法,代码备有比较完整的注释,可以帮助读者更好的加以理解. 五子棋游戏代码如下: /* * 使用键盘的上下左右键移动棋盘,空格键表示下棋,ESC键退出程序 */ #include <stdio.h> #include <stdlib.h> #include <bios.h> #include <graphics.h> #include<malloc.h> /* * 对应键盘键的十六进制数字 */ #defi

随机推荐