1. 程式人生 > >三子棋(賊菜的演算法)

三子棋(賊菜的演算法)

不是標題黨!!!
不是標題黨!!!
不是標題黨!!!
重要事情說三遍,嗯,就這樣
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:歡迎各位讀者評論,點贊,提意見給我,謝謝….