Implementation of tick TCK toe code in C language

Posted by dkim777 on Thu, 17 Feb 2022 22:59:40 +0100

We should all have played the three piece chess game. The rules of the game are not introduced. Let's go through it together before the code is realized!

1. Mind map

2. Design idea

Combined with the above figure, we can split it into three files for writing:

  1. test.c file is used to test the logic of the game
    do... while function, print the menu and judge the player's input
    If the player enters 1, call the game function
    If the player enters 0, break directly and jump out of the loop
    If the player enters other values, break directly and jump out of the loop

    Here, let's talk about the logic of game() function. First, initialize the chessboard. The specific function is implemented in game C, and then print and display the initialized chessboard. Secondly, every move of chess, whether played by players or computers, needs to be checked:

    1. The player will print the chessboard after a round of chess
    2. Judge whether the character returns' C ', otherwise the game continues
    3. In the computer round, print the chessboard after playing a move of chess
    4. Judge whether to return to 'C', otherwise the game continues
    5. If not the character 'C'
      1. Returns the character 'X', indicating that the player has won
      2. Return the character 'O', and it appears that the computer has won
      3. Return the character 'Q', the chessboard is full and the game is tied
  2. game.c is used for the implementation of correlation functions

    1. The function initBoard() initializes the chessboard with null values
    2. The function DisplayBoard() is more general for the size of ROW and COL
      1. Define row row. row-1 row will not be printed
      2. Define col column. Similarly, col-1 column will not be printed. The contents of each line will be printed after putting the null value of the chessboard in, and the lower border will be printed after line breaking. Pay attention to judge that if it is col-1, the symbol will not be printed.
      3. After the chessboard is displayed, the player begins to play chess. Combined with the user's habits, our value range is between 1 and 3. If it exceeds, it means illegal crossing or the value of the chessboard is not empty
    3. The standard value of move () in the computer is only used to judge whether the chessboard is empty
    4. The function isFull() determines whether the chessboard is full. If it is full, it returns 1, otherwise it returns 0
    5. The function hasWinner() determines whether there is a winner:
      1. Judge whether the values of each line of the chessboard are equal and not empty
      2. Judge whether the values of each column of the chessboard are equal and not empty
      3. Diagonal values determine whether they are equal and not empty
  3. game.h related function declaration, introduce the necessary header files and the functions required by each file for declaration, and initialize the size of rows and columns

3. Code implementation

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);
    
    /*
     Game status check:
     1. Player wins and returns to X
     2. Computer victory, return to O
     3. Draw, Q
     4. The game continues and returns to 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';
}

To improve readability, we created game h. So test C and game C just #include "game.h"

If the article is helpful, old fellow will support Thank You to 😃

Topics: C Game Development