欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言新手初階教程之三子棋實(shí)現(xiàn)

 更新時(shí)間:2022年01月04日 12:47:05   作者:build小春寶  
相信大家在小時(shí)候都用紙和筆與小伙伴們玩過一個(gè)經(jīng)典的游戲之井字棋,即三子棋,下面這篇文章主要給大家介紹了關(guān)于C語言新手初階教程之三子棋實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下

三子棋

大家小時(shí)候應(yīng)該都玩過三子棋吧,學(xué)習(xí)了這么久的C語言,我們其實(shí)已經(jīng)具備了做三子棋這種小型項(xiàng)目的能力,今天我會(huì)盡量沉浸式的教大家實(shí)現(xiàn)三子棋,如果看完這篇博客還是不會(huì)的可以去我最后附上的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

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

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

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

現(xiàn)在直接上頭文件的內(nèi)容,一會(huì)一步一步的教大家實(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("輸入錯(cuò)誤,請重新輸入\n");
        goto again;
    }
    } while (input);
    return 0;
}
為了防止用戶輸入錯(cuò)誤,直接退出了程序,我們利用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("輸入錯(cuò)誤,請重新輸入\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ù)字,可能會(huì)出現(xiàn)錯(cuò)誤,而且直接定義三行三列
之后我們想改造三子棋為五子棋會(huì)很麻煩,這個(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è)需要大家多動(dòng)手嘗試,先給大家看看我們理想的棋盤效果

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

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

接下來我們開始下棋了,我們先人為固定,我們下的是‘*’,電腦下的是‘#’

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

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

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

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("輸入錯(cuò)誤,請重新輸入");
        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("輸入錯(cuò)誤,請重新輸入");
        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");
}

這是拼裝后的結(jié)果

如果想和室友對戰(zhàn)的小伙伴,將computerplay改的和play差不多就行如果想玩五子棋也只需要對修改H L的常量值,以及判定條件,目前可能依然只能用列舉來判定

學(xué)到這,如果你依然不會(huì),沒關(guān)系,直接去我的碼云上找代碼,當(dāng)然我希望小伙伴們都能寫出屬于自己的三子棋,這個(gè)三子棋也并不完美,電腦下棋肯定是呆呆的,可以嘗試一下ai下棋

總結(jié)

到此這篇關(guān)于C語言新手初階教程之三子棋實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)C語言實(shí)現(xiàn)三子棋內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++ 中私有繼承的作用

    C++ 中私有繼承的作用

    這篇文章主要介紹了C++ 中私有繼承的作用的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-10-10
  • C++/STL實(shí)現(xiàn)判斷平面內(nèi)兩條線段的位置關(guān)系代碼示例

    C++/STL實(shí)現(xiàn)判斷平面內(nèi)兩條線段的位置關(guān)系代碼示例

    這篇文章主要介紹了C++/STL實(shí)現(xiàn)判斷平面內(nèi)兩條線段的位置關(guān)系代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • C語言設(shè)計(jì)簡易電話簿

    C語言設(shè)計(jì)簡易電話簿

    這篇文章主要為大家詳細(xì)介紹了C語言設(shè)計(jì)簡易電話簿,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • 關(guān)于C/C++中可變參數(shù)的詳細(xì)介紹(va_list,va_start,va_arg,va_end)

    關(guān)于C/C++中可變參數(shù)的詳細(xì)介紹(va_list,va_start,va_arg,va_end)

    可變參數(shù)的函數(shù)原理其實(shí)很簡單,而va系列是以宏定義來定義的,實(shí)現(xiàn)跟堆棧相關(guān).我們寫一個(gè)可變函數(shù)的C函數(shù)時(shí),有利也有弊,所以在不必要的場合,我們無需用到可變參數(shù)。如果在C++里,我們應(yīng)該利用C++的多態(tài)性來實(shí)現(xiàn)可變參數(shù)的功能,盡量避免用C語言的方式來實(shí)現(xiàn)
    2013-10-10
  • C++實(shí)現(xiàn)一個(gè)掃雷小游戲

    C++實(shí)現(xiàn)一個(gè)掃雷小游戲

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)一個(gè)掃雷小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • C++虛函數(shù)注意事項(xiàng)

    C++虛函數(shù)注意事項(xiàng)

    這篇文章主要給大家分享了EC++虛函數(shù)注意事項(xiàng),
    2022-01-01
  • c語言實(shí)現(xiàn)簡易版三子棋(附完整代碼)

    c語言實(shí)現(xiàn)簡易版三子棋(附完整代碼)

    大家好,本篇文章主要講的是c語言實(shí)現(xiàn)簡易版三子棋(附完整代碼),感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • 深入解析C++的循環(huán)鏈表與雙向鏈表設(shè)計(jì)的API實(shí)現(xiàn)

    深入解析C++的循環(huán)鏈表與雙向鏈表設(shè)計(jì)的API實(shí)現(xiàn)

    這篇文章主要介紹了C++的循環(huán)鏈表與雙向鏈表設(shè)計(jì)的API實(shí)現(xiàn),文中的示例對于鏈表結(jié)點(diǎn)的操作起到了很好的說明作用,需要的朋友可以參考下
    2016-03-03
  • 關(guān)于C語言strlen與sizeof區(qū)別詳情

    關(guān)于C語言strlen與sizeof區(qū)別詳情

    對于 strlen 和 sizeof,相信不少程序員會(huì)混淆其功能。雖然從表面上看它們都可以求字符串的長度,但二者卻存在著許多不同之處及本質(zhì)區(qū)別,今天得這篇文章我們就來學(xué)習(xí)C語言strlen與sizeof區(qū)別的相關(guān)資料,需要的朋友可以參考一下
    2021-10-10
  • 詳解C++11中的線程鎖和條件變量

    詳解C++11中的線程鎖和條件變量

    C++ 11允許開發(fā)者們以標(biāo)準(zhǔn)的、不依賴于平臺(tái)的方式編寫多線程程序。這篇文章概述了標(biāo)準(zhǔn)庫對于線程和同步操作機(jī)制的支持。這些都是非常重要的知識(shí),希望讀者們可以認(rèn)真看一下
    2021-06-06

最新評論