Gabriella Coronell
Gabriella Coronell

Reputation: 19

Stop Tic Tac Toe from overwriting moves in C

Sorry guys I just asked a question a couple of hours ago but this is the last thing I need to finish my project. My program allows overwrite of moves. Like say if player 1 picks the first square, it will allow player 2 to also pick this square. Everything else functions perfectly I have just been failing at the implementation of this.

Any ideas? I just put one part of my code since a lot of my code is sadly copy and pasted. I'm really new, so I haven't figured out optimization yet and I am already out of time for this project so any help will be appreciated.

So in this code I only included the printing of the original board and the first move of the first player (if playing with 2 humans). This should be enough to get help but if anybody wants to see the rest of the code please let me know as I have left out most of it. Thanks!!!

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

/* known bugs: Allows players to place a 1 or 2 on board even if there is already a 1 or 2 in that spot. */

int main()
{
    char board[3][3];
    int i,j,k,l, player, move;

    for(i=0;i<=3;i++) // prints initial board of 0's
    {
        for(j=0;j<=3;j++)
        {
            board[i][j] = '0';
        }
    }


    printf("Hello! Do you want to play alone or with a computer? \n\n"
           "Enter 1 for alone or 2 to play with a friend!\n");
    scanf("%d", &player);

    if (player == 2)
    {
        for(k=0;k<9;k++) // 9 moves max.
        {
            printf("\n\n"); // print board again.
            printf(" %c | %c | %c\n", board[0][0], board[0][1], board[0][2]);
            printf("---+---+---\n");
            printf(" %c | %c | %c\n", board[1][0], board[1][1], board[1][2]);
            printf("---+---+---\n");
            printf(" %c | %c | %c\n", board[2][0], board[2][1], board[2][2]);

            do
            {
                printf("Player 1, where would you like to move? Enter 1-9\n");
                scanf("%d", &move);

                if (move == 1)
                    board[0][0] = '1';
                if (move == 2)
                    board[0][1] = '1';
                if (move == 3)
                    board[0][2] = '1';
                if (move == 4)
                    board[1][0] = '1';
                if (move == 5)
                    board[1][1] = '1';
                if (move == 6)
                    board[1][2] = '1';
                if (move == 7)
                    board[2][0] = '1';
                if (move == 8)
                    board[2][1] = '1';
                if (move == 9)
                    board[2][2] = '1';

            }while(move>9 && move <1);

Upvotes: 1

Views: 766

Answers (2)

Barthy
Barthy

Reputation: 3231

  1. I would suggest using a switch case in the last do while loop (see example)
  2. I think you simply need to check if the field you are referencing is already taken!

** The check()**

void check (char *c, int *move){
    if(*c == '0'){
        *c = '1';
    }else {
        printf("\nThis field is already taken! Please choose another one.\n");
        /* since you repeat this as long as move is bigger than 9 or smaller
           than 1, this will have the user make another choice. */
        *move = 0; 
    }
}

** Your last do while**

do {
    printf("Player 1, where would you like to move? Enter 1-9\n");
    scanf("%d", &move);

    switch (move){
        case 1:
            check(&board[0][0], &move);
            break;
        case 2:
            check(&board[0][1], &move);
            break;
        case 3:
            check(&board[0][2], &move);
            break;
        case 4:
            check(&board[1][0], &move);
            break;
        case 5:
            check(&board[1][1], &move);
            break;
        case 6:
            check(&board[1][2], &move);
            break;
        case 7:
            check(&board[2][0], &move);
            break;
        case 8:
            check(&board[2][1], &move);
            break;
        case 9:
            check(&board[2][2], &move);
            break;
        default:
            printf("\nError! Choose a field between 1 and 9\n");
    }

}while(move>9 || move <1);

Note: like the others said, your for-loops need to iterate until i/j < 3, since your array has the size of 3 (indexes 0, 1, 2);

Note 2: The while statement must be move > 9 OR move < 1 since the int can't be bigger than 9 and smaller than 1 at the same time, which will cause an infinite loop.

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409166

When you declare an array of size N, then the indexes goes from zero to X minus one.

So in your case the indexes are 0 to 2 for the board arrays. Your loops in the main function goes from 0 to 3, i.e. out of bounds.

Writing to an array out of bounds leads to undefined behavior, and undefined behavior makes your program ill-formed. Undefined behavior (or UB) can cause any kind of problems, including seemingly work, just to the next moment lead to nasal demons.

Upvotes: 1

Related Questions