超过光速c 发表于 2021-8-25 18:45:02

【C语言练习项目】三子棋

本帖最后由 超过光速c 于 2021-8-25 18:47 编辑

三子棋游戏!!
三个文件,先直接贴上来。

test_.c文件的内容
/**
* @file test_.c
* @date 2021-08-24
*
* 三子棋
*
*/

#include "game_3.h"
#include "game_3.c"

void menu(){
    printf("****************************************************************\n");
    printf("**************** 1.Play    0.exit******************\n");
    printf("****************************************************************\n");

}

// 游戏的整个算法实现
void game_3(){
    char ret;
    // 数组-存放走出的棋盘信息
    char board = {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;
      }
      // 电脑下棋
      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");
    }


}


void test_(){
    int input=0;
    // 随机存储生成器
    srand((unsigned int)time(NULL));

    do{
      menu();
      printf("请选择 : >> ");
      scanf("%d",&input);
      switch(input){
            case 1:
                game_3();
                // printf("开始游戏!\n");
                break;
            case 0:
                printf("退出游戏!\n");
                break;
            default:
                printf("输入错误,请重新输入:");
                break;
      }
    }while(input);
}

int main(){

    test_();

    printf("\n");
    return 0;
}


game_3.c 文件内容
#include "game_3.h"


// 实现初始化
void InitBoard(char board, int row, int col){
    int i=0;
    int j=0;
    for(i=0;i<row;i++){
      for(j=0;j<col;j++){
            board = ' ';
      }
    }

}

// 实现打印棋盘
void DisplayBoard(char board, int row, int col){
    int i = 0;
    int j = 0;
    for(i=0;i<row;i++){
      // 1.打印第一行数据
      for(j=0;j<col;j++){
            printf(" %c ",board);
            if(j < col-1) printf("|");
      }
      printf("\n");
      // printf(" %c | %c | %c \n",board, board, board);
      // 2.打印分割行

      if(i < row-1){
            for(j=0;j<col;j++){
            printf("---");
            if(j < col-1) printf("|");
            }

            printf("\n");
      }
            // printf("---|---|---\n");
    }
}

// 实现玩家下棋
void PlayerMove(char board, int row, int col){
    int x=0, y=0;

    printf("玩家走:> \n");
    while(1){
      printf("请输入要下的坐标:>");
      scanf("%d%d",&x,&y);
      getchar();

      // 判断x和y输入的合法性
      if(x>=1 && x<=ROW && y>=1 && y<=COL){
            if(board == ' '){
                board = '*';
                break;
            }
            else{
                printf("坐标被占用\n");
            }
      }
      else
      {
            printf("坐标非法,请重新输入!");
      }
    }

}

// 实现电脑下棋
void ComputerMove(char board, int row, int col){
    int x=0;
    int y=0;
    printf("电脑走!\n");

    while(1){
      x = rand() % row;
      y = rand() % col;
      
      if(board == ' '){
            board = '#';
            break;
      }
    }
}


// 满了返回1,没满返回0
int IsFull(char board, int row, int col)
{
    for(int j=0;j<row;j++)
    {
      for(int i=0;i<col;i++)
      {
            if(board == ' ')
            {
                return 0; // 没满
            }
      }
    }
    return 1; // 满了
}

// 实现判断输赢
char IsWin(char board, int row, int col){
    // 判断行
    for(int i = 0; i < row; i++){
      if(board == board && board == board && board != ' ')
      {
            return board;
      }
    }

    // 判断列
    for(int i = 0; i < col; i++){
      if(board == board && board == board && board != ' ')
      {
            return board;
      }
    }

    // 判断交叉
    if(board == board && board == board && board != ' ')
    {
      return board;
    }
    if(board == board && board == board && board != ' ')
    {
      return board;
    }

    // 判断平局
    if(1 == IsFull(board, ROW, COL))
    {
      return 'Q';
    }
    return 'C';
}



game_3.h 文件内容
#define ROW 3
#define COL 3

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// #include "game_3.c"

// 声明
void InitBoard(char board, int row, int col);
void DisplayBoard(char board, int row, int col);
void PlayerMove(char board, int row, int col);
void ComputerMove(char board, int row, int col);


// 告诉我门四种游戏状态,玩家赢 * 、电脑赢 #、平局 Q、继续 C
char IsWin(char board, int row, int col);


/**
* 整体逻辑回顾
*
* 1、游戏便于循环玩,所以将所有操作包含在一个 do while 循环内
*-- 先打印选择目录,用户选择输入 1开始游戏,0退出游戏(退出循环)
*-- 对输入有一个检验,若输入错误则提示用户重新输入
* 2、游戏的操作
*-- 用一个二维数组来存储棋盘
*-- 初始化棋盘,再将棋盘打印出来。利用for循环将棋盘拆分成每一个单独的元素进行遍历打印,更加的灵活
*-- 用户下棋:提示用户输入坐标,检验输入的坐标有效性,1、是否输入错误数值;2、输入坐标是否被占用。将坐标数组添加*号
*-- 电脑下棋:使用随机数值,检验坐标是否被占用。将坐标数组添加#号       随机存储生成器不理解?
*-- 每次走一步后将棋盘打印输出,观察走棋后的结果
* 3、判断输赢
*-- 横、纵、交叉的坐标数组内相等,且任意一个坐标不等于‘ ’值(棋盘初始化为' '空值),就返回此前坐标数组内的符号,返回*则玩家赢,返回#则电脑赢
*-- 检验棋盘空格数。循环遍历检验每一个坐标数组,若满则返回为平局,若未满则继续游戏
*
*
* 学得:
* C语言,随机存储生成器,随机数的使用
* rand() 函数包含于 <stdlib.h> 头文件中【random() 函数不是一个标准函数,无法再VC/VS等编译器通过。】
* rand() 会随机产生一个位于 0~RAND_MAX(至少是32767)之间的整数
* 伪随机数,根据电脑启动时而定,则不再变化。随机存储生成器:srand((unsigned)time(NULL)),根据时间进行随机产生新的数值
* 随机数的范围设定:
* rand() % 10 即 0~9
* rand() % 51 + 13 即 13~63。rand()%51 即0~50,+13则是 0+13~50+13 即 13~63
*
* 连续随机数的产生
* 用for循环产生的都是一样的随机数
* for(int i=0; i<10; i++)
* {
*      srand((unsigned)time(NULL));
*      a = rand() % 100;
*      printf("%d", a);
* }
*
*
* 关于头文件 #include "" 和 <> 的区别用法,调取其他文件的函数
* <> : 到库里面寻找头文件
* "" : 优先到当前目录下寻找,找不到再到库里面取找。尽量优先使用,减少寻找所占用的资源。
*/

效果是这样的:

yobdc 发表于 2021-8-26 10:15:37

学习

burntlime 发表于 2021-8-26 21:13:15

学习
页: [1]
查看完整版本: 【C语言练习项目】三子棋