C语言实现三子棋

简介: C语言实现三子棋

今天小杜为大家带来一个C语言小游戏——三子棋

在我们学习编程语言的过程中,需要有这样有趣的项目来保持自己对于编程的兴趣和信心

1.游戏整体思路

我们需要有三个文件:

  • test.c      ——  测试游戏
  • game.h   ——  游戏函数的声明
  • game.c   ——  游戏函数的实现

2.游戏菜单的创建

进入游戏时,首先出现的是菜单界面

我们定义一个“菜单函数”menu( )来实现这一功能

游戏菜单应该实现这几个功能:

  • 游戏的进入
  • 游戏的退出
  • 非法输入的返回提示和说明

接下来是我们实现这一功能的代码块

#include<stdio.h>
#include"game.h"
void menu() {
  printf("********************\n");
  printf("****** 1.play ******\n");
  printf("****** 0.exit ******\n");
  printf("********************\n");
}
int main() {
  int input = 0;
  do
  {
    menu();
    printf("请输入:>");
    scanf("%d", &input);
    switch (input)
    {
    case 1:
      printf("三子棋\n");
      break;
    case 0:
      printf("退出游戏\n");
      break;
    default:
      printf("选择错误\n");
      break;
    }
  } while (input);
    return 0;
}

这是该模块菜单函数的运行截图

3.游戏主体的实现

3.1棋盘的初始化  

游戏刚开始时,我们需要对棋盘进行初始化操作,对棋盘进行清空,以保证后续游戏的正常进行。我们定义一个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] = ' ';
    }
  }
}

3.2打印棋盘

初始化棋盘后就需要打印棋盘了

打印棋盘的代码如下

void DisplayBoard(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++)
    {
      printf(" %c ",board[i][j]);
      if (j < col - 1)
      {
        printf("|");
      }
    }
    printf("\n");
    //再打印分割行部分
    if (i < row - 1)
    {
      for (j = 0; j < col; j++)
      {
        printf("---");
        if (j < col - 1)
        {
          printf("|");
        }
      }
    }
    printf("\n");
  }
}

3.3玩家下棋

打印好棋盘,就要进行我们的下棋阶段

我们规定玩家先下棋

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);
    if (x >= 1 && x <= ROW && y >= 1 && y <= COL)
    {
      if (board[x - 1][y - 1] != ' ')
      {
        printf("该位置已被占用,请输入其他坐标\n");
      }
      else
      {
        board[x - 1][y - 1] = '*';
        break;
      }
    }
    else
    {
      printf("输入非法,请重新输入\n");
    }
  }
}

玩家输入对应的合法坐标下棋,接下来就是电脑下棋

暂且不设计电脑对抗玩家的算法,就让电脑产生一个棋盘内部的随机坐标

3.4电脑下棋

void ComputerBoard(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;
    }
  }
}

给电脑设计了随机数rand()函数,但这个函数需要srand()设置,所以我们在main()函数开头加上srand()

接下来写一个判断输赢的函数来进行判断

3.5判断输赢

三子棋游戏出现的结果有以下四种,我们用各自对应的符号进行判断

//玩家赢 - *

//电脑赢 - #

//平局 - Q

//继续游戏 - C

char IsWin(char board[ROW][COL], int row, int col)
{
  int i = 0;
  int j = 0;
  for (i = 0; i < row; i++)
  {
    if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
    {
      return board[i][0];
    }
  }
  for (i = 0; i < col; i++)
  {
    if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
    {
      return board[0][i];
    }
  }
  if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
    return board[1][1];
  if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
    return board[1][1];
  if (IsFull(board, row, col))
    return 'Q';
  return 'C';
}

3.6棋盘满

接下来我们还需要有一个函数来判断棋盘是否已满

static 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;
}

我们用static修饰这个函数,使当前函数只能在本文件内部使用

3.7game()函数

上面我们铺垫了所有三子棋所要用到的函数,这些函数在game()函数中使用

void game()
{
  char ret = 0;
  char board[ROW][COL] = {0};
  InitBoard(board,ROW,COL);
  DisplayBoard(board,ROW,COL);
  while (1)
  {
    //玩家下棋
    PlayerMove(board, ROW, COL);
    DisplayBoard(board, ROW, COL);
    //判断输赢
    ret = IsWin(board, ROW, COL);
    if (ret != 'C')
      break;
    //电脑下棋
    ComputerBoard(board, ROW, COL);
    DisplayBoard(board, ROW, COL);
    //判断输赢
    ret = IsWin(board, ROW, COL);
    if (ret != 'C')
      break;
  }
  if (ret == '*')
  {
    printf("玩家赢\n");
  }
  if (ret == '#')
  {
    printf("电脑赢\n");
  }
  if (ret == 'Q')
  {
    printf("平局\n");
  }
}

4.整体代码

这些代码我们在实际使用时是需要封装在不同的文件内的

所以我们定义了test.c,game.c,game.h文件封装我们所有用到的函数以及头文件

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include"game.h"
void menu() {
  printf("********************\n");
  printf("****** 1.play ******\n");
  printf("****** 0.exit ******\n");
  printf("********************\n");
}
void game()
{
  char ret = 0;
  char board[ROW][COL] = { 0 };
  InitBoard(board, ROW, COL);
  DisplayBoard(board, ROW, COL);
  while (1)
  {
    //玩家下棋
    PlayerMove(board, ROW, COL);
    DisplayBoard(board, ROW, COL);
    //判断输赢
    ret = IsWin(board, ROW, COL);
    if (ret != 'C')
      break;
    //电脑下棋
    ComputerBoard(board, ROW, COL);
    DisplayBoard(board, ROW, COL);
    //判断输赢
    ret = IsWin(board, ROW, COL);
    if (ret != 'C')       
      break;
  }
  if (ret == '*')
  {
    printf("玩家赢\n");
  }
  if (ret == '#')
  {
    printf("电脑赢\n");
  }
  if (ret == 'Q')
  {
    printf("平局\n");
  }
}
int main() {
  int input = 0;
  do
  {
    menu();
    printf("请输入:>");
    scanf("%d", &input);
    switch (input)
    {
    case 1:
      printf("三子棋\n");
      game();
      break;
    case 0:
      printf("退出游戏\n");
      break;
    default:
      printf("选择错误\n");
      break;
    }
  } while (input);
  return 0;
}

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#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] = ' ';
    }
  }
}
void DisplayBoard(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++)
    {
      printf(" %c ", board[i][j]);
      if (j < col - 1)
      {
        printf("|");
      }
    }
    printf("\n");
    //再打印分割行部分
    if (i < row - 1)
    {
      for (j = 0; j < col; j++)
      {
        printf("---");
        if (j < col - 1)
        {
          printf("|");
        }
      }
    }
    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);
    if (x >= 1 && x <= ROW && y >= 1 && y <= COL)
    {
      if (board[x - 1][y - 1] != ' ')
      {
        printf("该位置已被占用,请输入其他坐标\n");
      }
      else
      {
        board[x - 1][y - 1] = '*';
        break;
      }
    }
    else
    {
      printf("输入非法,请重新输入\n");
    }
  }
}
void ComputerBoard(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;
    }
  }
}
static 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;
  int j = 0;
  for (i = 0; i < row; i++)
  {
    if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
    {
      return board[i][0];
    }
  }
  for (i = 0; i < col; i++)
  {
    if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
    {
      return board[0][i];
    }
  }
  if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
    return board[1][1];
  if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
    return board[1][1];
  if (IsFull(board, row, col))
    return 'Q';
  return 'C';
}

game.h

#pragma once
#define ROW 3
#define COL 3
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col);
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);
//电脑下棋
void ComputerBoard(char board[ROW][COL], int row, int col);
//判断输赢
//有四种可能
//玩家赢   - *
//电脑赢   - #
//平局     - Q
//继续游戏 - C
char IsWin(char board[ROW][COL], int row, int col);

我们把所有的函数声明头文件以及宏定义都放在我们自己创建的game.h文件中

我们在其他文件中使用时只需要包含该文件用双引号引住即可

5.结束

今天我们练习写出来自己的三子棋游戏,这是一个很好的进步

小杜跟各位小伙伴在一起成长,祝我们都能成为大牛!

                                                                                                                               //小杜的成长之路

相关文章
|
10月前
|
C语言
以c语言为基础实现的简易三子棋
以c语言为基础实现的简易三子棋
52 1
|
10月前
|
C语言
c语言简单三子棋
c语言简单三子棋
|
10月前
|
算法 C语言 C++
【C语言实战项目】三子棋游戏
【C语言实战项目】三子棋游戏
73 1
|
10月前
|
C语言
C语言之三子棋小游戏
C语言之三子棋小游戏
|
10月前
|
C语言
用c语言实现三子棋
用c语言实现三子棋
49 0
|
9月前
|
C语言
【海贼王编程冒险 - C语言海上篇】C语言如何实现简单的三子棋游戏?
【海贼王编程冒险 - C语言海上篇】C语言如何实现简单的三子棋游戏?
42 1
|
10月前
|
C语言
万字详解:C语言三子棋进阶 + N子棋递归动态判断输赢(二)
我们可以通过创建并定义符号常量NUMBER,来作为判断是否胜利的标准。如三子棋中,令NUMBER为3,则这八个方向中有任意一个方向达成3子连珠,则连珠的这个棋子所代表的玩家获胜。
95 1
|
10月前
|
算法 C语言 C++
万字详解:C语言三子棋进阶 + N子棋递归动态判断输赢(一)
三子棋游戏设计的核心是对二维数组的把握和运用。
121 1
|
10月前
|
编译器 C语言
【C语言入门小游戏】三子棋
【C语言入门小游戏】三子棋
69 0
【C语言入门小游戏】三子棋
|
10月前
|
C语言
【用C语言轻松搞定】三子棋(超详细教程)
【用C语言轻松搞定】三子棋(超详细教程)