三子棋游戏程序编写(C语言版)

简介: ●通过对三子棋的程序编写,实现对数组等知识点的应用与理解。●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教!

前言:

●通过对三子棋的程序编写,实现对数组等知识点的应用与理解。

●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教!

正文:

说明:本代码编译环境为Visual Studio2019,其中出现特定为该编译器设定的代码语句:#define  _CRT_SECURE_NO_WARNINGS

此代码语句的功能:为了解决Visual Studio编译环境的一些库函数等报错或警告问题

注:代码语句只在Visual Studio编译环境使用,其他编译器需屏蔽此代码语句

 

1.创建头文件:game.h  

代码如下:

#define ROW 3 //行
#define COL 3 //列
  //转向test.c修改数组定义,将[3][3]修改为[ROW][COL]
#include <stdio.h>
#include<stdlib.h>
#include<time.h>
void InitBoard(char board[ROW][COL], int row,int col);  //对应接收test.c中的Initboard(...) ,这里row,col小写等会调试
   //转到game.c 实现
void DisplayBoard(char board[ROW][COL], int row, int col);
void PlayerMove(char board[ROW][COL], int row, int col);
void ComputerMove(char board[ROW][COL], int row, int col);
//告知我们四种游戏状态
//玩家赢 - '*’
//电脑赢 - '#'
//平局 - 'Q'
//继续 - 'C'
char IsWin(char board[ROW][COL], int row, int col);

image.gif

2.创建源文件:  game.c

代码如下:

#define  _CRT_SECURE_NO_WARNINGS
#include "game.h"
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] = ' ';
    }
  }
}
//这时每个元素均初始化,转到test.c
void DisplayBoard(char board[ROW][COL], int row, int col)
{
  int i = 0;
  for (i = 0; i < row; i++)
  {
    //1.打印一行的数据
    //printf(" %c | %c | %c \n",board[i][0],board[i][1],board[i][2]);
    //改为如下
    int j = 0;
    for (j = 0; j < col; j++)
    {
      //1.打印一行的数据
      printf(" %c ", board[i][j]);
      if (j < col - 1)  //控制是否打印最后一列
        printf("|");
    }
    printf("\n");
    //2.打印分割行
    if (i < row - 1)   //控制是否打印最后一行
    {
      //printf("---|---|---\n");
      for (j = 0; j < col; j++)
      {
        printf("---");
        if (j < col - 1)   //控制是否打印最后一列
          printf("|");
      }
      printf("\n");
    }
    //printf("---|---|---\n");
  }
}
void PlayerMove(char board[ROW][COL], int row, int col)
{
  int x = 0;
  int y = 0;
  printf("请玩家置入棋子:>\n");
  while (1)
  {
    printf("请玩家输入坐标:>");
    scanf("%d%d", &x, &y);
    //判断x,y坐标的合法性
    if (x >= 1 && x <= row && y >= 1 && y <= col)  //玩家可能不理解数组从0开始,而认为从1开始
    {
      if (board[x - 1][y - 1] == ' ')
      {
        board[x - 1][y - 1] = '*';
        break;
      }
      else
      {
        printf("该坐标被占用,请重新输入!\n");
      }
    }
    else
    {
      printf("输入坐标非法,请重新输入!\n");
    }
  }
}
void ComputerMove(char board[ROW][COL], int row, int col)
{
  int x = 0;
  int y = 0;
  printf("请电脑置入棋子:>\n");
  while (1)
  {
    x = rand() % row;
    y = rand() % col;
    if (board[x][y] == ' ')
    {
      board[x][y] = '#';
      break;
    }
  }
}
//返回1表示棋盘满了
//返回0表示棋盘没满
int IsFull(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++)
    {
      if (board[i][j] == ' ')
      {
        return 0; //没满
      }
    }
  }
  return 1; //满了
}
char IsWin(char board[ROW][COL], int row, int col)
{
  int i = 0;
  //横三行
  for (i = 0; i < row; i++)
  {
    if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')
    {
      return board[i][1]; //[i][0]   //[i][2]均可以
    }
  }
  //竖三列
  for (i = 0; i < col; i++)
  {
    if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
    {
      return board[1][i];
    }
  }
  //两个对角线
  if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
  {
    return board[1][1];
  }
  if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ')
  {
    return board[1][1];
  }
  //判断是否平局
  if (1 == IsFull(board, ROW, COL))
  {
    return 'Q';
  }
  return 'C';
}

image.gif

3.创建源文件: test.c

代码如下:

//测试三子棋游戏
#define  _CRT_SECURE_NO_WARNINGS   //此语句为使用VS2019编译环境特定,其他编译器可屏蔽此语句
 //步骤一   test.c步骤    //#include <stdio.h>     
//void menu()
//{
//  printf("***********************\n");
//  printf("****1.play   0.exit****\n");
//  printf("***********************\n");
//}
//void test()
//{
//  int input = 0;  //最初赋个随机值
//  do
//  {
//    menu(); //菜单
//    printf("请选择:>");
//    scanf("%d", &input);
//    switch (input)
//    {
//    case 1:
//      printf("三子棋\n");
//      break;
//    case 0:
//      printf("退出游戏\n");
//      break;
//    defult:   //选择的不是1也不是0
//      printf("选择错误,请重新选择!\n");
//      break;
//    }
//  }
//  while (input);    //判断选择要为真  0为假,1或defult为真(!0)
//}
//int main()
//{
//  test();
//  return 0;
//}
//步骤二  创建void game()及棋盘
#include <stdio.h>
#include "game.h"    //这时可使用game.h中定义的行列
void menu()
{
  printf("三子棋游戏\n");
  printf("***********************\n");
  printf("****1.Play   0.Exit****\n");
  printf("***********************\n");
  printf("//输入坐标方式为;行(输入数字)-空格键-列(输入数字)//\n");
}
//游戏的整个算法实现
void game()    
{ 
  char ret = 0;
  //创建数组,存放走出的棋盘信息
  char board[ROW][COL] = { 0 };   //char board[3][3] = { 0 };//将[3][3]修改为[ROW][COL]
    //再引用自定义头文件"game.h"
  //初始化棋盘
  InitBoard(board,ROW,COL); //再转到game.h定义
  //这时打印棋盘
  DisplayBoard(board,ROW,COL); //再分装打印棋盘的函数
  //下棋
  while (1)
  {
    //玩家下棋
    PlayerMove(board,ROW,COL);
    DisplayBoard(board, ROW, COL);
    //判断玩家是否赢棋
    ret=IsWin(board,ROW,COL);
    if (ret != 'C')
    {
      break;
    }
    //电脑下棋
    ComputerMove(board, ROW, COL);
    DisplayBoard(board, ROW, COL);
    //判断电脑是否赢棋
    ret=IsWin(board, ROW, COL);
    if (ret != 'C')
    {
      break;
    }
  }
  if (ret == '*')
  {
    printf("玩家获胜!\n请选择是否进行下一局!\n");
  }
  else if (ret == '#')
  {
    printf("电脑获胜!\n请选择是否进行下一局!\n");
  }
  else
  {
    printf("平局!\n请选择是否进行下一局!\n");
  }
}
void test()
{
  int input = 0;
  srand((unsigned int)time(NULL));
  do
  {
    menu();
    printf("请选择<Play>(输入1)或<Exit>(输入0):>");
    scanf("%d", &input);
    switch (input)
    {
    case 1:
      game();
      break;
    case 0:
      printf("退出游戏!\n");
      break;
    defult:
      printf("选择错误,请重新选择!\n");
      break;
    }
  } while (input);
}
int main()
{
  test();
  return 0;
}

image.gif

4.按照提示运行程序即可

运行示例:

image.gif编辑

image.gif编辑

image.gif编辑

总结:

作为作者编写的第一个游戏程序,夹杂着喜悦与辛酸!作为一名学习编程新手,作者目前水平有限,只会照葫芦画瓢,其中蕴含的知识极为深邃,而作者只领略一二!虽然仅是照葫芦画瓢的编入编译器,但调试环节确实让作者学会了许多知识!

调试过程中,作者几次都以为将要失败,但坚持经历了多次调试与请教后,终于使得这个第一次编写的游戏程序成功运行!这是一件极为让人喜悦的事!

囿于某些原因,本文有许多不详细,不足之处,其中许多知识仍需作者反复学习与理解,希望在以后的时光里,作者能够和读者一道共同成长!

此处,致敬第一个写出三子棋游戏代码的开发者。

                                                                                            ——By 新晓•故知

相关文章
|
1天前
|
前端开发 C语言 C++
C语言03----第一个程序HelloWorld(vs版)
C语言03----第一个程序HelloWorld(vs版)
|
2天前
|
存储 数据管理 C语言
C语言实战 | 使用链表完成“贪吃蛇”游戏
【7月更文挑战第1天】整体思维,即系统思维,强调以整体视角理解事物。在编程中,结构体体现这种思想,将相关变量打包处理。示例展示了如何用链表而非数组实现“贪吃蛇”游戏,链表提供了更灵活的动态数据管理。一系列代码图片详细描绘了链表结构体在游戏中的应用,包括节点定义、移动、碰撞检测等,凸显了使用链表的优势和代码的清晰组织。
12 0
C语言实战 | 使用链表完成“贪吃蛇”游戏
|
7天前
|
存储 C语言
C语言实战 | “贪吃蛇”游戏重构
在程序设计中,模块化思维至关重要,尤其对于复杂项目,它帮助分解任务,便于团队协作。以“贪吃蛇”游戏为例,游戏涉及两个角色:蛇和食物。使用数组存储蛇的位置,变量存储食物位置。游戏流程分为初始化、显示和更新数据。初始化时,食物位置随机,蛇的位置根据数组设定。显示数据则根据这些信息在屏幕上呈现角色。更新数据时,处理蛇的移动和增长以及食物的生成和消失。类似地,通过模块化方法可开发“打砖块”游戏,涉及球、球拍和砖墙,每个角色都有相应数据结构和更新逻辑。通过这种方式,游戏开发就像搭建积木,遵循框架逐步实现。
19 0
C语言实战 | “贪吃蛇”游戏重构
|
7天前
|
C语言
C语言实现猜数字游戏:代码详解与函数解析
C语言实现猜数字游戏:代码详解与函数解析
10 0
|
7天前
|
存储 C语言
C语言实战 | “俄罗斯方块”游戏重构
摘要(Markdown格式): 在之前的游戏中,全局变量的过度使用导致存储浪费和低代码通用性。以“贪吃蛇”为例,显示功能依赖全局变量,限制了函数的复用。通过参数传递代替全局变量,如在“俄罗斯方块”等游戏中控制物体运动的函数,可提升代码重用性和模块化。重构过程中,即使小到变量命名和代码精简的改进,也能逐步带来程序质量的显著提升。
9 0
|
7天前
|
自然语言处理 C语言 C++
程序与技术分享:C++写一个简单的解析器(分析C语言)
程序与技术分享:C++写一个简单的解析器(分析C语言)
|
7天前
|
程序员 编译器 C语言
详解C语言入门程序:HelloWorld.c
详解C语言入门程序:HelloWorld.c
8 0
|
7天前
|
机器学习/深度学习 C语言 Windows
程序与技术分享:C语言学生宿舍管理系统代码(可运行)
程序与技术分享:C语言学生宿舍管理系统代码(可运行)
11 0
|
5天前
|
Java C语言 C++
定义C语言的int main()函数
定义C语言的int main()函数
|
6天前
|
存储 移动开发 C语言
技术心得记录:嵌入式开发中常用到的C语言库函数
技术心得记录:嵌入式开发中常用到的C语言库函数