c语言实现简易三子棋

简介: c语言实现简易三子棋

前言

实现一个简易的三子棋游戏,玩家能够和电脑进行对战,分出高下。

一、整体流程

  1. 创建三个文件,test.c用来放测试三子棋功能,game.c里放置游戏各个功能的实现代码,game.h用来放置需要用到的所有头文件及函数的声明。
  2. 在test.c中写一个菜单打印函数,用来每次游戏时打印菜单。在主函数中实现选择进入游戏,退出游戏等功能。当选择进入游戏,游戏具体操作的代码放在一个game()函数中。
  3. 书写game()函数,创建一个棋盘,并且完成棋盘的初始化,打印棋盘,玩家下棋,电脑下棋,判断输赢等功能。将这些功能包装成函数放在game.c中,并在game.h中声明。
  1. 完善代码并测试功能,进行修改完善。

二、具体代码实现

1、制作游戏菜单

void menu()
{
  printf("************************\n");
  printf("******1 开始游戏 *******\n");
  printf("******0 退出游戏 *******\n");
  printf("************************\n");
}

2、制作出主函数框架

int main()
{
  int input = 0;
  srand((unsigned int)time(NULL));//这里是后面电脑下棋需要用到的
  do {
    menu();
    printf("请输入你的选择>\n");
    scanf("%d", &input);//输入选择
    switch (input) 
    {
    case 1:
      game();
      break;
    case 0:
      printf("退出游戏\n");
      break;
    default:
      printf("输入非法,请重新输入\n");
      break;
    }
  } while (input);
  return 0;
}

3、接下来完善game()函数,将游戏各个功能写在game.c中。用二维数组放置棋盘,棋盘的行和列长度可以放在头文件中定义,方便整体的修改。

void game()
{
  char board[ROW][COL] = { 0 };//棋盘
  InitBoard(board, ROW, COL);//置空初始化棋盘
  DisplayBoard(board, ROW, COL);//打印棋盘
  char ret = ' ';
  while (1)
  {
    //玩家下棋
    PlayerMove(board, ROW, COL);
    DisplayBoard(board, ROW, COL);
    ret = IsWin(board, ROW, COL);
    if (ret != 'B')
    {
      break;
    }
    printf("---------------------\n");
    //电脑下棋
    ComputerMove(board, ROW, COL);
    DisplayBoard(board, ROW, COL);
    ret = IsWin(board, ROW, COL);
    if (ret != 'B')
    {
      break;
    }
  }

代码中的一些属性会在后续具体函数的代码中出现

4、棋盘中的元素都为0,需要进行初始化

void InitBoard(char board[ROW][COL], int row, int col)
{
  for (int i = 0; i < row; i++) 
  {
    for (int j = 0; j < col; j++) 
    {
      board[i][j] = ' ';//将数组中所有元素置为空格
    }
  }
}

5、将棋盘打印出来,加上一些线区分每个棋子位置

void DisplayBoard(char board[ROW][COL], int row, int col)
{
  for (int i = 0; i < row; i++) 
  {
    for (int j = 0; j < col; j++) 
    {
      printf(" %c ", board[i][j]);
      if (j < col - 1) 
      {
        printf("|");
      }
    }
    printf("\n");
    if (i < row - 1) 
    {
      for (int j = 0; j < col; j++) 
      {
        printf("---");
        if (j < col - 1) 
        {
          printf("|");
        }
      }
      printf("\n");
    }
  }
}

6、实现玩家下棋的功能

void PlayerMove(char board[ROW][COL], int row, int col)
{
  int x = 0;
  int y = 0;
  while (1)
  {
    printf("该你下了(以空格隔开):\n");
    scanf("%d %d", &x, &y);//输入想要下的坐标(从1开始)
    if (x >= 1 && x <= row && y >= 1 && y <= col)//判断输入坐标是否合法
    {
      if (board[x - 1][y - 1] == ' ')//判断输入坐标是否已有棋子
      {
        board[x - 1][y - 1] = '*';
        break;
      }
      else
      {
        printf("坐标以被占用,请重新输入:\n");
      }
    }
    else
    {
      printf("输入非法,请重新输入:\n");
    }
  }
}

7、实现电脑下棋功能

void ComputerMove(char board[ROW][COL], int row, int col)
{
  printf("轮到电脑了:\n");
  while (1)
  {
    int x = rand() % row + 1;
    int y = rand() % col + 1;
    if (board[x][y] == ' ')
    {
      board[x][y] = '#';
      break;
    }
  }
}

~srand((unsigned int)time(NULL));已经在主函数中写上,利用时间戳返回一个随机数

~int x =rand() % row ;可以得到0 ~ row-1的随机数,整体加一便可得到1~row的随机数~对col也是一样

8、判断是否胜利

这里需要用到一个判断棋盘是否已满的函数

int IsFull(char board[ROW][COL], int row, int col)
{
  for (int i = 0; i < row; i++)
  {
    for (int j = 0; j < col; j++)
    {
      if (board[i][j] == ' ')
      {
        return 0;
      }
    }
  }
  //如果一个空格都没有,走出了循环,说明已经满了
  return 1;
}

判断是否胜利,返回不同的字符,在game()函数中进行判断,得出谁获得胜利

该判断只适用于3*3棋盘的三子棋

char IsWin(char board[ROW][COL], int row, int col)
{
  //行
  for (int 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 (int i = 0; i < row; 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 'A';
  }
  return 'B';
}

9、记得将需要的头文件函数等在game.h中进行声明,并在test.c中引用该头文件

以下是头文件中的内容

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 3
#define COL 3
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 ComputerMove(char board[ROW][COL], int row, int col);
int IsFull(char board[ROW][COL], int row, int col);
char IsWin(char board[ROW][COL], int row, int col);

三、整体代码

game.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 3
#define COL 3
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 ComputerMove(char board[ROW][COL], int row, int col);
int IsFull(char board[ROW][COL], int row, int col);
char IsWin(char board[ROW][COL], int row, int col);

game.c

#include "game.h"
//数组置空
void InitBoard(char board[ROW][COL], int row, int col)
{
  for (int i = 0; i < row; i++) 
  {
    for (int j = 0; j < col; j++) 
    {
      board[i][j] = ' ';
    }
  }
}
//打印数组
void DisplayBoard(char board[ROW][COL], int row, int col)
{
  for (int i = 0; i < row; i++) 
  {
    for (int j = 0; j < col; j++) 
    {
      printf(" %c ", board[i][j]);
      if (j < col - 1) 
      {
        printf("|");
      }
    }
    printf("\n");
    if (i < row - 1) 
    {
      for (int 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;
  while (1)
  {
    printf("该你下了(以空格隔开):\n");
    scanf("%d %d", &x, &y);//输入想要下的坐标(从1开始)
    if (x >= 1 && x <= row && y >= 1 && y <= col)
    {
      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)
{
  printf("轮到电脑了:\n");
  while (1)
  {
    int x = rand() % row + 1;
    int y = rand() % col + 1;
    if (board[x][y] == ' ')
    {
      board[x][y] = '#';
      break;
    }
  }
}
//判断是否满了
int IsFull(char board[ROW][COL], int row, int col)
{
  for (int i = 0; i < row; i++)
  {
    for (int j = 0; j < col; j++)
    {
      if (board[i][j] == ' ')
      {
        return 0;
      }
    }
  }
  return 1;
}
//判断是否胜利
char IsWin(char board[ROW][COL], int row, int col)
{
  //行
  for (int 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 (int i = 0; i < row; 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 'A';
  }
  return 'B';
}
#

test.c

#include "game.h"
//游戏菜单
void menu()
{
  printf("************************\n");
  printf("******1 开始游戏 *******\n");
  printf("******0 退出游戏 *******\n");
  printf("************************\n");
}
//三子棋游戏
void game()
{
  char board[ROW][COL] = { 0 };//棋盘
  InitBoard(board, ROW, COL);//置空
  DisplayBoard(board, ROW, COL);//打印棋盘
  char ret = ' ';
  while (1)
  {
    //玩家下棋
    PlayerMove(board, ROW, COL);
    DisplayBoard(board, ROW, COL);
    ret = IsWin(board, ROW, COL);
    if (ret != 'B')
    {
      break;
    }
    printf("---------------------\n");
    //电脑下棋
    ComputerMove(board, ROW, COL);
    DisplayBoard(board, ROW, COL);
    ret = IsWin(board, ROW, COL);
    if (ret != 'B')
    {
      break;
    }
  }
  if (ret == '*')
  {
    printf("恭喜你取得胜利\n");
  }
  else if (ret == '#')
  {
    printf("很遗憾,你输了\n");
  }
  else
  {
    printf("你与电脑势均力敌\n");
  }
}
int main()
{
  int input = 0;
  srand((unsigned int)time(NULL));
  do {
    menu();
    printf("请输入你的选择>\n");
    scanf("%d", &input);//输入选择
    switch (input) 
    {
    case 1:
      game();
      break;
    case 0:
      printf("退出游戏\n");
      break;
    default:
      printf("输入非法,请重新输入\n");
      break;
    }
  } while (input);
  return 0;
}

四、效果测试

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