【18.7.10】三子棋C语言小游戏,自制了判定规则。

写了好久的博客一直在草稿箱忘了发,到发下一篇才看到。qAq。
废话不说了上效果图。→_→
代码点开,control+F5,走!

这里写图片描述

输入开始游戏指令

这里写图片描述

干掉电脑了,不过瘾的话再来一把

这里写图片描述

接下来,是代码,将代码分为头文件game.h,游戏的核心文件game.c,和test.c

Game.c(我把它叫做游戏的核心文件)

初始化

使用memset函数将数组里的元素都初始化成‘空格’,注意添加string.h头文件
void Initboard(char Checkerboard[ROW][COL],int row,int col)
{
    memset(Checkerboard,' ',row*col*sizeof(Checkerboard[0][0]));
}

打印棋盘

这里用到了制表符,可以使我们的棋盘看起来更加的精美
void Printboard(char Checkerboard[ROW][COL],int row,int col)
{
        int i = 0;
        int j = 0;
        printf("┏");
        for(j=0;j<col-1;j++)
        {
            printf("━┳");
        }
        printf("━┓\n");
        for(i=0;i<row;i++)
        {
            printf("┃");
            for(j=0;j<col;j++)
            {
                printf(" %c",Checkerboard[i][j]);
                printf("┃");
            }
            printf("\n");
            if(i<row-1)
            {
                printf("┣");
                for(j=0;j<col-1;j++)
                {
                    printf("━╋");
                }
                printf("━┫\n");
            }
        }
        printf("┗");
        for(j=0;j<col-1;j++)
        {
            printf("━┻");
        }
        printf("━┛\n");
}

玩家下棋

首先玩家不是程序猿,他可不知道数组的下标是从0开始的,所以在‘下棋’的时候,我们要注意将玩家输入的坐标下标都进行-1的操作。而且要注意,这里的循环一定要用一个死循环,落棋再退出,因为玩家有无数种理由,无限输错。
void Playermove(char Checkerboard[ROW][COL],int row,int col)
{
    int i = 0;
    int j = 0;
    while(1)
    {
        printf("请玩家输入坐标:");
        scanf("%d%d",&i,&j);
        if(i>=1&&i<=row&&j>=1&&j<=col)
        {
            if(Checkerboard[i-1][j-1]==' ')
            {
                Checkerboard[i-1][j-1]='o';
                break;
            }
            else
            {
                printf("对不起,该坐标被占用,请重新输\n");
            }
        }
        else
        {
            printf("对不起,您的输入有误,请重新输\n");
        }
    }
}

电脑下棋

这里要用到rand产生一个随机数,先加头文件stdlib.h,但是rand()函数产生的随机数好像一点也不随机,那我们在加一个srand((unsigned int)time(NULL))(我放在的test.c里)进去让他在随机一点,记得头文件time.h。
void Computermove(char Checkerboard[ROW][COL],int row,int col)
{
    int i = 0;
    int j = 0;
    while(1)
    {
        i=rand()%row;
        j=rand()%col;
        if(Checkerboard[i][j]==' ')
        {
            Checkerboard[i][j]='x';
            break;
        }
    }
}

输赢判定

这里我把棋盘拆成了内块与外块,这样在判定时,不会访问到棋盘以外的地方,解决了越界的问题。
char Judge(char Checkerboard[ROW][COL],int row,int col)
{
    int i = 0;
    int j = 0;
    for(i=1;i<row-1;i++)
    {
        for(j=1;j<col-1;j++)
        {
            if(Checkerboard[i][j]==Checkerboard[i][j+1]&&Checkerboard[i][j]==Checkerboard[i][j-1]&&Checkerboard[i][j]!=' ')
            {
                return Checkerboard[i][j];
            }
            if(Checkerboard[i][j]==Checkerboard[i+1][j]&&Checkerboard[i][j]==Checkerboard[i-1][j]&&Checkerboard[i][j]!=' ')
            {
                return Checkerboard[i][j];
            }
            if(Checkerboard[i][j]==Checkerboard[i+1][j+1]&&Checkerboard[i][j]==Checkerboard[i-1][j-1]&&Checkerboard[i][j]!=' ')
            {
                return Checkerboard[i][j];
            }
            if(Checkerboard[i][j]==Checkerboard[i+1][j-1]&&Checkerboard[i][j]==Checkerboard[i-1][j+1]&&Checkerboard[i][j]!=' ')
            {
                return Checkerboard[i][j];
            }
        }
    }
    for(i=1;i<row-1;i++)
    {
        if(Checkerboard[i][0]==Checkerboard[i+1][0]&&Checkerboard[i][0]==Checkerboard[i-1][0]&&Checkerboard[i][0]!=' ')
            {
                return Checkerboard[i][0];
            }
        if(Checkerboard[i][col-1]==Checkerboard[i+1][col-1]&&Checkerboard[i][col-1]==Checkerboard[i-1][col-1]&&Checkerboard[i][col-1]!=' ')
            {
                return Checkerboard[i][col-1];
            }
    }
    for(j=1;j<col-1;j++)
    {
        if(Checkerboard[0][j]==Checkerboard[0][j+1]&&Checkerboard[0][j]==Checkerboard[0][j-1]&&Checkerboard[0][j]!=' ')
            {
                return Checkerboard[0][j];
            }
        if(Checkerboard[row-1][j]==Checkerboard[row-1][j+1]&&Checkerboard[row-1][j]==Checkerboard[row-1][j-1]&&Checkerboard[row-1][j]!=' ')
            {
                return Checkerboard[row-1][j];
            }
    }
    if (Full(Checkerboard,ROW,COL))
    {
        return 'W';
    }
    return ' ';
}
这里有一个平局(流局)的函数,赶紧带上
static int Full(char Checkerboard[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(Checkerboard[i][j] == ' ')
            {
                return 0;
            }
        }
    }
    return 1;
}

Test.c

这样一个简单的三子棋游戏核心的内容就完成了,然后我们进入test.c文件中,就可以直接调用之前写的文件。写完以后再用cls清一下屏幕,把多余的内容清理干净,玩家不会找不到自己玩到哪里了。
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()
{
    printf("■■■■■■三子棋游戏■■■■■■\n");
    printf("■■■■■■■■■■■■■■■■■\n");
    printf("■■■■■■■■■■■■■■■■■\n");
    printf("■■■■■■1.开始游戏■■■■■■\n");
    printf("■■■■■■■■■■■■■■■■■\n");
    printf("■■■■■■0.退出游戏■■■■■■\n");
    printf("■■■■■■■■■■■■■■■■■\n");
}
void game()
{
    char ret = 0;
    char Checkerboard[ROW][COL] = {0};
    srand((unsigned int)time(NULL));
    Initboard(Checkerboard,ROW,COL);
    Printboard(Checkerboard,ROW,COL);
    while(1)
    {
        Playermove(Checkerboard,ROW,COL);
        system("cls");
        ret=Judge(Checkerboard,ROW,COL);
        if(ret!=' ')
        {
            break;
        }
        Computermove(Checkerboard,ROW,COL);
        ret=Judge(Checkerboard,ROW,COL);
        if(ret!=' ')
        {
            break;
        }
        Printboard(Checkerboard,ROW,COL);
    }
    if(ret=='o')
    {
        printf("恭喜您,击败电脑\n");
        Printboard(Checkerboard,ROW,COL);
    }
    else
    {
        if(ret=='x')
        {
            printf("很遗憾,您被电脑击败\n");
            Printboard(Checkerboard,ROW,COL);
        }
        else
        {
            if(ret=='W')
            {
                printf("很遗憾,您和电脑平局\n");
                Printboard(Checkerboard,ROW,COL);
            }
        }
    }
}
void test()
{
    int input = 0;
    do
    {
        menu();
        printf("请输入指令:");
        scanf("%d",&input);
        switch(input)
        {
        case 0:
            printf("即将退出游戏\n");
            Sleep(2000);
            system("cls");
            break;
        case 1:
            printf("游戏即将开始\n");
            Sleep(2000);
            system("cls");
            game();
            break;
        default :
            printf("输入错误,请您重新输入\n");
            break;
        }
    }
    while(input);
}

int main()
{
    test();
    return 0;
}

Game.h

头文件,这里定义了一个宏,row和col可以自行修改棋盘的大小,我这里演示用的5行5列的。注意test调用game的每一个函数都要写,不要偷懒TvT。
#ifndef __GAME_H__
#define __GAME_H__

#define ROW 5
#define COL 5

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

void InitBoard(char board[ROW][COL], int row, int col);
void PrintBoard(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);
char Judge(char board[ROW][COL], int row, int col);
int Full(char board[ROW][COL], int row, int col);



#endif //__GAME_H__

一个简单三子棋游戏就搞定了,这是新手练手的很好的选择,入门的小伙伴们,还不赶紧动手试一下?

猜你喜欢

转载自blog.csdn.net/weixin_39392653/article/details/81188539