带你玩转三子棋—【C语言】

简介: 带你玩转三子棋—【C语言】

前言:

为了实现三子棋,首先我们应该将代码分模块编写,我们分为3个部分

1. test.c —测试游戏(主函数)2. game.c 实现游戏部分代码 3. game.h 函数的声明、宏定义等

1. 菜单的打印

菜单打印:

为了玩游戏方便,我们可以设置一个菜单,在每次玩游戏的时候都打印一下,方便玩家玩游戏体验,实现如下:

玩家选择 “1” -玩游戏      

玩家选择 “0”-退出游戏      

玩家选择其他数字—提示选择错误,重新选择


实现选择数字玩游戏:


1.如何做到玩完一把再玩一把,不想玩了还能退出游戏呢?


我们可以使用do-while循环,设置循环判断为输入的值,这样就实现了只有在输入为0时退出游戏


2. 如何做到选择1玩游戏、选择0退出游戏、选择其他数提示选择错误呢?


我们可以在do-while循环的里面使用switch-case语句


代码如下:



2. game函数的实现

2.1 初始化棋盘

我们这里写的是三子棋的代码,三子棋有三行三列,我们可以使用二维数组来打印

我们可以遍历这个二维数组,把里面的9个元素都初始化为空格

代码:

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

2.2 显示棋盘

由于我们将上面二维数组的每个元素都初始化为空格,如果我们就这样打印出来给玩家玩游戏,那体验感是非常差的,所以,我们将用以下方法优化我们的棋盘显示,方便玩家玩

面蓝色长方形框中:


我们可以将三个空格(中间是数据,两边是空格)和后面的竖线归为1组,这一行有三组


注意:我们最后1组没有竖线(|),所以要另外控制下


上面黄色长方形框中:


我们将三个横线和一条竖线归为1组,一行也是三组,最后一行同理


代码实现:


总结:通过上面的分析,我们可以看出,每打印一行棋盘,我们其实是有两行的棋盘格式控制,所以,我们可以将蓝色和黄色框看成一组,一共有三组,最后一组不打印横线


void DisplayBoard(char board[ROW][COL], int row, int col)
{
  int i = 0;
  for (i = 0; i < row; i++)
  {
    //1. 打印数据
    int j = 0;
    for (j = 0; j < col; j++)
    {
      printf(" %c ", board[i][j]);
      if(j<col-1)
        printf("|");
    }
    printf("\n");
    //2. 打印分割线
    if (i < row - 1)
    {
      //printf("---|---|---\n");
      int j = 0;
      for (j = 0; j < col; j++)
      {
        printf("---");
        if(j<col-1)
          printf("|");
      }
      printf("\n");
    }
  }
}

2.3 玩家下棋

三行三列的二维数组,行和列的下标范围都是0~2,玩家有可能不知道数组的性质,会出现数组下标越界的情况,这时我们需要将玩家输入的横竖坐标都进行减1处理

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] == ' ')//可以落子
      {
        board[x - 1][y - 1] = '*';
        break;
      }
      else//不能落子
      {
        printf("坐标被占有,不能落子,重新输入坐标\n");
      }
    }
    else//非法
    {
      printf("坐标非法,重新输入\n");
    }
  }
}


2.4 电脑下棋

电脑下棋,我们可以使用生成随机数的函数,让生成的随机数%行、%列,就是一个随机的二维数组下标

生成随机数的函数用法,在我之前的博客有介绍,有兴趣可以去学习下哦!

void ComputerMove(char board[ROW][COL], int row, int col)
{
  int x = 0;//0~row-1
  int y = 0;//0~col-1
  printf("电脑下棋:>\n");
  while (1)
  {
    x = rand() % row;
    y = rand() % col;
    if (board[x][y] == ' ')
    {
      board[x][y] = '#';
      break;
    }
  }
}


2.5 判断输赢

该函数要实现以下4种情况


1. 玩家赢


2. 电脑赢


3. 平局


4. 上面情况都不符合,那就继续下


赢的三种情况


1. 每一行出现三个相同的符号 2. 每一列出现三个相同的符号 3. 对角线出现三个相同的


平局:


实现一个判断这把游戏是不是平局的函数,在判断输赢函数中来调用


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][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) == 1)
  {
    return 'Q';
  }
  //继续
  return 'C';
}

2.6 判断棋盘是否满了

遍历数组,看是否有元素还是空格,如果有返回0,如果没有,那就表示棋盘满了,返回1

注意:这里返回的数字是返回到判断输赢函数的条件判断语句中

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


3. 全部代码

3.1 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);
//判断输赢
//玩家赢 - '*'
//电脑赢 - '#'
//平局  - 'Q'
//继续  - 'C'
char IsWin(char board[ROW][COL], int row, int col);

3.2  game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
//初始化棋盘为空格
void InitBoard(char board[ROW][COL], int row, int col)
{
  int i = 0;
  for (i = 0; i < row; i++)
  {
    int j = 0;
    for (j = 0; j < col; j++)
    {
      board[i][j] = ' ';
    }
  }
}
//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col)
{
  int i = 0;
  for (i = 0; i < row; i++)
  {
    //1. 打印数据
    int j = 0;
    for (j = 0; j < col; j++)
    {
      printf(" %c ", board[i][j]);
      if(j<col-1)
        printf("|");
    }
    printf("\n");
    //2. 打印分割线
    if (i < row - 1)
    {
      //printf("---|---|---\n");
      int j = 0;
      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] == ' ')//可以落子
      {
        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;//0~row-1
  int y = 0;//0~col-1
  printf("电脑下棋:>\n");
  while (1)
  {
    x = rand() % row;
    y = rand() % col;
    if (board[x][y] == ' ')
    {
      board[x][y] = '#';
      break;
    }
  }
}
//判断棋盘是否已满
int IsFull(char board[ROW][COL], int row, int col)
{
  int i = 0;
  for (i = 0; i < row; i++)
  {
    int j = 0;
    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][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) == 1)
  {
    return 'Q';
  }
  //继续
  return 'C';
}


3.3 test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void menu()
{
  printf("*****************************\n");
  printf("********  1. play   *********\n");
  printf("********  0. exit   *********\n");
  printf("*****************************\n");
}
void game()
{
  char board[ROW][COL] = {0};
  InitBoard(board, ROW, COL);
  //打印棋盘
  DisplayBoard(board, ROW, COL);
  //下棋
  char ret = 0;
  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");
  else if (ret == '#')
    printf("电脑赢\n");
  else
    printf("平局\n");
}
int main()
{
  int input = 0;
  srand((unsigned int)time(NULL));
  do
  {
    menu();
    printf("请选择:>");
    scanf("%d", &input);//1 0 4
    switch (input)
    {
    case 1:
      game();
      break;
    case 0:
      printf("退出游戏\n");
      break;
    default:
      printf("选择错误,重新选择!\n");
      break;
    }
  } while (input);
  return 0;
}
相关文章
|
6月前
|
C语言
c语言简单三子棋
c语言简单三子棋
|
C语言
c语言实现简易三子棋
c语言实现简易三子棋
40 0
|
C语言
三子棋 (C语言)【超详解】
三子棋 (C语言)【超详解】
|
4月前
|
存储 编译器 C语言
【C语言】三子棋及多子棋
C语言实现三子棋及多子棋
32 2
【C语言】三子棋及多子棋
|
5月前
|
存储 C语言
三子棋(C语言版)
三子棋(C语言版)
|
6月前
|
存储 C语言
C语言实现三子棋
C语言实现三子棋
34 0
|
6月前
|
C语言
C语言:三子棋的实现。
C语言:三子棋的实现。
35 0
|
6月前
|
C语言
三子棋的实现(c语言)
三子棋的实现(c语言)
|
6月前
|
C语言
C语言-三子棋
C语言-三子棋
39 1