三子棋

三子棋
在這個程序裏面總共包含了5個子函數,和一個main函數。接下來逐個分析一下每個函數的構建思路。
1.初始化函數。
該部分函數主要對棋盤內的9個空格進行賦值,一般情況下我們把它們設爲空格,這裏我把它設爲‘0’,不是空格也無大礙。這是很簡單的一部分,只需要些兩個for循環就可以把初始化完成。
對於傳參這部分,需要把數組board傳進去,因爲我們要用數組對棋盤進行初始化,還需要row和col兩個參數,來控制棋盤的大小。

void InitBoard(char board[ROW][COL],int row,int col)
{

    int i = 0;
    int j = 0;
    for(i=0;i<row;i++)
    {
        for(j=0;j<col;j++)
        {
            board[i][j]='0';
        }
    }

}`

2.顯示棋盤
這裏也是比較簡單的一部分,只需要一個for循環就可以完成。對於格子裏的橫線豎線,我們可以自己調整到自己喜歡的樣子,我這裏沒有畫出外面的一圈線,因爲我發現不太好畫,畫出來不美觀。
傳參同樣需要數組board和row、col,和初始化函數一致。

void PrintBoard(char board[ROW][COL],int row,int col)
{
    int i = 0;
    for (i = 0; i < row; i++)
    {
        printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
        if(i != row-1)
        printf("---|---|---\n");
    }
}

3.電腦走
這裏是玩家先走還是電腦先走,是我們自己定的,我這裏定的電腦先走,畢竟電腦下這個三子棋不會思考,所以讓它先走吧,不要欺負它嘛!
先說傳參的部分,與上面的部分一致,需要一個數組,還需要知道行和列。
要想電腦走到任意一個位置,這裏我們就用到了一個生成隨機數的關鍵字rand,但是事先我們要在測試文件中定義srand((unsigned int)time(NULL)),這樣子纔可以使用rand()。然後我們用rand模上行和列,就得到了電腦要下的位置,行和列是3,所以我們模3的結果就是0-2,就是棋盤數組的下標,這就是我們爲什麼要模3的原因。
還需要注意的一點就是,電腦在下的時候,需要判斷該位置是否已經被佔了,如果被佔了,肯定是不能下這個地方的,所以這個地方用一個if,判斷一下,就OK了,因爲我的初始化是設爲0,所以如果該位置不爲0,那就可以下。

void ComMove(char board[ROW][COL],int row,int col)
{
    int x = 0;
    int y = 0;
    printf("電腦走!\n");
    while(1)
    {
        x = rand()%row;//因爲下標是0-2,所以這裏模3
        y = rand()%col;
        if(board[x][y] =='0')
        {
            board[x][y] ='2';
            break;
        }
    }
}

4.玩家走
玩家走的時候,也需要考慮和電腦走的時候同樣的問題,一個是該位置是否被佔,一個是玩家輸入座標是否合法。
## 判斷是否被佔 ##
假如玩家輸入x和y,x和y就要在1-3之間,這樣子才能匹配棋盤位置,然後數組裏面的部分就要寫成x-1和y-1,因爲數組下標從0開始,下標與順序差1。
其實也可以規定輸入x和y要在0-2之間,這樣子數組裏面就不用改了,只是玩家要清楚位置與下標之間的關係。
## 判斷輸入是否合法 ##
這裏與電腦輸入一樣,判斷要下的位置是否爲0,不是0纔可以下到該位置。否則輸出“座標非法!重新輸入”,我們可以看見把printf(“玩家走!\n”)放在while(1)外面,就是爲了不重複顯示“玩家走”,重複顯示“請輸入座標”就可以了!

void PlayerMove(char board[ROW][COL],int row,int col)
{
int x = 0;
int y = 0;
printf("玩家走!\n");
while(1)
{
printf("請輸入座標(x,y):");
scanf("%d%d",&x,&y);
if(((x>=1) && (x<=row)) &&((y>=1) &&( y<=col)))
{
if(board[x-1][y-1] == '0')
{
board[x-1][y-1] ='1';
break;
}
else
{
printf("該位置被佔用!");
}
}
else
{
printf("座標錯誤!");
}
}
}

5.判斷輸贏
這裏我們知道有8種贏的局面,橫着3個相同的相連有3種,豎着也有3種,還有斜着的有2種。
所以只要我們判斷出是否有上述8種情況出現,就可以判斷出輸贏。不過我們還不知道誰輸誰贏,所以我們要判斷出現“贏”的情況時,那一步是誰下的。所以我們的思路是,電腦或者玩家走,判斷輸贏,打印棋盤,打印誰輸誰贏。

`char CheckWin(char board[ROW][COL], int row, int col)
{
    int i = 0;
    for(i=0; i<row; 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<col; 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];  
    if((board[0][2]==board[1][1])  
        &&(board[1][1]==board[2][0])  
        &&(board[1][1]!=' '))      
        return board[1][1];  

    if(is_full(board,row,col))
    {
        return 'q';
    }
    return ' ';
}`
static int is_full(char board[ROW][COL],int row,int col)

{
    int i = 0;
    int j = 0;
    for(i=0;i<row;i++)
    {
        for(j=0;j<col;j++)
        {

            if(board[i][j] == ' ')
                return 0;
        }
    }
}

5個函數就寫好了,我們把它們放在game.c裏面

接下來,還需要一個測試文件test.c,把我們寫的game.c運行起來。

#define _CRT_SECURE_NO_WARNINGS 1

#include"game.h"
//測試的代碼都放到test文件裏面,遊戲的代碼都放到game文件裏面
void menu()
{
    printf("*****1.play 0.exit*****\n");
}
//1.打印棋盤 玩家走;請輸入座標;判斷輸贏;電腦走;判斷輸贏
void game()
{
    char arr[ROW][COL]={0};
    InitBoard(arr,ROW,COL);
    PrintBoard(arr,ROW,COL);
    while(1)
    {
        ComMove(arr,ROW,COL);
        PrintBoard(arr,ROW,COL);

        CheckWin();
        PlayerMove(arr,ROW,COL);
        PrintBoard(arr,ROW,COL);


        CheckWin();


    }
}



void test()
{
    int input = 0;
    srand((unsigned int)time(NULL));
    do
    {
        menu();
        printf("請選擇:");
        scanf("%d",&input);
        switch(input)
        {
        case 1:
            game();
            break;
        case 0:
            break;
        default:
            printf("選擇錯誤\n");
            break;
        }
    }while(input);
}


int main()
{
    test();
    system("pause");
    return 0;
}

最後我們還需要一個頭文件,來聲明這些函數,我們設置頭文件可以防止裏面的函數被重複調用。

#ifndef __GAME_H__
#define __GAME_H__

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

#define COL 3
#define ROW 3

void InitBoard(char board[ROW][COL],int row,int col);
void PrintBoard(char board[ROW][COL],int row,int col);
void ComMove(char board[ROW][COL],int row,int col);
void PlayerMove(char board[ROW][COL],int row,int col);
char CheckWin(char board[ROW][COL], int row, int col);

#endif   //__GAME_H__

!運行實例

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章