C语言三子棋Tick-Tck-Toe代码实现

Posted SuchABigBug

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言三子棋Tick-Tck-Toe代码实现相关的知识,希望对你有一定的参考价值。

三子棋游戏大家应该都玩过,游戏规则不做介绍,代码实现之前先一起过一遍思路!

1. 思维导图

在这里插入图片描述

2. 设计思路

结合上图,我们可以拆分为三个文件进行编写:

  1. test.c文件用于测试游戏的逻辑
    do…while函数,打印菜单并进行玩家输入判断
    如果玩家输入1,调用game函数
    如果玩家输入0, 直接break,跳出循环
    如果玩家输入其他值,直接break,跳出循环

    这里我们具体说一说game() function的逻辑,首先要对棋盘进行初始化,具体函数实现我们在game.c中会讲到,然后把初始化好的棋盘进行打印显示。其次无论是玩家还是电脑下的每一步棋,都需要对其状态进行检查:

    1. 玩家回合,下完一步棋后对棋盘进行打印
    2. 判断字符是否返回‘C’,否则游戏继续
    3. 电脑回合,下完一步棋后对棋盘进行打印
    4. 判断是否返回‘C’,否则游戏继续
    5. 如果不是字符‘C’
      1. 返回字符‘X’,表明玩家赢了
      2. 返回字符’O’,表面电脑赢了
      3. 返回字符’Q’,棋盘已满,平局
  2. game.c 用于相关函数实现

    1. 函数initBoard(),初始化棋盘的值都为空
    2. 函数DisplayBoard(),为了ROW和COL大小更通用
      1. 定义row行,row-1行不进行打印
      2. 定义col列,同理col-1列不进行打印,每行的内容先把棋盘的空值放进去后打印符号|,换行后对下边框进行打印---|,注意判断如果是col-1,符号|不进行打印。
      3. 棋盘展示好后,玩家开始进行下棋,结合用户习惯我们取值范围是在1~3之间,超过则表示非法越界或者棋盘的值不为空
    3. 函数ComputerMove(),这里电脑下棋的标准为:只判断棋盘里的值是否为空
    4. 函数isFull(),判断棋盘的是否已满,全满返回1,否则返回0
    5. 函数hasWinner(),判断是否有赢家:
      1. 对棋盘的每行进行判断是否值都相等且不为空
      2. 对棋盘的每列进行判断是否值都相等且不为空
      3. 对角的值判断是否都相等且不为空
  3. game.h 相关函数声明,引入必要头文件及各文件需要的函数进行声明,并初始化行和列是多大

3. 代码实现

test.c

#include "game.h"

void menu(){
    printf("****************************************\\n");
    printf("*************  0. Exit   ***************\\n");
    printf("*************  1. Play   ***************\\n");
    printf("****************************************\\n");
}

void game(){

    char board[ROW][COL];

    //init board
    initBoard(board, ROW, COL);
    
    //Show board
    DisplayBoard(board, ROW, COL);
    
    /*
     游戏状态检查:
     1. 玩家胜利, 返回X
     2. 电脑胜利, 返回O
     3. 平局, 返回Q
     4. 游戏继续, 返回C
     */
    char ret = 0; //get game status
    while(1)
    {
        //Player turn
        PlayerMove(board, ROW, COL);
        DisplayBoard(board, ROW, COL);
        ret = hasWinner(board, ROW, COL);
        if(ret != 'C')
            break;
        
        //Computer turn
        ComputerMove(board, ROW, COL);
        DisplayBoard(board, ROW, COL);
        //Check whether got winner
        ret = hasWinner(board, ROW, COL);
        if(ret != 'C')
            break;
    }
    if(ret == 'X'){
        printf("Player winned \\n");
    }else if(ret == 'O'){
        printf("Computer winned \\n");
        
    }else{
        printf("Play Even \\n");
    }
    DisplayBoard(board, ROW, COL);
    
}

int main(){

    int input=0;
    srand((unsigned int)time(NULL));
    do{
        menu();
        printf("Please Choose:>  ");
        scanf("%d", &input);
        switch (input)
        {
        case 0:
            printf("Exit Game\\n");
            break;
        case 1:
            game();
            printf("Playing Game\\n");
            break;
        default:
            printf("Choose wrong, Please retry\\n");
            break;
        }
    }while(input);

    return 0;
}

game.h

#pragma once

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

#define ROW 3
#define COL 3

//Declare function
void initBoard(char board[ROW][COL], int row, int col);

//print move
void DisplayBoard(char board[ROW][COL],int row,int col);

//Player‘s turn
void PlayerMove(char board[][COL], int row, int col);

//Computer's turn
void ComputerMove(char board[][COL], int row, int col);

//Does board has winner yet?
char hasWinner(char board[][COL], int row, int col);

game.c

#include "game.h"

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] = ' '; //Init board to empty
        }
    }

}

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

    for(int i=0; i<row; i++){
        for(int j=0; j<col; j++){
            printf(" %c ",board[i][j]);
            if(j<col-1)
                printf("|");
        }
        printf("\\n");
        if(i<row-1)
            // printf("---|---|---\\n");
            for(int j=0; j<col; j++){
                printf("---");
                if(j<col-1)
                    printf("|");
            }
            printf("\\n");
    }

}

void PlayerMove(char board[][COL], int row, int col){
    int x=0;
    int y=0;
    
    while(1){
        printf("Player's Turn :> \\n");
        printf("Please input coordinate: >");
        scanf("%d %d", &x, &y);
        
        //Check coordinate validation
        if( x>=1 && x<=row && y>=1 && y<=col ){
            //Check if input x,y coordinates is valid
            if(board[x-1][y-1] != ' ' ){
                printf("x,y coordinate is not empty, Please Retry");
            }else{
                board[x-1][y-1] = 'X';
                break;
            }
        }else{
            printf("Invalid coordinate, Please Retry");
        }
         
    }
    
}

void ComputerMove(char board[][COL], int row, int col){
    printf("Computer's Turn :? \\n");
    
    while(1){
        int x = rand()%row;
        int y = rand()%col;
        if(board[x][y] == ' '){
            board[x][y] = 'O';
            break;
        }
    }
   
}


//Check Board status below:
int isFull(char board[][COL], int row, int col){
    for(int i=0; i<row; ++i){
        for(int j=0; j<col; ++j){
            if(board[i][j] == ' '){
                return 0; //board not full yet~
            }
        }
    }
    return 1;
}

char hasWinner(char board[][COL], int row, int col){
    
    for(int i=0; i<row; i++){
        for(int j=0; j<col; j++){
            if(board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' '){
                return board[i][1];
            }
        }
    }
    
    //Check three col
    for(int i=0; i<row; i++){
        for(int j=0; j<col; j++){
            if(board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ' ){
                return board[1][i];
            }
        }
    }
    
    //check if it's diagonal
    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];
    }
    
    //check if board it's full
    int ret = isFull(board, row, col);
    //1 indicates play even
    if(ret == 1){
        return 'Q';
    }
    
    return 'C';
}

为了提高可读性,我们创建了game.h,因此test.c和game.c只需要#include "game.h"即可


如果文章对你有帮助,老铁支持一波,Thank You~ 😃

以上是关于C语言三子棋Tick-Tck-Toe代码实现的主要内容,如果未能解决你的问题,请参考以下文章

《C语言入门》三子棋C语言实现(详细版)

C语言实现三子棋游戏

用C语言实现三子棋游戏(附上思路+项目展示+源代码)

详细解读C语言实现三子棋

C语言实现三子棋

c语言三子棋