三子棋(贼菜的算法)

不是标题党!!!
不是标题党!!!
不是标题党!!!
重要事情说三遍,嗯,就这样
C语言学了这么久没想到写一个这么简单的程序自己还是这么菜,看来C语言学习任重而道远。
说说写三子棋的心路历程吧……
在项目里创建三个文件,分别是game.h,game.c,play.c。分别是头文件,功能函数文件,主函数文件。
game.h文件中有库函数的调用函数声明,和功能函数的声明

#ifndef __Game_h__
#define __Game_h__

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

#define ROW 3
#define COL 3

void InitTable(char chessTable[ROW][COL]);
void MoveChess(char chessTable[ROW][COL]);
void ShowTable(char chessTable[ROW][COL]);
char is_win(char chessTable[ROW][COL]);

#endif // !__Game_h__

下面便是比较核心的,也是费时最长的部分:功能函数。四个函数,如头文件声明一般。

这是用来初始化棋盘的函数,全置为空格,其实更好的办法是使用memset()函数对数组初始化,只是自己开始没有想到。当然别忘记在game.h中加入该函数的头文件#include < string.h >。

void InitTable(char chessTable[ROW][COL])//棋盘初始化
{
    int row = 0;
    int col = 0;
    for (row = 0; row < ROW; row++)
    {
        for (col = 0; col < COL; col++)
            chessTable[row][col] = ' ';
    }
}

这个是打印棋盘的函数,其实是很烂的算法

void ShowTable(char chessTable[ROW][COL])//打印棋盘
{   
    int row = 0;
    int col = 0;
    for (row = 0; row < ROW; row++)
    {
        for (col = 0; col < COL; col++)
        {
            printf("%c ", chessTable[row][col]);
            if (col < COL - 1)
                printf("|");
        }
        if (row < ROW - 1)
        {
            printf("\n--|--|--\n");
        }
    }
    printf("\n");
}

下面这部分是我写的最繁杂的一部分,集合许多算法在其中,没有写成小模块的功能函数来实现,也许读者看完了会有种一头雾水的感觉吧,写到这自己真的笑了…..

#define _CRT_SECURE_NO_WARNINGS

#include "game.h"

void InitTable(char chessTable[Row][Col])//初始化
{
    int row = 0;
    int col = 0;
    for (row = 0; row < Row; row++)
    {
        for (col = 0; col < Col; col++)
            chessTable[row][col] = ' ';
    }
}

void ShowTable(char chessTable[Row][Col])//打印棋盘
{   
    int row = 0;
    int col = 0;
    for (row = 0; row < Row; row++)
    {
        for (col = 0; col < Col; col++)
        {
            printf("%c ", chessTable[row][col]);
            if (col < Col - 1)
                printf("|");
        }
        if (row < Row - 1)
        {
            printf("\n--|--|--\n");
        }
    }
    printf("\n");
}

void MoveChess(char chessTable[Row][Col])
{
    int times = 0;//判断棋盘已满变量
    int player_row = 0;
    int player_col = 0;
    int computer_row = 0;
    int computer_col = 0;
    char chess_1 = '*';
    char chess_2 = 'O';

    srand((unsigned int)time(NULL));//产生随机数,让电脑落子

    for (times = 0; times <=Row*Col / 2; times++)
    {
        printf("电脑落子...\n");//为电脑轮次
        do
        {
            computer_row = rand() % Row;
            computer_col = rand() % Col;
        } while (chessTable[computer_row][computer_col] != ' ');
        chessTable[computer_row][computer_col] = '*';

        if (is_win(chessTable)=='*')
        {
            ShowTable(chessTable);
            printf("电脑赢了...\n");
            break;
        }
        ShowTable(chessTable);

        if (times ==4)
        { 
            printf("棋盘满了...\n");
            printf("游戏结束,平局....\n");
            break;
        }

        while (1)//玩家轮次
        {
            printf("输入你想落子的坐标...\n");//人的轮次
            scanf("%d%d", &player_row, &player_col);

            if (player_row > 0 && player_row <= Row && player_col > 0 && player_col <= Col 
                        && chessTable[player_row-1][player_col-1]==' ')
            {
                chessTable[player_row - 1][player_col - 1] = 'O';
                break;
            }
            else
                printf("输入有误,请重新输入...\n");
        }

        if (is_win(chessTable)=='O')
        {
            printf("玩家落子...");
            ShowTable(chessTable);
            printf("玩家胜利...\n");
            break;
        }
        ShowTable(chessTable);
    }
}
char is_win(char chessTable[Row][Col])//判赢函数
{
    int i = 0;
    for (i = 0; i < Row; i++)//将每一行判断
    {
        if (chessTable[i][0] == chessTable[i][1] && chessTable[i][1] == chessTable[i][2])
            return chessTable[i][0];
    }
    for (i = 0; i < Col; i++)//将每一列进行判断
    {
        if (chessTable[0][i] == chessTable[1][i] && chessTable[1][i] == chessTable[2][i])
            return chessTable[0][i];
    }
    if ((chessTable[0][0] == chessTable[1][1] && chessTable[1][1] == chessTable[2][2])//斜线判断
        || (chessTable[2][2] == chessTable[1][1] && chessTable[1][1] == chessTable[2][0]))
        return chessTable[1][1];
    else
        return 0;

}

最一部分是判赢函数,就是判断在玩家落下棋子的坐标是否与玩家的棋子连城三点一线,从横、竖、对角线,三种类型判断

char is_win(char chessTable[ROW][COL])//判赢函数
{
    int i = 0;
    for (i = 0; i < ROW; i++)//将每一行判断
    {
        if (chessTable[i][0] == chessTable[i][1] && chessTable[i][1] == chessTable[i][2])
            return chessTable[i][0];
    }
    for (i = 0; i < COL; i++)//将每一列进行判断
    {
        if (chessTable[0][i] == chessTable[1][i] && chessTable[1][i] == chessTable[2][i])
            return chessTable[0][i];
    }
    if ((chessTable[0][0] == chessTable[1][1] && chessTable[1][1] == chessTable[2][2])//斜线判断
        || (chessTable[2][2] == chessTable[1][1] && chessTable[1][1] == chessTable[2][0]))
        return chessTable[1][1];
    else
        return 0;

}

最最最后,就是游戏入口的部分,界面比较简单。其实是自己想象力不足,懂得少,高级的界面设计不会写。其实本来还想写PVP函数的函数,奈何已经写了一周,不敢再拖了,就先写这么点吧/手动笑哭

#define _CRT_SECURE_NO_WARNINGS
#include "game.h"

void PVE()
{
    char ChessTable[ROW][COL] = { 0 };

    printf("注意人的落子为'O',电脑落子为'*'\n");

    InitTable(ChessTable);

    MoveChess(ChessTable,1);

}


void test()
{
    int choose;

    do
    {
        printf("*************************************\n");
        printf("*********1.PVE  2.exit  ********\n");
        printf("请输入你的选择:....\n");
        scanf("%d", &choose);
        switch (choose)
        {
        case 1: PVE();//人机对战
            printf("\n");
            break;
        case 2:
            break;
        default:
            printf("输入错误,请重新输入....\n");
        }
    } while (2 != choose);

}

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

最后,复制粘贴不修改就能用,嗯…传个想本来想让电脑赢,现实却是你还要我怎样的图吧
这里写图片描述
PS:欢迎各位读者评论,点赞,提意见给我,谢谢….

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值