溫馨提示×

溫馨提示×

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

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

怎么用C語言實(shí)現(xiàn)三子棋

發(fā)布時(shí)間:2022-01-04 14:45:55 來源:億速云 閱讀:139 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“怎么用C語言實(shí)現(xiàn)三子棋”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

    三子棋

    大家小時(shí)候應(yīng)該都玩過三子棋吧,學(xué)習(xí)了這么久的C語言,我們其實(shí)已經(jīng)具備了做三子棋這種小型項(xiàng)目的能力,今天我會盡量沉浸式的教大家實(shí)現(xiàn)三子棋,如果看完這篇博客還是不會的可以去我最后附上的gitee倉庫鏈接中尋找。但我還是希望大家能自己完成,在三子棋中體現(xiàn)自己的風(fēng)格。

    創(chuàng)建項(xiàng)目環(huán)境

    首先,第一步,打開我們的vs編譯器,新建一個(gè)三子棋項(xiàng)目

    在這個(gè)新建的項(xiàng)目中創(chuàng)建三個(gè)文件

    1.test.c

    2.game.c

    3.game.h

    怎么用C語言實(shí)現(xiàn)三子棋

    我們把函數(shù)聲明和頭文件的引入放在game.h這個(gè)頭文件中

    將一些自定義函數(shù)定義放在game.c中

    將主函數(shù)的編寫放在test.c中

    現(xiàn)在直接上頭文件的內(nèi)容,一會一步一步的教大家實(shí)現(xiàn)頭文件中的接口和引用頭文件的原因

    頭文件內(nèi)容

    #ifndef __GAME_H__
    #define __GAME_H__
    #include<stdio.h>
    #include<stdlib.h>
    #include<time.h>
    #include<Windows.h>
    #define H 3
    #define L 3
    void menu();
    void game();
    void board(char arr[H][L],int x,int y);
    void printfboard(char arr[H][L], int x,int y);
    void  play(char arr[H][L], int x, int y);
    void computerplay(char arr[H][L], int x, int y);
    char win(char arr[H][L],int x,int y);
    #endif
    #ifndef #define #endif是為了防止頭文件重復(fù)引入,其實(shí)在大家自己創(chuàng)建頭文件時(shí)自帶的
    #pramga once
    同樣也可以達(dá)到目的

    編寫main函數(shù)(test.c)

    寫test.c第一步引用頭文件game.h即
    #include"game.h"
    玩游戲一定要有一個(gè)菜單,所以我們需要打印寫一個(gè)菜單,這個(gè)菜單函數(shù)的實(shí)現(xiàn)就在test.c中進(jìn)行即可
    但我們先需要在頭文件中聲明void menu();
    接下來實(shí)現(xiàn)菜單
    void menu(){
    printf("*******************\n");
    printf("***1.play 0.exit***\n");
    printf("*******************\n");
    }
    我們使用了printf函數(shù),我們這個(gè)時(shí)候需要引用帶有標(biāo)準(zhǔn)輸入輸出流的頭文件stdio.h
    然后我們在game.h中加上#include<stdio.h>
    像這種選擇1,開始游戲,選擇退出程序的模式,我們可以直接用switch來實(shí)現(xiàn)
    游戲肯定不止一把,只要用戶不選擇0,就讓用戶一直玩,所以我們這樣編寫主函數(shù)
    int main() {
        int input;
        do{
        menu();
    again:    
        printf("請輸入:");
        scanf("%d", &input);
        switch (input) {
        case 1:
            game();
            break;
        case 0:
            printf("退出游戲\n");
            break;
        default:
            printf("輸入錯誤,請重新輸入\n");
            goto again;
        }
        } while (input);
        return 0;
    }
    為了防止用戶輸入錯誤,直接退出了程序,我們利用goto的特性來實(shí)現(xiàn)

    接下來我們組裝一下,text.c就完成了

     #include"game.h"
    void menu() {
        printf("*********************\n");
        printf("**1.play  0.exit*****\n");
        printf("*********************\n");
    }
    int main() {
        int input;
        do{
        menu();
    again:
        printf("請輸入:");
        scanf("%d", &input);
        switch (input) {
        case 1:
            game();
            break;
        case 0:
            printf("退出游戲\n");
            break;
        default:
            printf("輸入錯誤,請重新輸入\n");
            goto again;
        }
        } while (input);
        return 0;
    }

    實(shí)現(xiàn)每一個(gè)接口函數(shù)

    這一個(gè)過程可能有點(diǎn)復(fù)雜,大家可能需要多多上手實(shí)驗(yàn)

    game函數(shù)是相當(dāng)于game.c的main函數(shù),我們需要一步一步去構(gòu)建

    1.board

    在下三子棋之前我們應(yīng)該知道用什么來承載棋子,三行三列的棋子,正好對應(yīng)了二維數(shù)組的行和列
    我們就用二維數(shù)組來進(jìn)行
    在game函數(shù)中我們可以加入
    int arr[3][3];
    但是在實(shí)際設(shè)計(jì)程序中,不建議大家使用數(shù)字,可能會出現(xiàn)錯誤,而且直接定義三行三列
    之后我們想改造三子棋為五子棋會很麻煩,這個(gè)時(shí)候我們可以用常量來代替
    所以我們應(yīng)該在頭文件中加入這兩行代碼,H代表行,L代表列
    #define H 3
    #define L 3
    void game(){
    char arr[H][L];
    board(arr,H,L);
    }
    board函數(shù)是用來實(shí)現(xiàn)初始化棋盤的,沒有下子的位置都將其初始化為空,即空格
    void board(char arr[H][L], int x, int y) {
        int i, j;
        for (i = 0; i < x; i++) {
            for (j = 0; j < y; j++) {
                arr[i][j] = ' ';
            }
        }
    }

    2.printfboard

    初始化之后,我們需要打印棋盤這個(gè)printfboard函數(shù)是用來打印棋盤的,這一步比較重要,也比較困難,這個(gè)需要大家多動手嘗試,先給大家看看我們理想的棋盤效果

    怎么用C語言實(shí)現(xiàn)三子棋

    從圖中我們可以看到,我們用|和-作為分割符

    void printfboard(char arr[H][L], int x, int y) {
        for (int i = 0; i < x; i++) {
            for (int j = 0; j < y; j++) {
                printf(" %c ", arr[i][j]);
                if (j < y - 1)
                    printf("|");
            }
            printf("\n");
            if (i < x - 1) {
                for (int j = 0; j < y; j++) {
                    printf("---");
                    if (j < y - 1)
                        printf("|");
                }
                printf("\n");
            }
        }
    }
    接下來講game函數(shù)改造為
    void game(){
    char arr[H][L];
    board(arr,H,L);
    printfboard(arr,H,L);
    }

    這個(gè)函數(shù)的實(shí)現(xiàn)并不簡單,希望大家多多嘗試

    3.play

    接下來我們開始下棋了,我們先人為固定,我們下的是&lsquo;*&rsquo;,電腦下的是&lsquo;#&rsquo;

    首先,用戶并不知道數(shù)組下標(biāo)是從零開始的,我們需要設(shè)計(jì)從1開始

    其次,我們需要提醒用戶的錯誤下棋,比如下在已有棋子的地方和下在棋盤以外

    最后,我們需要提醒用戶正確的下棋方法,防止出現(xiàn)程序錯誤

    void play(char arr[H][L], int x,int y) {
        int i, j;
        again:
        printf("(提示,以x y的形式輸入,x代表行,y代表列)請輸入你要下棋的位置:");
        scanf("%d %d", &i, &j);
        if (i >= 1 && i <= 3 && j >= 1 && j <= 3) {
            if (arr[i - 1][j - 1] != ' ') {
                printf("該位置以有棋子,請重新輸入");
                goto again;
            }
            else
            {
                arr[i-1][j-1] = '*';
                printfboard(arr, x, y);//下完棋打印棋盤
            }
        }
        else
        {
            printf("輸入錯誤,請重新輸入");
            goto again;
        }
     
    }

    4.computerplay

    玩家下完之后,需要電腦來下棋,電腦下棋就需要隨機(jī)數(shù)rand來進(jìn)行

    首先我們在頭文件中引用
    #include<time.h>
    #include<stdlib.h>
    computerplay的要點(diǎn)與play一致
    void computerplay(char arr[H][L], int x, int y) {
        int i, j;
        srand((unsigned)time(NULL));//作為隨機(jī)數(shù)的生成起點(diǎn)
    again:    i = rand()%x;   //這樣i和j都只能是0 1 2符合數(shù)組下標(biāo)規(guī)則
        j = rand() % y;
        if (arr[i][j] == ' ')
        {
            arr[i][j] = '#';
            printfboard(arr, H, L);
        }
        else goto again;
    }
    電腦和人在還沒有結(jié)束之前需要一直下,而且電腦有時(shí)候下的很快,我們需要用Sleep休息一下
    void game() {
        char arr[H][L] = { 0 };
        board(arr, H, L);
        printfboard(arr, H, L);
        while (1) {
            play(arr, H, L);
            printf("電腦正在下棋請稍等\n");
            Sleep(1000);
            computerplay(arr, H, L);
        }
    }

    5.win

    接下來便是整個(gè)三子棋的最后一步,判斷輸贏

    我們先想一想輸贏的條件,連成一條線就是贏,沒有位置就是平局
    平局的條件比較好判斷,但判斷贏我們找不到好的方法就只能一一列舉
    但是我們可以想一些有用的思路,我們從行和列交叉一次判讀
    如果相等且不為空格直接返回
    當(dāng)棋盤滿了,返回!
    char win(char arr[H][L], int x, int y) {
        int i, j;
        int flag = 0; 
        for (i = 0; i < x; i++) {   //行
            for (j = 0; j < y - 2; j++) {
                if (arr[i][j] == arr[i][j + 1] && arr[i][j + 1] == arr[i][j + 2] && arr[i][j] != ' ')
                    return arr[i][j];
            }
        }
        for (j = 0; j < y; j++) {  //列
            for (i = 0; i < x - 2; i++) {
                if (arr[i][j] == arr[i + 1][j] && arr[i + 1][j] == arr[i + 2][j] && arr[i][j] != ' ')
                    return arr[i][j];
            }
        }
        for (i = 0; i < x - 2; i++) {  //對角線
            for (j = 0; j < y - 2; j++) {
                if (arr[i][j] == arr[i + 1][j + 1] && arr[i + 1][j + 1] == arr[i + 2][j + 2] && arr[i][j] != ' ')
                    return arr[i][j];
            }
            for (i = 0; i < x; i++) {//對角線
                for (j = y - 1; j > 1; j--) {
                    if (arr[i][j] == arr[i + 1][j - 1] && arr[i + 1][j - 1] == arr[i + 2][j - 2] && arr[i][j] != ' ')
                        return arr[i][j];
                }
     
            }
     
        }
        for (i = 0; i < x; i++) {
            for (j = 0; j < y; j++) {
                if (arr[i][j] == ' ')
                    flag = 1;
            }
        }
        if (flag == 1)
            return ' ';
        else
            return '!';
    }

      再將game進(jìn)行改造

    void game() {
        char arr[H][L] = { 0 };
        char ret;
        board(arr, H, L);
        printfboard(arr, H, L);
        while (1) {
            play(arr, H, L);
            ret = win(arr, H, L);
            if (ret != ' ')
                break;
            printf("電腦正在下棋請稍等\n");
            Sleep(1000);
            computerplay(arr, H, L);
            ret = win(arr, H, L);
            if (ret != ' ')
                break;
        }
        if (ret == '*')
            printf("恭喜你獲勝了\n");
        else if (ret == '#')
            printf("很遺憾你輸了\n");
        else
            printf("勢均力敵,再接再厲\n");
    }

    然后將game.c拼裝在一起就完事了

    #include"game.h"
    void board(char arr[H][L], int x, int y) {
        int i, j;
        for (i = 0; i < x; i++) {
            for (j = 0; j < y; j++) {
                arr[i][j] = ' ';
            }
        }
    }
    void printfboard(char arr[H][L], int x, int y) {
        for (int i = 0; i < x; i++) {
            for (int j = 0; j < y; j++) {
                printf(" %c ", arr[i][j]);
                if (j < y - 1)
                    printf("|");
            }
            printf("\n");
            if (i < x - 1) {
                for (int j = 0; j < y; j++) {
                    printf("---");
                    if (j < y - 1)
                        printf("|");
                }
                printf("\n");
            }
        }
    }
    void play(char arr[H][L], int x,int y) {
        int i, j;
        again:
        printf("(提示,以x y的形式輸入,x代表行,y代表列)請輸入你要下棋的位置:");
        scanf("%d %d", &i, &j);
        if (i >= 1 && i <= 3 && j >= 1 && j <= 3) {
            if (arr[i - 1][j - 1] != ' ') {
                printf("該位置以有棋子,請重新輸入");
                goto again;
            }
            else
            {
                arr[i-1][j-1] = '*';
                printfboard(arr, x, y);
            }
        }
        else
        {
            printf("輸入錯誤,請重新輸入");
            goto again;
        }
     
    }
    void computerplay(char arr[H][L], int x, int y) {
        int i, j;
        srand((unsigned)time(NULL));//作為隨機(jī)數(shù)的生成起點(diǎn)
    again:    i = rand()%x;   //這樣i和j都只能是0 1 2符合數(shù)組下標(biāo)規(guī)則
        j = rand() % y;
        if (arr[i][j] == ' ')
        {
            arr[i][j] = '#';
            printfboard(arr, H, L);
        }
        else goto again;
    }
    char win(char arr[H][L], int x, int y) {
        int i, j;
        int flag = 0;
        for (i = 0; i < x; i++) {
            for (j = 0; j < y - 2; j++) {
                if (arr[i][j] == arr[i][j + 1] && arr[i][j + 1] == arr[i][j + 2] && arr[i][j] != ' ')
                    return arr[i][j];
            }
        }
        for (j = 0; j < y; j++) {
            for (i = 0; i < x - 2; i++) {
                if (arr[i][j] == arr[i + 1][j] && arr[i + 1][j] == arr[i + 2][j] && arr[i][j] != ' ')
                    return arr[i][j];
            }
        }
        for (i = 0; i < x - 2; i++) {
            for (j = 0; j < y - 2; j++) {
                if (arr[i][j] == arr[i + 1][j + 1] && arr[i + 1][j + 1] == arr[i + 2][j + 2] && arr[i][j] != ' ')
                    return arr[i][j];
            }
            for (i = 0; i < x; i++) {
                for (j = y - 1; j > 1; j--) {
                    if (arr[i][j] == arr[i + 1][j - 1] && arr[i + 1][j - 1] == arr[i + 2][j - 2] && arr[i][j] != ' ')
                        return arr[i][j];
                }
     
            }
     
        }
        for (i = 0; i < x; i++) {
            for (j = 0; j < y; j++) {
                if (arr[i][j] == ' ')
                    flag = 1;
            }
        }
        if (flag == 1)
            return ' ';
        else
            return '!';
    }
    void game() {
        char arr[H][L] = { 0 };
        char ret;
        board(arr, H, L);
        printfboard(arr, H, L);
        while (1) {
            play(arr, H, L);
            ret = win(arr, H, L);
            if (ret != ' ')
                break;
            printf("電腦正在下棋請稍等\n");
            Sleep(1000);
            computerplay(arr, H, L);
            ret = win(arr, H, L);
            if (ret != ' ')
                break;
        }
        if (ret == '*')
            printf("恭喜你獲勝了\n");
        else if (ret == '#')
            printf("很遺憾你輸了\n");
        else
            printf("勢均力敵,再接再厲\n");
    }

    “怎么用C語言實(shí)現(xiàn)三子棋”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

    向AI問一下細(xì)節(jié)

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

    AI