Programming Tic Tac Toe

0 Reynaldo Gunawan · June 13, 2015
For my next project, i am asked to create Tic Tac Toe in C. The only clue that i got is that i need 3-dimensional array, as the users will put in the number of column and row to indicate which box they want to play. 

The question also says that i need to prove whether the box is already full or whether one of the player has his/her symbol three times in a line, well everyone knows Tic Tac Toe.

I know that i need a tremendous amount of functions to make this program, but i don't even know where to start and which and how many variables i would need. I've created the structure of the game without the number like the photos below, but that's only like 1/1000 done of what i need to do. I am so screwed...

If someone has any ideas, please let me know. I'm not expecting a whole complete program, as i would not learn as much from it anyway. I appreciate your replies.

Example of the format:

./images/forum/upload/2015-06-13/b985899b892f2ec437b27c4afe79c665.png/images/forum/upload/2015-06-13/12b00650949cfe1723bd16879b3dfb8f.png

Post a Reply

Replies

- page 2
Oldest  Newest  Rating
0 Alan Johnson · June 15, 2015
make_move puts either an X or O in the position the user wants to move in, depending on whose turn it is.
turn ? says if the turn variable is true(1)  then then put a "O" in the cell, otherwise put an "X" in the cell.
 board[pos] = turn ? "O" : "X";


Then it switches to the other player's turn, if it was 1 before (player O), it becomes 0 (player X),  and vice versa, so the other player can make a move next.
turn = !turn;


The while loop continuously executes until the game is over, it asks the user for what position to play in, puts an X or O in the cell they want to move in and finally shows them what the game board looks like now after their turn.
+1 Keyno Neile · June 16, 2015
Nice programing, its really neat and well documented  @jonas Meise
0 Reynaldo Gunawan · June 16, 2015
@AlanJohnson alright, i'm beginning to understand it. Thanks a lot for your work and replies.
0 Alan Johnson · June 16, 2015
No problem, glad to help you
0 Jon Z. · June 17, 2015
Hi, I just spent 2 hours writing the program.
The only problem I find so far is that is that it doesn't display properly who won, when someone wins it always says Player #1 won. I think I made some mistake in the checkWhoWon function.
Here is the code:

/*
* tic.c
* Tic Tac Toe
* by Jon Z. jonz@inbox.com
*/

#include

#define SYSTEM_CLEAR "cls"   //"cls" for windows. for unix-based systems replace "cls" with "clear"

void clear();
void displayGameState();
void userInput(int user);
int checkWhoWon();
int checkIfFull();

char pos[3][3]; //array to story state of the game

main(){

    clear(pos); //set every element in the array to ' ' (space)
    int gameOver = 0; //set to 1 to end game
    int whoWon = 0; //player 1 or 2? 0 for a tie

    //loops until someone wins, or all the positions are taken
    while(gameOver == 0){
        displayGameState();
        userInput(1);
        displayGameState();

        whoWon = checkWhoWon();
        if(whoWon != 0){
            gameOver = 1;
            break;  //exits loop if someone won
        }else{
            gameOver = 0;
        }

        gameOver = checkIfFull();
        if(gameOver != 0){
            break;  //exits loop if array is full and it's a tie
        }

        userInput(2);
        displayGameState();

        whoWon = checkWhoWon();
        if(whoWon != 0){
            gameOver = 1;
            break;
        }else{
            gameOver = 0;
        }

        gameOver = checkIfFull();
        if(gameOver != 0){  //this is not necesary sincsince it's at the end of the loop, but i just copied it from before
            break;  //exits loop if array is full and it's a tie
        }
    } //end of loop

    if(whoWon =! 0){
        printf("\n\tPlayer #%d Won!!!\n\n", whoWon);
    }
    else{
        printf("\n\tIt's a tie\n\tGAME OVER!\n\n");
    }


    return 0;
}

//set every element in the array to ' ' (space)
void clear(){
    int i, j;

    for(i=0; i
0 Reynaldo Gunawan · June 23, 2015
/* 
 * File:   ticTacToe.c
 * Author: reynaldogunawan
 *
 * Created on June 13, 2015, 1:24 PM
 */

#include
#include
#include

/*
 * 
 */
int i;
int j;
char* playBoard[3][3] = {0};
int turn;

int input();
void displayBoard();
void move();
void emptyBoard();
bool gameOver();
int end = 0;

int main() {

    printf("***** Willkommen in Tic Tac Toe! ****** \n");
    printf("\tSpieler X spielt erstmal.\t \n");
    
    
    emptyBoard();
    displayBoard();
    
    while(!gameOver()){
        int koordinates = input();
        move(koordinates);
        displayBoard();

    }
    
    printf("\nNeu Starten? \n(Drücken Sie eine beliebige Zahl, um erneut zu spielen. Sonst 0, um das Spiel zu beenden.) \n");
    scanf(" %d", &end);
    
    (end == 0) ? printf("Danke für Spielen\n") : main();

    return (EXIT_SUCCESS);
}



int input(){
    printf("Koordinaten eingeben (Zeile Spalte): ");
    
    int pos[2];
    
    fpurge(stdin);
    
    scanf(" %d %d", &pos[0], &pos[1]);
    pos[0]--;       //damit die eingegebenen Koordinaten die Positionen im Array entsprechen
    pos[1]--;
    
    if((pos[0] < 0 || pos[0] > 2) || (pos[1] < 0 || pos[1] > 2)){
        printf("Koordinaten unbekannt. Versuchen Sie noch einmal... \n\n");
        input();
    }
    else if(playBoard[pos[0]][pos[1]] != ' '){
        printf("Koordinaten ist schon besetz. \n\n");
        input();
    }
    
    return pos[2];
}

void displayBoard(){
    for(i = 0; i < 42; i++){
        printf("-");
    }
    printf("\n");
    printf("\t\t    1  2  3 \n");
    for(i = 0; i < 3; i++){
        printf("\t\t");
        printf("%d  ", i+1);
        for(j = 0; j < 3; j++){
            printf("", playBoard[i][j]);
            if(j == 2){
                printf("\n");
            }
        }
    }
    for(i = 0; i < 42; i++){
        printf("-");
    }
    printf("\n");
    return;
}

void emptyBoard(){
    for(i = 0; i < 3; i++){
        for(j = 0; j < 3; j++){
            playBoard[i][j] = ' ';
        }  
    }    
}

void move(){
    int pos[2];
    playBoard[pos[0]][pos[1]] = turn ? 'O' : 'X';
    turn = !turn;
}

bool gameOver(){
    
    bool result = false;
    
    /* Vertical */
    if((playBoard[0][0] == 'O' && playBoard[1][0] == 'O' && playBoard[2][0] == 'O') || 
            (playBoard[0][1] == 'O' && playBoard[1][1] == 'O' && playBoard[2][1] == 'O') || 
            (playBoard[0][2] == 'O' && playBoard[1][2] == 'O' && playBoard[2][2] == 'O')){
        printf("Spieler 'O' hat gewonnen! \n");
        result = true;
    }
    if((playBoard[0][0] == 'X' && playBoard[1][0] == 'X' && playBoard[2][0] == 'X') || 
            (playBoard[0][1] == 'X' && playBoard[1][1] == 'X' && playBoard[2][1] == 'X') || 
            (playBoard[0][2] == 'X' && playBoard[1][2] == 'X' && playBoard[2][2] == 'X')){
        printf("Spieler 'X' hat gewonnen! \n");
        result = true;
    }
    /* Horizontal */
    if((playBoard[0][0] == 'O' && playBoard[0][1] == 'O' && playBoard[0][2] == 'O') || 
            (playBoard[1][0] == 'O' && playBoard[1][1] == 'O' && playBoard[1][2] == 'O') || 
            (playBoard[2][0] == 'O' && playBoard[2][1] == 'O' && playBoard[2][2] == 'O')){
        printf("Spieler 'O' hat gewonnen! \n");
        result = true;
    }
    if((playBoard[0][0] == 'X' && playBoard[0][1] == 'X' && playBoard[0][2] == 'X') || 
            (playBoard[1][0] == 'X' && playBoard[1][1] == 'X' && playBoard[1][2] == 'X') || 
            (playBoard[2][0] == 'X' && playBoard[2][1] == 'X' && playBoard[2][2] == 'X')){
        printf("Spieler 'X' hat gewonnen! \n");
        result = true;
    }
    /* Diagonal */
    if((playBoard[0][0] == 'O' && playBoard[1][1] == 'O' && playBoard[2][2] == 'O') ||
            (playBoard[0][2] == 'O' && playBoard[1][1] == 'O' && playBoard[2][0] == 'O')){
        printf("Spieler 'O' hat gewonnen! \n");
        result = true;
    }
    if((playBoard[0][0] == 'X' && playBoard[1][1] == 'X' && playBoard[2][2] == 'X') ||
            (playBoard[0][2] == 'X' && playBoard[1][1] == 'X' && playBoard[2][0] == 'X')){
        printf("Spieler 'X' hat gewonnen! \n");
        result = true;
    }
    /* Board is full */
    if((playBoard[0][0] != ' ' && playBoard[1][0] != ' ' && playBoard[2][0] != 'O') && 
            (playBoard[0][1] != ' ' && playBoard[1][1] != ' ' && playBoard[2][1] != ' ') && 
            (playBoard[0][2] != ' ' && playBoard[1][2] != ' ' && playBoard[2][2] != ' ')){
        printf("Das Spiel ist unentschieden! \n");
        result = true;
    }
    return result;
    
    
}




So, i finally made this for my college assignment, based on @AlanJohnson 's code. Freaking due dates are making me under pressured and uncreative. I made it so that it matches my assignment, so some changes were made. 

There is however still a problem and that is when I made a mistake by the input. The next input and the turn of the player seem to be messed up, and the conditions are, somehow, invalid. If someone can spot the mistake that i made, it would be really cool, cause I spent hours trying to fix it, but meh, i suck.

Thank you in advance
0 Alan Johnson · June 23, 2015
Can you send me or post here your full assignment brief in english? I'll fix this up for you.
0 Reynaldo Gunawan · June 23, 2015
Hahaha right, i put everything in german. Keep forgetting. Wow thanks a lot. I'll translate them real quick
+1 Alan Johnson · June 23, 2015
Fixed it up for you, let me know if its not as you want it.

http://pastebin.com/fh2qbVQX
0 Homer Simpson · June 24, 2015
main.cpp
#include "engine.h"

int main()
{
    engine.play();
    return 0;
}


engine.h
#ifndef ENGINE_H
#define ENGINE_H

#include "board.h"

class Engine{
    private:
        
        char symbol; // is set to 'X' or 'O'
        
        int display_menu();
        // returns true if theres no moves left or if a player has won
        bool game_over();
        // return true if there are no available move, otherwise it returns false
        bool is_out_of_moves();
        // return true if a player has won, otherwise it returns false;
        bool player_won();
        // changes the symbol 
        void swap_turns();
        
    public:
        // 'X' is set to always be first
        Engine(char x) { symbol = x; };
        // run the game
        void play();
};

extern Engine engine;

enum choices {
    SINGLEPLAYER = 1, TWO_PLAYERS, ABOUT, EXIT
};

#endif // ENGINE_H


engine.cpp
#include "engine.h"
#include "misc.h"

#include <cstdio>
#include <cstdlib>
#include <iostream>

Engine engine('X');

int Engine::display_menu()
{
    std::cout << "\n\n\n\n\n\n\n\n\n\n\n\n-=[ Tic Tac Toe ]=-" << std::endl;
    std::cout << "\n1. Single Player" << std::endl;
    std::cout << "2. Two players" << std::endl;
    std::cout << "3. About" << std::endl;
    std::cout << "4. Exit\n" << std::endl;
    std::cout << "Your selection: ";
}

//////////////////////////////////////////////////////////////////////

void Engine::play()
{
    int choice = 0;
    
    do {
        display_menu();
        std::cin >> choice;
        // ensure the user entered an integer value
        if (is_invalid_input()) 
            choice = 0;
        
        
        switch (choice) {
        
            case SINGLEPLAYER:
                board.init();
            break;
            
            case TWO_PLAYERS:
                board.init();
                
                // keep looping until theres no available moves or a player wins
                while (!game_over()) {
                    int loc; // location
                    std::cout << "Player " << symbol << " move: ";
                    std::cin >> loc;    // set the symbol at that location
                    
                    if (is_invalid_input()) // ensure the user entered an integer value
                        loc = 0;
         
                    if (board.update(loc, symbol)){ // returns true if the users space is availible
                        if (game_over()) break; // check to see if player won or ran out of moves
                        swap_turns(); // if not change the symbol
                    } else {
                        chill();            // else let the user know they entered an invalid location
                        board.display();    // redisplay the board
                    }
                }
             break;
             
             case ABOUT:
                std::cout << "\n\t\tCreated by: Homer Simpson" << std::endl;
                chill();
             break;
             
             case EXIT:
                std::cout << "\n\n\t\tThank you for playing!\n" << std::endl;
             break;
             
             default:
                std::cout << "[!!] Inavalid Selection!!" << std::endl;
        }
        
    } while (choice != EXIT);
}

///////////////////////////////////////////////////////////////////////

bool Engine::game_over()
{
    if (board.out_of_moves() || player_won()) {
        if (board.out_of_moves()){
            std::cout << "\t\tNO WINNER!!!" << std::endl;
            chill();
        }
        return true;
    }
    return false;
}

///////////////////////////////////////////////////////////////////////////

void Engine::swap_turns()
{
    symbol = (symbol == 'X') ? 'O' : 'X';
}

///////////////////////////////////////////////////////////////////////////

bool Engine::player_won()
{
    for (int i = 0; i < DIMENSIONS; ++i) {
        for (int j = 0; j < DIMENSIONS; ++j) {
            // check to see if we have a winner
            if(((board.tiles[0] == symbol) && (board.tiles[1] == symbol) && (board.tiles[2] == symbol)) || // horizontally
               ((board.tiles[0][j] == symbol) && (board.tiles[1][j] == symbol) && (board.tiles[2][j] == symbol)) || // vertically
               ((board.tiles[0][0] == symbol) && (board.tiles[1][1] == symbol) && (board.tiles[2][2] == symbol)) || // diagnol checks
               ((board.tiles[2][0] == symbol) && (board.tiles[1][1] == symbol) && (board.tiles[0][2] == symbol))) { 
                std::cout << "\t\t\t" << symbol << " has won!!!" << std::endl;
                chill();
                return true;
            } 
        }
    }
    
    return false;
}

//////////////////////////////////////////////////////////////////////////////

misc.h
#ifndef MISC_H
#define MISC_H

// equivalent to system(PAUSE) -- it prompts the user to press enter before continuing
void chill();
// if the user entered invalid input it resets the stream
bool is_invalid_input();

#endif // MISC_H


misc.cpp
#include "misc.h"

#include <cstdio>
#include <iostream>

/////////////////////////////////////////////////////////////////////////////////

void chill()
{
    std::cout << "\n\nPress ENTER to continue...\n" << std::endl;
    std::cin.ignore();
    std::fflush(stdin);
    std::cin.get();
}

////////////////////////////////////////////////////////////////////////////////

bool is_invalid_input()
{
    if (std::cin.fail()) {
        std::cin.clear();               // clear the error flag
        std::cin.ignore(256, '\n');     // ignore until newline
        return true;
    }
    
    return false;
}


///////////////////////////////////////////////////////////////////////////////////


board.h
#ifndef TIC_TAC_TOE_BOARD_H
#define TIC_TAC_TOE_BOARD_H

#define CONVERT_TO_CHAR(x) (x + 48)
#define DIMENSIONS 3
#define MIN_TILE 1
#define MAX_TILE 9

#include <vector>

class Board {
    private:
        
        // returns true if the user entered a valid location; otherwise notifies user and returns false
        bool is_valid_location(int);
        // displays the current state of the game
        
    public:
        void init();
        
        // takes the location of the place marker and inserts the correct symbol; calls display() after
        bool update(int, char);
        // sets a place marker by displaying a 3 x 3 matrix numbered from 1 - 9
        void clear();
        void display();
        bool out_of_moves(); // returns true when there are no available locations
        
        char tiles[DIMENSIONS][DIMENSIONS]; // 3 x 3 matrix
};

extern Board board;

#endif // TIC_TAC_TOE_BOARD_H


board.cpp
#include "board.h"

#include <iostream>

Board board;

///////////////////////////////////////////////////////////////

void Board::init()
{
    clear();
    display();
}

///////////////////////////////////////////////////////////////

bool Board::update(int location, char symbol)
{
    if (!is_valid_location(location)) 
        return false;
        
    // iterate through the matrix and check if the location is empty
    for (int i = 0; i < DIMENSIONS; ++i) {
        for (int j = 0; j < DIMENSIONS; ++j) {
            // if the place holder is still then insert the symbol and display 
            if (tiles[j] == CONVERT_TO_CHAR(location)) {
                tiles[j] = symbol;
                display();
                return true;
            }
        }
    }
    
    std::cout << "[!!] Invalid placement!\n" << std::endl;
    return false;
}

///////////////////////////////////////////////////////////////

bool Board::is_valid_location(int location)
{
    if ((location < MIN_TILE) || (location > MAX_TILE)) {
        std::cout << "[!!] Invalid placement!\n" << std::endl;
        return false;
    } 
    
    return true;
}

/////////////////////////////////////////////////////////////////

bool Board::out_of_moves()
{
    int place_marker = CONVERT_TO_CHAR(1);
    for (int i = 0; i < DIMENSIONS; ++i) {
        for (int j = 0; j < DIMENSIONS; ++j) {
            if (tiles[j] == place_marker) return false;
            ++place_marker;
        }
    }
    
    return true;
}

//////////////////////////////////////////////////////////////

void Board::display()
{
    // create some blank space
    std::cout << "\n\n\n\n\n\n\n\n\n\n\n" << std:: endl;
    // iterate through every row
    for(int i = 0; i < DIMENSIONS; ++i) {
        // draw the horizontal lines and center the board
        if (i > 0) std::cout << "\t\t\t___________" << std::endl; 
        // iterate through every column
        for (int j = 0; j < DIMENSIONS; ++j) {
            // center the board
            if (j == 0)
                std::cout << "\t\t\t";
            // display the tiles and the horizontal lines
            std::cout << tiles[j] << " | ";
        }
        // align the board
        std::cout << std::endl;
    }
    
    // more blank spaces
    std::cout << "\n\n\n\n" << std::endl;
}

////////////////////////////////////////////////////////////////

void Board::clear()
{
    int place_marker = CONVERT_TO_CHAR(1); // ascii code for 1
    // iterate through every row
    for (int i = 0; i < DIMENSIONS; ++i) {    
        // iterate through every column    
        for (int j = 0; j < DIMENSIONS; ++j) {
            tiles[j] = place_marker;
            ++place_marker;
        }
    }
}

//////////////////////////////////////////////////////////////////


My atrocious mess...

C

107,273 followers
About

One of the most popular languages of all time.

Links
Moderators
Bucky Roberts Administrator