c语言三字棋(非智能版)0.0.(包含多字棋思路)

简介:

@[TOC]

前言:

1.本文的三字琪,针对电脑是一种随机落子,不智能(后面会进行修改)。
2.因为在对胜负的判断很麻烦,因此我的思路:建立一个大原先棋盘2圈棋盘,(下棋范围仍是原棋盘,大2圈是为了边界情况的判定) 这样的话判断胜负时,我只需要判断落子后周围2圈的情况
3.电脑下琪是随机下棋,因此需要随机数:见我了我一篇博客:伪随机数的生成
4.这需要很多的函数,为了mian函数文件的好看,自定义库函数,main.c文件调用相应函数
5.为了提高程序的灵活性,我把棋盘定义为全局变量,这样方便更改棋盘大小。
6.return可以直接结束函数运行,break只能结束一层循环,仔细体会其中妙处。后面的判断胜负函数就用到了,有兴趣的请看程序,非常的妙
7.在最终判断是无论胜负,平局都返回0,否则1.特别妙。0.0.

我想要的棋盘

image-20210817004108672

思路:

程序代码(分步+汇总)

自定义函数库:game.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define Row 9
#define Col 9
#define Rows Row+4
#define Cols  Col+4
void Beg_board(char board[Rows][Cols] ,int row, int col);//初始化棋盘
void Show_board(char board[Rows][Cols], int row, int col);//用于输出棋盘
char Peo_ply(char board[Rows][Cols], int row, int col);//玩家走
char Com_ply(char board[Rows][Cols], int row, int col);//电脑走
char   Is_win(char board[Rows][Cols], int x, int y, int row, int col);//返回判断的信息.
int   Ret_win(char ch);//返回的值,用于终止游戏,
void game();//游戏执行
//玩家赢返回‘*’;
//电脑赢返回‘#’;
//平局返回'E';
//继续返回' C'; 

棋盘的初始化函数

void Beg_board(char board[Rows][Cols] ,int row, int col)
{
    int i = 0;
    int j = 0;
    for(i=1;i<= row-3;i++)
    {
        for (j = 1; j <= col - 3 ; j++)
        {
            if (i==1)
            {
                board[i][j] = j - 1+'0';
                board[j][i] = j - 1+'0';
            }
            else if(j>1)
            {
                board[i][j] = ' ';
            }
        }
    }

}

输出棋盘函数

void Show_board(char board[Rows][Cols], int row, int col)
{
    int i = 0;
    int j = 0;
    int t = 0;
    for (i = 1; i < row - 2; i++)
    {
        for (j = 1; j < col - 2; j++)
        {
            if (i == 1)
            {
                printf(" %c  ", board[i][j]);
            }
            else
            {
                if (j == 1)
                {
                    printf(" %c |", board[i][j]);

                }
                else 
                {
                    printf(" %c |", board[i][j]);
                }
            }
        }
        printf("\n");

        for (t = 0; t < col - 2; t++)
        {
            printf("----");
        
        }
        printf("\n");
    }

}

玩家走函数

char Peo_ply(char board[Rows][Cols], int row, int col)
{
    int x = 0;
    int y = 0;
    while (1)
    {
        printf("请输入坐标:");//字符数组的行列与坐标轴不同,但有规律
        scanf("%d %d", &x, &y);
        if (x > 0 && x < row - 3 && y>0 && y < col - 3)
        {
            if (board[y+1][x+1] == ' ')//防止重置电脑走的棋或者自己走过的棋
            {
                board[y+1][x+1] = '*';
                Show_board(board, row, col);
                break;
            }
            else
            {
                printf("坐标输入错误,请注意是否重复!\n");
            }
        }
        else 
        {
            printf("坐标输入错误,请注意横纵坐标轴!\n");
        }
    }

    return  Is_win(board, x, y, row, col);
    
}

判断胜负函数

周围2圈,共12种情况
判断胜负,只有连续3个不为空格,直接返回值。这地方非常妙
返回相应的字符,用以终止落子循环
char   Is_win(char board[Rows][Cols], int x, int y, int row, int col)
{

    int m = y + 1;//用于存储x,y的坐标.
    int n = x + 1;
    int i = 0;
    int j = 0;
//判断周围一格的情况(直接返回字符,不需加以判断,但前提是非空格字符)
            if ((board[m][n] == board[m][n - 1] )&& (board[m][n] == board[m][n + 1] )&& (board[m][n] != ' '))
            {
                return board[m][n];//比较左右
            }
            else if( (board[m][n] == board[m - 1][n] )&&( board[m ][n] ==board[m+1][n]) &&( board[m][n] != ' '))
            {
                return board[m][n];//比较上下
            }
            else if( (board[m][n] == board[m + 1][n + 1]) && (board[m][n] ==board[m - 1][n - 1] )&& (board[m][n] != ' '))
            {
                return board[m][n];//比较左上右下
            }
            else if ((board[m][n] == board[m - 1][n + 1] )&&( board[m][n] == board[m + 1][n - 1]) && (board[m][n] != ' '))
            {
                return board[m][n];//比较左下右上
            }

//判断周围 2格的情况
            else if ((board[m][n] == board[m][n - 1] )&& (board[m][n] == board[m][n - 2]) &&( board[m][n] != ' '))
            {
                return board[m][n];//比较左边2个
            }
            else     if( (board[m][n] == board[m][n + 1] )&& (board[m][n] == board[m][n + 2] )&&( board[m][n] != ' '))
            {
                return board[m][n];//比较右边2个
            }
            else if ((board[m][n] == board[m - 1][n] )&& (board[m][n] == board[m - 2][n]) &&( board[m][n] != ' '))
            {
                return board[m][n];//比较上边2个
            }

            else if ((board[m][n] == board[m + 1][n] )&&( board[m][n] == board[m + 2][n] )&&( board[m][n] != ' '))
            {
                return board[m][n];//比较下边2个
            }
            else if ((board[m][n] == board[m + 1][n + 1] )&& (board[m][n] == board[m + 2][n + 2] )&& (board[m][n] != ' '))
            {
            
                return board[m][n];//比较右下2个
            }
            else     if( (board[m][n] == board[m - 1][n + 1] )&&( board[m][n] == board[m - 2][n + 2]) && (board[m][n] != ' '))
            {
                return board[m][n];//比较右上2个
            }
            else if( (board[m][n] == board[m - 1][n - 1]) &&( board[m][n] == board[m - 2][n - 2]) && (board[m][n] != ' '))
            {
                return board[m][n];//比较左上2个
            }
            else if( (board[m][n] == board[m + 1][n - 1] )&&(board[m][n]== board[m + 2][n - 2])&&( board[m][n] != ' '))
            {
                return board[m][n];//比较左下2个
            }
            

//判断是否继续:    
    for (i=2;i<row-3;i++)
               for(j=2;j<col-3;j++)
                  if (board[i][j] == ' ')
                     return 'C';//碰到空格字符,程序结束。
              
//最后一种情况:平局,比较难判断,不过因为return的原因,变容易了。

    return 'E';
}

电脑走(非智能电脑0.0)函数

char  Com_ply(char board[Rows][Cols], int row, int col)
{
    int x = 0;
    int y = 0;
    while (1)
    {
        x = rand() % (row - 3);
        y = rand() % (col - 3);
        if (x > 0 && x < row - 3 && y>0 && y < col - 3)
        {
            if (board[y+1][x+1] == ' ')//防止重置玩家,或者电脑走的位置。
            {
                board[y+1][x + 1] = '#';
                Show_board(board, row, col);
                break;
            }
        }
    }
    return  Is_win(board, x, y, row, col);
}

终止落子函数

将判断胜负函数的返回值做为条件
无论谁赢,或者平局返回0,否则1
int   Ret_win(char ch)//无论输赢,或者平局都返回0,继续则1;
{
    if (ch == '*')
    {
        printf("恭喜你赢了!\n");
        return 0;
    }
    else if (ch == '#')
    {
        printf("很遗憾,你输了!\n");
        return 0;
    }
    else if (ch == 'E')
        {
            printf("本局平局!\n");
            return 0;
        }
    else
    {
        return 1;
    }
}

游戏执行函数

void game()
{

    char game_board[Rows][Cols] = {0};
    Beg_board(game_board, Rows, Cols);
    Show_board(game_board, Rows, Cols);
    while (1)
    {
        if(Ret_win(Peo_ply(game_board, Rows, Cols)))//玩家走,走完判断胜负情况
        {
            printf("继续游戏\n");
        }
        else
        {
        Show_board(game_board, Rows, Cols);
        break;
         }
        if( Ret_win(Com_ply(game_board, Rows, Cols)))//玩家走,走完判断胜负情况
         {

         }
        else
        {
        Show_board(game_board, Rows, Cols);
        break;
         }
    }

}

汇总


//我的思路:
//在判断3三子棋情况,若是棋盘过大, 判断情况太多, 因此我设置了 - 个比原棋盘
//大2圈的棋盘,这样我只需在每次下棋后,判断周围2圈的情况,并返回值。再通
//过另外 - 个函数,将返回的值作为参数,只要不是继续的情况就返回0,否则就返
//回1.这样方便结束下棋的循环。

#include "game.h"
void menu()
{
    printf("*********************************\n");
    printf("******    1.Play  ***************\n");
    printf("******    0.Exit  ***************\n");
    printf("*********************************\n");
}
int main()
{
    srand((unsigned int)time(NULL));
    int input = 0;
    do
    {
        menu();
        printf("请输入:");
        scanf("%d", &input);
        switch (input)
        {
        case 1:game(); break;
        case 0:printf("再见\n"); break;
        default:printf("输入错误\n"); break;
        }
    } while (input);
 
    return 0;
}

运行结果

image-20210817002839571

总结

1.return与break的灵活运用
2.多留意数组下标的位置。
3.注意x,y轴与二维数组行列的不同
4.五字棋等多子棋,和三字棋相似,但是需要确认周围几格内的元素,修改胜负判断条件即可。
相关文章
|
4月前
|
C语言
C语言游戏——三字棋
C语言游戏——三字棋
32 0
|
6月前
|
C语言
【C语言】小游戏-三字棋
【C语言】小游戏-三字棋
38 0
|
编译器 数据安全/隐私保护 C语言
C语言之三字棋
这个三字棋看似生活不起眼的小游戏,但是对于像我一样才开始接触C的人来说,实现起来也不是那样轻而易举。实现三字棋的过程,让我明白掌握代码并非最重要的,最重要的是,理清实现功能的逻辑,例如:实现这个游戏时,首先得了解游戏规则,其次需要一个棋盘......只要自己逻辑清晰,写代码也是水到渠成,还有一点,只要自己掌握逻辑,下次想再次实现这个功能或着分析已写的代码就不会犯怵了。最后我们要多善于整理总结,下次我们遇到类似的问题,就可以触类旁通了。
|
C语言
C语言实现三字棋~步骤详解与代码
C语言实现三字棋~步骤详解与代码
C语言实现三字棋~步骤详解与代码
|
C语言
c语言实现三子棋(内含阅读思路,简单易实现)
本文如果按顺序来阅读可能不太好接受,建议阅读顺序为,由test.c的逻辑顺序读下去,遇见具体函数的实现跳转到game.c中来理解
115 0
c语言实现三子棋(内含阅读思路,简单易实现)
|
存储 C语言 C++
数算部分第二节——顺序表(C语言实现+思路分析+源码分析+运行)
初始化函数,简而言之,我们想要它能够将我的这个顺序表初始化。
234 0
数算部分第二节——顺序表(C语言实现+思路分析+源码分析+运行)
|
机器学习/深度学习 人工智能 算法
从频度引发的c语言多重for循环乃至编写算法思路的思考
首先需要声明的是,笔者是一名有C语言基础并正在为考研而复习数据结构的大学生,本篇文章中的for循环代码来自于清华大学严蔚敏教授出版的《数据结构》。 本篇博客适用于初学者理解C语言for循环,多重for循环、数据结构频度、线性代数矩阵等知识点。 整篇文章从频度开始,讲述两个矩阵相乘算法,最后讲述整个算法的设计原理
160 4
从频度引发的c语言多重for循环乃至编写算法思路的思考
|
C语言
C语言——扫雷1.0(详细分析代码及思路)
C语言——扫雷1.0(详细分析代码及思路)
141 0
C语言——扫雷1.0(详细分析代码及思路)
|
存储 C语言 容器
【c语言】 我使用c语言基础做了一个老少皆宜的”国民小游戏(三字棋)“
本三字棋小游戏是依靠二维数组为核心来实现的,可以更加好理解掌握c语言数组的概念知识,依靠做小游戏项目,把学到了知识在输出出来加已巩固,最后有源代码
108 0
【c语言】 我使用c语言基础做了一个老少皆宜的”国民小游戏(三字棋)“
|
机器学习/深度学习 存储 自然语言处理
C语言编译器概要设计思路一
C语言编译器概要设计思路一
235 0
C语言编译器概要设计思路一