溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

三子棋分析與實(shí)現(xiàn)——C語(yǔ)言

發(fā)布時(shí)間:2020-07-24 16:37:39 來(lái)源:網(wǎng)絡(luò) 閱讀:329 作者:Xin_37 欄目:編程語(yǔ)言

三子棋作為一款經(jīng)典的小游戲,對(duì)于初學(xué)C語(yǔ)言的我們?nèi)绻?可以熟練了解并可以實(shí)現(xiàn)其游戲功能,則對(duì)于以后更系統(tǒng)的學(xué)習(xí)C語(yǔ)言有很好幫助。下來(lái)我分享一下我在編程時(shí)的感悟和代碼

首先介紹一下三子棋規(guī)則:只要將自己的棋連成一條線(行,列,斜線),即為贏
如圖:

三子棋分析與實(shí)現(xiàn)——C語(yǔ)言

先根據(jù)圖和玩法大致有個(gè)思路:

1.我們可以將棋盤看做是一個(gè)三行三列的二維數(shù)組,且每行每列用線隔開(kāi)以便區(qū)分
2.分為電腦下棋和玩家下棋(電腦先下和玩家先下)
3.判斷輸贏(玩家贏,電腦贏和平局)

大致思路即為上面分析,下面開(kāi)始寫代碼:

創(chuàng)建tset.c,game.c和head.h三個(gè)文件

1.在test.c中編寫主函數(shù)并寫出游戲菜單

在這里我分為電腦先下和玩家先下,代碼如下;

void menu()
{
    printf("***************************************\n");
    printf("*      1.play             0.exit      *\n");
    printf("***************************************\n");
}
void first_move()
{
    printf("***************************************\n");
    printf("*  1.computer first   2.player first  *\n");
    printf("***************************************\n");
}
void game()
{
   return 0;
}
int main()
{
    int choice;
    srand((unsigned int)time(NULL));//產(chǎn)生隨機(jī)數(shù)
    do
    {
        menu();  
        printf("請(qǐng)選擇:");
        scanf("%d", &choice);
        switch (choice)
        {
        case 1:
            game();
            break;
        case 0:
            break;
        default:
            printf("輸入錯(cuò)誤請(qǐng)重新輸入.\n");
            break;
        }
    } while (choice);
    return 0;
}

2.下來(lái)逐步在game.c中實(shí)現(xiàn)所需功能并且在game函數(shù)中調(diào)用

先打印出棋盤,并將棋盤初始化為空格。代碼如下;

void show_board(char board[ROWS][COLS], int rows, int cols)//打印棋盤
{
    int i;
    for (int i = 0; i < rows; i++)
    {
        printf("  %c | %c | %c  \n", board[i][0], board[i][1], board[i][2]);
        if (i != rows - 1)
            printf(" ---|---|--- \n");
    }
}

void init_board(char board[ROWS][COLS], int rows, int cols)//將數(shù)組初始化為空格
{
    int i, j;
    for (i = 0; i < rows; i++)
    {
        for (j = 0; j < cols; j++)
        {
            board[i][j] = ' ';
        }
    }
}

效果如圖
三子棋分析與實(shí)現(xiàn)——C語(yǔ)言

3.編寫玩家落子的代碼

玩家數(shù)輸入二維數(shù)組的坐標(biāo),這時(shí)需要判斷玩家輸入坐標(biāo)是否合理以及在此坐標(biāo)上是否有棋子,代碼如下;

void player_move(char board[ROWS][COLS], int rows, int cols)//玩家落子
{
    int x, y;
    printf("玩家落子:\n");
    while (1)
    {
        scanf("%d %d", &x, &y);
        if (x >= 1 && x <= rows && y >= 1 && y <= cols)
        {
            if (board[x - 1][y - 1] == ' ')
            {
                board[x - 1][y - 1] = '*';
                break;
            }
            else printf("位置已被占用!請(qǐng)?jiān)僭囈淮巍n");
        }
        else printf("輸入錯(cuò)誤!請(qǐng)重新輸入.\n");
    }
}

4.玩成電腦落子

這里實(shí)現(xiàn)的是電腦在為空格的數(shù)組中隨機(jī)落子。代碼如下;

void computer_move(char board[ROWS][COLS], int rows, int cols)// 電腦落子
{

    int x, y;
    printf("電腦落子:\n");
    while (1)
    {
        x = rand() % rows;
        y = rand() % cols;
        if (board[x][y] == ' ')
        {
            board[x][y] = '#';
            break;
        }
    }
}

5.最后就只剩判斷輸贏

先討論玩家或者電腦贏的情況;代碼如下;

char check_win(char board[ROWS][COLS], int rows, int cols)//判斷輸贏
{
    int i;
    for (i = 0; i < rows; i++)
    {
        if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')
            return board[i][1];
    }
    for (i = 0; i < cols; i++)
    {
        if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
            return board[1][i];
    }
    if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
        return board[1][1];
    else if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ')
        return board[1][1];
    else if (is_full(board, rows, cols))
        return 'q';
    return 0;
}

這是考慮是平局的情況,平局則為棋盤下滿都沒(méi)有輸贏,可以遍歷整個(gè)數(shù)組(棋盤)若沒(méi)有空格就為平局。代碼如下;

static int is_full(char board[ROWS][COLS], int rows, int cols)//檢測(cè)是否為平局
{
    int i, j;
    for (i = 0; i < rows; i++)
    {
        for (j = 0; j < cols; j++)
        {
            if (board[i][j] == ' ')
                return 0;
        }
    }
    return 1;
}

初步測(cè)試結(jié)果如下

三子棋分析與實(shí)現(xiàn)——C語(yǔ)言

在圖中我們可以看出電腦可以有贏的機(jī)會(huì)卻在隨機(jī)下子,這樣的游戲是沒(méi)有挑戰(zhàn)的。因此應(yīng)該修改下電腦下子的代碼,使其智能化。我們可在電腦落子時(shí)判斷如果有在同行,同列或者斜線上有相同棋子的,電腦則優(yōu)先落子在其未成一條線的空格處,這樣實(shí)現(xiàn)簡(jiǎn)單智能化

代碼如下;

void computer_move(char board[ROWS][COLS], int rows, int cols)//智能化電腦落子
{
    int x, y, i;
    printf("電腦落子:\n");
    while (1)
    {
        x = rand() % rows;
        y = rand() % cols;
        for (i = 0; i < rows; i++)
        {
            if (board[i][0] == board[i][1] && board[i][0] == '#' && board[i][2] == ' ')
            {
                board[i][2] = '#';
                goto flag1;
            }
            else if (board[i][1] == board[i][2] && board[i][1] == '#' && board[i][0] == ' ')
            {
                board[i][0] = '#';
                goto flag1;
            }
            else if (board[i][0] == board[i][2] && board[i][2] == '#' && board[i][1] == ' ')
            {
                board[i][1] = '#';
                goto flag1;
            }
            else if (board[0][i] == board[1][i] && board[0][i] == '#' && board[2][i] == ' ')
            {
                board[2][i] = '#';
                goto flag1;
            }
            else if (board[1][i] == board[2][i] && board[1][i] == '#' && board[0][i] == ' ')
            {
                board[0][i] = '#';
                goto flag1;
            }
            else if (board[0][i] == board[2][i] && board[2][i] == '#' && board[1][i] == ' ')
            {
                board[1][i] = '#';
                goto flag1;
            }
            else if (board[0][0] == board[1][1] && board[0][0] == '#' && board[2][2] == ' ')
            {
                board[2][2] = '#';
                goto flag1;
            }
            else if (board[1][1] == board[2][2] && board[1][1] == '#' && board[0][0] == ' ')
            {
                board[0][0] = '#';
                goto flag1;
            }
            else if (board[0][0] == board[2][2] && board[0][0] == '#' && board[1][1] == ' ')
            {
                board[1][1] = '#';
                goto flag1;
            }
            else if (board[0][2] == board[1][1] && board[1][1] == '#' && board[2][0] == ' ')
            {
                board[2][0] = '#';
                goto flag1;
            }
            else if (board[1][1] == board[2][0] && board[1][1] == '#' && board[0][2] == ' ')
            {
                board[0][2] = '#';
                goto flag1;
            }
            else if (board[2][0] == board[0][2] && board[2][0] == '#' && board[1][1] == ' ')
            {
                board[1][1] = '#';
                goto flag1;
            }
        }
        for (i = 0; i < rows; i++)
        {
            if (board[i][0] == board[i][1] && board[i][0] == '*' && board[i][2] == ' ')
            {
                board[i][2] = '#';
                goto flag1;
            }
            else if (board[i][1] == board[i][2] && board[i][1] == '*' && board[i][0] == ' ')
            {
                board[i][0] = '#';
                goto flag1;
            }
            else if (board[i][0] == board[i][2] && board[i][2] == '*' && board[i][1] == ' ')
            {
                board[i][1] = '#';
                goto flag1;
            }
            else if (board[0][i] == board[1][i] && board[0][i] == '*' && board[2][i] == ' ')
            {
                board[2][i] = '#';
                goto flag1;
            }
            else if (board[1][i] == board[2][i] && board[1][i] == '*' && board[0][i] == ' ')
            {
                board[0][i] = '#';
                goto flag1;
            }
            else if (board[0][i] == board[2][i] && board[2][i] == '*' && board[1][i] == ' ')
            {
                board[1][i] = '#';
                goto flag1;
            }
            else if (board[0][0] == board[1][1] && board[0][0] == '*' && board[2][2] == ' ')
            {
                board[2][2] = '#';
                goto flag1;
            }
            else if (board[1][1] == board[2][2] && board[1][1] == '*' && board[0][0] == ' ')
            {
                board[0][0] = '#';
                goto flag1;
            }
            else if (board[0][0] == board[2][2] && board[0][0] == '*' && board[1][1] == ' ')
            {
                board[1][1] = '#';
                goto flag1;
            }
            else if (board[0][2] == board[1][1] && board[1][1] == '*' && board[2][0] == ' ')
            {
                board[2][0] = '#';
                goto flag1;
            }
            else if (board[1][1] == board[2][0] && board[1][1] == '*' && board[0][2] == ' ')
            {
                board[0][2] = '#';
                goto flag1;
            }
            else if (board[2][0] == board[0][2] && board[2][0] == '*' && board[1][1] == ' ')
            {
                board[1][1] = '#';
                goto flag1;
            }
        }
        if (board[x][y] == ' ')
        {
            board[x][y] = '#';
            goto flag1;
        }
    }
flag1:;
}

效果如圖;
三子棋分析與實(shí)現(xiàn)——C語(yǔ)言

檢測(cè)所有結(jié)果

電腦贏
三子棋分析與實(shí)現(xiàn)——C語(yǔ)言
玩家贏
三子棋分析與實(shí)現(xiàn)——C語(yǔ)言
平局
三子棋分析與實(shí)現(xiàn)——C語(yǔ)言

全部代碼

tese.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"head.h"
void menu()
{
    printf("***************************************\n");
    printf("*      1.play             0.exit      *\n");
    printf("***************************************\n");
}
void first_move()
{
    printf("***************************************\n");
    printf("*  1.computer first   2.player first  *\n");
    printf("***************************************\n");
}
void game()
{
    int choice, win;
    char board[ROWS][COLS];
    init_board(board, ROWS, COLS);
    first_move();
flag:
    printf("請(qǐng)選擇");
    scanf("%d", &choice);
    switch (choice)
    {
    case 1: //電腦先落子
        do
        {
            computer_move(board, ROWS, COLS);   //電腦落子
            show_board(board, ROWS, COLS);      //打印棋盤
            win = check_win(board, ROWS, COLS); 
            if (win != 0)  //沒(méi)贏
                break;
            player_move(board, ROWS, COLS);     //玩家落子
            show_board(board, ROWS, COLS);      // 打印棋盤
            win = check_win(board, ROWS, COLS);
        } while (win == 0);
        if (win == '#')
            printf("很遺憾,你輸了!\n");
        if (win == '*')
            printf("恭喜,你贏了!\n");
        if (win == 'q')
            printf("平局\n");
        break;
    case 2: //玩家先落子
        show_board(board, ROWS, COLS);
        do
        {
            player_move(board, ROWS, COLS);
            show_board(board, ROWS, COLS);
            win = check_win(board, ROWS, COLS);
            if (win != 0)
                break;
            computer_move(board, ROWS, COLS);
            show_board(board, ROWS, COLS);
            win = check_win(board, ROWS, COLS);
        } while (win == 0);
        if (win == '#')
            printf("很遺憾,你輸了!\n");
        if (win == '*')
            printf("恭喜,你贏了!\n");
        if (win == 'q')
            printf("平局\n");
        break;
    default:
        printf("輸入錯(cuò)誤,請(qǐng)重新輸入\n");
        goto flag;
    }
}
int main()
{
    int choice;
    srand((unsigned int)time(NULL));//產(chǎn)生隨機(jī)數(shù)
    do
    {
        menu();  
        printf("請(qǐng)選擇:");
        scanf("%d", &choice);
        switch (choice)
        {
        case 1:
            game();
            break;
        case 0:
            break;
        default:
            printf("輸入錯(cuò)誤請(qǐng)重新輸入.\n");
            break;
        }
    } while (choice);
    return 0;
}

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"head.h"

void show_board(char board[ROWS][COLS], int rows, int cols)//打印棋盤
{
    int i;
    for (int i = 0; i < rows; i++)
    {
        printf("  %c | %c | %c  \n", board[i][0], board[i][1], board[i][2]);
        if (i != rows - 1)
            printf(" ---|---|--- \n");
    }
}

void init_board(char board[ROWS][COLS], int rows, int cols)//將數(shù)組初始化為空格
{
    int i, j;
    for (i = 0; i < rows; i++)
    {
        for (j = 0; j < cols; j++)
        {
            board[i][j] = ' ';
        }
    }
}

//void computer_move(char board[ROWS][COLS], int rows, int cols)// 電腦落子
//{
//
//  int x, y;
//  printf("電腦落子:\n");
//  while (1)
//  {
//      x = rand() % rows;
//      y = rand() % cols;
//      if (board[x][y] == ' ')
//      {
//          board[x][y] = '#';
//          break;
//      }
//  }
//}
void computer_move(char board[ROWS][COLS], int rows, int cols)//智能化電腦落子
{
    int x, y, i;
    printf("電腦落子:\n");
    while (1)
    {
        x = rand() % rows;
        y = rand() % cols;
        for (i = 0; i < rows; i++)
        {
            if (board[i][0] == board[i][1] && board[i][0] == '#' && board[i][2] == ' ')
            {
                board[i][2] = '#';
                goto flag1;
            }
            else if (board[i][1] == board[i][2] && board[i][1] == '#' && board[i][0] == ' ')
            {
                board[i][0] = '#';
                goto flag1;
            }
            else if (board[i][0] == board[i][2] && board[i][2] == '#' && board[i][1] == ' ')
            {
                board[i][1] = '#';
                goto flag1;
            }
            else if (board[0][i] == board[1][i] && board[0][i] == '#' && board[2][i] == ' ')
            {
                board[2][i] = '#';
                goto flag1;
            }
            else if (board[1][i] == board[2][i] && board[1][i] == '#' && board[0][i] == ' ')
            {
                board[0][i] = '#';
                goto flag1;
            }
            else if (board[0][i] == board[2][i] && board[2][i] == '#' && board[1][i] == ' ')
            {
                board[1][i] = '#';
                goto flag1;
            }
            else if (board[0][0] == board[1][1] && board[0][0] == '#' && board[2][2] == ' ')
            {
                board[2][2] = '#';
                goto flag1;
            }
            else if (board[1][1] == board[2][2] && board[1][1] == '#' && board[0][0] == ' ')
            {
                board[0][0] = '#';
                goto flag1;
            }
            else if (board[0][0] == board[2][2] && board[0][0] == '#' && board[1][1] == ' ')
            {
                board[1][1] = '#';
                goto flag1;
            }
            else if (board[0][2] == board[1][1] && board[1][1] == '#' && board[2][0] == ' ')
            {
                board[2][0] = '#';
                goto flag1;
            }
            else if (board[1][1] == board[2][0] && board[1][1] == '#' && board[0][2] == ' ')
            {
                board[0][2] = '#';
                goto flag1;
            }
            else if (board[2][0] == board[0][2] && board[2][0] == '#' && board[1][1] == ' ')
            {
                board[1][1] = '#';
                goto flag1;
            }
        }
        for (i = 0; i < rows; i++)
        {
            if (board[i][0] == board[i][1] && board[i][0] == '*' && board[i][2] == ' ')
            {
                board[i][2] = '#';
                goto flag1;
            }
            else if (board[i][1] == board[i][2] && board[i][1] == '*' && board[i][0] == ' ')
            {
                board[i][0] = '#';
                goto flag1;
            }
            else if (board[i][0] == board[i][2] && board[i][2] == '*' && board[i][1] == ' ')
            {
                board[i][1] = '#';
                goto flag1;
            }
            else if (board[0][i] == board[1][i] && board[0][i] == '*' && board[2][i] == ' ')
            {
                board[2][i] = '#';
                goto flag1;
            }
            else if (board[1][i] == board[2][i] && board[1][i] == '*' && board[0][i] == ' ')
            {
                board[0][i] = '#';
                goto flag1;
            }
            else if (board[0][i] == board[2][i] && board[2][i] == '*' && board[1][i] == ' ')
            {
                board[1][i] = '#';
                goto flag1;
            }
            else if (board[0][0] == board[1][1] && board[0][0] == '*' && board[2][2] == ' ')
            {
                board[2][2] = '#';
                goto flag1;
            }
            else if (board[1][1] == board[2][2] && board[1][1] == '*' && board[0][0] == ' ')
            {
                board[0][0] = '#';
                goto flag1;
            }
            else if (board[0][0] == board[2][2] && board[0][0] == '*' && board[1][1] == ' ')
            {
                board[1][1] = '#';
                goto flag1;
            }
            else if (board[0][2] == board[1][1] && board[1][1] == '*' && board[2][0] == ' ')
            {
                board[2][0] = '#';
                goto flag1;
            }
            else if (board[1][1] == board[2][0] && board[1][1] == '*' && board[0][2] == ' ')
            {
                board[0][2] = '#';
                goto flag1;
            }
            else if (board[2][0] == board[0][2] && board[2][0] == '*' && board[1][1] == ' ')
            {
                board[1][1] = '#';
                goto flag1;
            }
        }
        if (board[x][y] == ' ')
        {
            board[x][y] = '#';
            goto flag1;
        }
    }
flag1:;
}

void player_move(char board[ROWS][COLS], int rows, int cols)//玩家落子
{
    int x, y;
    printf("玩家落子:\n");
    while (1)
    {
        scanf("%d %d", &x, &y);
        if (x >= 1 && x <= rows && y >= 1 && y <= cols)
        {
            if (board[x - 1][y - 1] == ' ')
            {
                board[x - 1][y - 1] = '*';
                break;
            }
            else printf("位置已被占用!請(qǐng)?jiān)僭囈淮?。\n");
        }
        else printf("輸入錯(cuò)誤!請(qǐng)重新輸入.\n");
    }
}

static int is_full(char board[ROWS][COLS], int rows, int cols)//檢測(cè)是否為平局
{
    int i, j;
    for (i = 0; i < rows; i++)
    {
        for (j = 0; j < cols; j++)
        {
            if (board[i][j] == ' ')
                return 0;
        }
    }
    return 1;
}

char check_win(char board[ROWS][COLS], int rows, int cols)//判斷輸贏
{
    int i;
    for (i = 0; i < rows; i++)
    {
        if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')
            return board[i][1];
    }
    for (i = 0; i < cols; i++)
    {
        if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
            return board[1][i];
    }
    if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
        return board[1][1];
    else if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ')
        return board[1][1];
    else if (is_full(board, rows, cols))
        return 'q';
    return 0;
}

head.h

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

#define ROWS 3
#define COLS 3

void show_board(char board[ROWS][COLS], int rows, int cols);//打印棋盤
void init_board(char board[ROWS][COLS], int rows, int cols);//初始化棋盤為空格
void computer_move(char board[ROWS][COLS], int rows, int cols);//電腦落子
void player_move(char board[ROWS][COLS], int rows, int cols);//玩家落子
char check_win(char board[ROWS][COLS], int rows, int cols);//判斷輸贏
向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI