可扩展三子棋^五子棋

一、开始的思路

1.从三子棋开始,先不考虑扩展

(1)、 打印棋盘

打印一个棋盘,如何打印呢?先考虑下棋的位置,是三行三列,所以定义一个数组c[3][3],如何让这个棋盘有分割线呢?分别打印,第一行先输出 a[0][0] | a[0][1] | a[0][2] ,第二行输出—|—|—,依次类推(见函数void dayin (int a[ROW][COL], int row,int col))。打印出的棋盘,每个数值并不为‘ ’,使用循环赋值,使数组元素全为‘ ’(见函数void empty( int a[ROW][COL], int row,int col) ),效果如下图
棋盘

(2)、开始下棋,

写一个菜单,一个简单的函数,内为简单的printf输出即可(见函数void menu () )。用switch,keys语句接收一个数字,判断是否开始游戏(见函数void get_panduan())。
开始下棋分为两布,玩家下棋(见函数void player_move(int a[ROW][COL], int row, int col)
)和电脑下棋(见函数void computer_move(int a[ROW][COL], int row, int col)
)。电脑下棋我们采用生成随机坐标的方法。

(3)、判断输赢

两种情况(见函数int who_win(int a[ROW][COL], int row, int col)

1、棋盘满时或未满时,有一方已连成三个
行三个
列三个
对角线三个
反对角线三个
(有一方赢时 函数返回1,结束游戏,否则不返回游戏继续)

2、棋盘已满,没有人赢,输出平局。

//game.h
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>     //对应printf,scanf
#include<string.h>   //对应sizeof
#include<stdlib.h>    //对应rand()随机生成数
#define ROW 3
#define COL 3
void empty(int a[ROW][COL], int row,int col);
void dayin(int a[ROW][COL], int row, int col);
int full(int a[ROW][COL], int row,int col);
void computer_move(int a[ROW][COL], int row, int col);
void player_move(int a[ROW][COL], int row, int col);
int who_win(int a[ROW][COL], int row, int col);
//game.c  在这里定义游戏函数,核心
#include"game.h"
void empty( int a[ROW][COL], int row,int col)               //1.定义一个将数组致空的循环
{
    int i = 0, j = 0;
    for (i = 0; i < row; i++)
    {
        for (j = 0; j <col; j++)
        {
            a[i][j] = ' ';
        }
    }

}
void dayin (int a[ROW][COL], int row,int col)               //2.打印初始空棋盘
{       
    int i = 0, j = 0;
    for (j = 0; j <= 2; j++)
    {
        printf(" %c ",a[0][j]);
        if (j < 2)
            printf("|");
    }
    printf("\n");                         //打印出第一行的   |   |   ;
    for (j = 0; j <= 2; j++)
    {
        printf("---");
        if (j < 2)
            printf("|");
    }
    printf("\n");

    for (j = 0; j <= 2; j++)    //打印分隔---|---|---
    {
        printf(" %c ",a[1][j]);
        if (j < 2)
            printf("|");      //打印出第二行的   |   |   ;
    }
    printf("\n");

    for (j = 0; j <= 2; j++)    //打印分隔---|---|---
    {
        printf("---");
        if (j < 2)
            printf("|");
    }
    printf("\n");


    for (j = 0; j <= 2; j++)
    {
        printf(" %c ",a[2][j]);
        if (j < 2)
            printf("|");     //打印出第三行的   |   |   ;
    }
    printf("\n\n");

}
int full(int a[ROW][COL],int b, int c)       // 一个判断棋盘某处位置是否为空的函数,参数为该点坐标
{
    if (a[b - 1][c - 1] == ' ')                    //(b,c)为坐标,b-1,c-1为数组元素的下标
        return 1;                                 //该处为空,可以下棋子
    else
        return 0;                                 //该处有棋子,不可下
}

void computer_move(int a[ROW][COL], int row, int col)
{
    int x = 0, y = 0;
    srand((unsigned)time(NULL));
    while (1)
    {
        x = rand() % 4;           //rand随机生成正整数,%3使生成结果<3
        y = rand() % 4;
        if (full(a,x,y))
        {
            a[x-1][y-1] = 'X';
            break;
        }
    }
}
void player_move(int a[ROW][COL], int row, int col)
{
    printf("请玩家下棋\n");
    int x = 0, y = 0;

    while (1)
    {
        scanf("%d %d", &x, &y);
        if (full(a, x, y))
        {
            a[x-1][y-1] = 'O';
            break;
        }
        else
        {
            printf("输入错误,请重新输入!");
        }
    }

}
int who_win(int a[ROW][COL], int row, int col)
{
//一种情况,棋盘未满,但有一方已连成一条线三个,每次下完都要扫描

//判断一行是否全部相同,一个想法,是否可以用循环来比较两元素值是否相等
    int i = 0;
    int j = 0;
    int countO = 0;
    int countX = 0;
    //判断对角线
    for (i = 0; i < row; i++)
    {
        j = i;
        if (a[i][j] == 'O')
        {
            countO++;

        }
        else if (a[i][j] == 'X')
        {
            countX++;
        }
    }
    if (countO == row)
    {
        printf("duijiao玩家赢!恭喜你!\n");
        return 1;
    }
    else if (countX == row)
    {
        printf("很遗憾,电脑赢了,你真的是菜鸡\n");
        return 1;
    }
    //判断反对角线
    countO = 0;
    countX = 0;

    for (i = 0; i < row; i++)
    {
        j = col-1-i;
        if (a[i][j] == 'O')
        {
            countO++;

        }
        else if (a[i][j] == 'X')
        {
            countX++;
        }
    }
    if (countO == row)
    {
        printf("duijiao玩家赢!恭喜你!\n");
        return 1;
    }
    else if (countX == row)
    {
        printf("很遗憾,电脑赢了,你真的是菜鸡\n");
        return 1;
    }
    //判断行
    for (i = 0; i < row; i++)  
    {
        countO = 0;
        countX = 0;
        for (j = 0; j < col; j++)
        {
            if (a[i][j] == 'O')
            {
                countO++;   
            }
            else if (a[i][j] == 'X')            //只要一行里有一个数不满足跟同行其他数相等就没赢,跳出,无需再判断
            {
                countX++;

            }//想到一个问题,通过判断整列是否全为某个元素来判是否有一方获胜,目前这种写法只能写出3*3格为三子棋,4*4格为四子棋,无法做到例如10*10格中下五子棋
        }

        if (countO == col)
        {
            printf("hang玩家赢!恭喜你!\n");
            return 1;
        }
        else if (countX == col)
        {
            printf("很遗憾,电脑赢了,你真的是菜鸡\n");
            return 1;
        }
    }
//判断一列是否全部相同,一个想法,是否可以用循环来比较两元素值是否相等

    for (j = 0; j < col; j++)  
    {
        countO = 0;
        countX = 0;
        for (i = 0; i < row; i++)
        {
            if (a[i][j] == 'O')
            {
                countO++;
            }
            if (a[i][j] == 'X')            //只要一列里有一个数不满足跟同行其他数相等就没赢,跳出,无需再判断
            {
                countX++;
            }
            //想到一个问题,通过判断整列是否全为某个元素来判是否有一方获胜,目前这种写法只能写出3*3格为三子棋,4*4格为四子棋,无法做到例如10*10格中下五子棋

        }

        if (countO == row )
        {
            printf("lie玩家赢!恭喜你!\n");
            return 1;
        }
        else if (countX == row )
        {
            printf("很遗憾,电脑赢了,你真的是菜鸡\n");
            return 1;
        }
    }
//棋盘已满,胜负未分,没有一方连成了一条,判平局
    int num = 0;
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            if((a[i][j]=='O')||(a[i][j] == 'X') )//full函数前面定义为空返回1,不空返回0
            num++;
        }

    }
    if (num == row*col)
    {
        printf("平局\n");
    }
    return 0;
}
//test.c


#include "game.h"
void menu () //     写一个菜单
{
    printf("————————————\n");
    printf("|       1.play         |\n");
    printf("|       0.exit         |\n");
    printf("————————————\n");
}
void get_panduan()  //接收一个数字,判断是否开始玩游戏
{
    int a;
    scanf("%d",&a);
    switch (a)
    {
    case 1:
        printf("开始游戏\n");
        break;
    case 0:
        printf("游戏已退出\n");

        break;
    default:
        printf("输入错误,请重新输入\n");
        break;
    }

}
int main()
{
    int c[ROW][COL] = { 0 };
    int row = ROW;
    int col = COL;
    int sz = sizeof(c) / sizeof(c[0]);
    menu();                          //打印菜单
    get_panduan();                   //判断是否进入游戏
    empty(c,row,col);                //数组致空格 //打印初始空棋盘 //开始下棋,玩家先走
    dayin(c,row,col);              
    while (1)
    {
        player_move(c, row, col);
        dayin(c, row, col);
        if (who_win(c, row, col))
        {
            break;
        }
        computer_move(c, row, col);
        dayin(c, row, col);
        if (who_win(c, row, col))
        {
            break;
        }
    }
    system("pause");
    return 0;
}

这里写图片描述
这里写图片描述
这里写图片描述

让电脑变聪明,后续….

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值