Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stddef.h>
- #include <stdlib.h>
- #include <time.h>
- // Tristen ################### 8/13/2017 7:01 A.M.
- // Tic-tac-toe program.
- // Grid size for the user (1-9). 0-8 for arrays.
- #define GRID_SIZE 9
- int grid[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
- // Gets the player's character based on the value provided.
- char convert_digits(int digit)
- {
- if (digit == 1)
- {
- return 'O';
- }
- else if (digit == -1)
- {
- return 'X';
- }
- else
- {
- return '-';
- }
- }
- int valid_position(short pos)
- {
- if (grid[pos] == 0)
- {
- return 1;
- }
- else
- {
- return 0;
- }
- }
- void cat_message()
- {
- printf("\nCat - Nobody wins.");
- }
- void lost_message(char c)
- {
- printf("\nPlayer %c loses the game.", c);
- }
- void win_message(char c)
- {
- printf("\nPlayer %c wins the game.", c);
- }
- // Find the number of empty spots left.
- int find_empty_indices_l()
- {
- short indices_left = 0;
- short i;
- for (i = 0; i < GRID_SIZE; i++)
- {
- if (grid[i] == 0)
- {
- indices_left += 1;
- }
- }
- return indices_left;
- }
- // Find the index of the empty spots that are left, and then store those indexes
- // in an array that is the length of find_empty_indexes_l().
- int* find_empty_indices()
- {
- short indices_left;
- short i;
- short i_indices_left = 0;
- indices_left = find_empty_indices_l();
- int * indices_array = malloc(sizeof(char) * indices_left);
- for (i = 0; i < GRID_SIZE ; i++)
- {
- if (grid[i] == 0)
- {
- indices_array[i_indices_left] = i;
- i_indices_left += 1;
- }
- }
- return indices_array;
- }
- // Returns 0 if no cat detected. Returns 1 if cat is detected.
- int check_cat()
- {
- if (find_empty_indices() == 0) return 1;
- return 0;
- }
- // Allows the player to move. Uses scanf for input and uses error-checking to avoid invalid parameters.
- // Places an X at that location.
- void pla_move()
- {
- short pos;
- int check = 0;
- while (check == 0)
- {
- printf("\nChoose a position (1-9): \n");
- scanf("%d", &pos); // Entering any alphabetical characters seems to put this code into an infinite loop, bypassing intended user input. Works as intended for integers.
- if (valid_position(pos - 1) != 1 || pos > 9)
- {
- printf("Invalid position: try again\n");
- }
- else
- {
- check = 1;
- }
- }
- grid[pos - 1] = -1; // -1 corresponds to X.
- }
- // Allows the bot to move. Calculates what spots are left and moves to one randomly.
- // Finds a random index for the list of spots left, and choses the value at that index.
- // Places an O at that location.
- void bot_move()
- {
- short pos;
- int* valid_pos = find_empty_indices();
- srand(time(NULL));
- int pos_random = (rand() % find_empty_indices_l());
- pos = *(valid_pos+pos_random); // Randomly decided position on the main static grid.
- grid[pos] = 1;
- printf("\nThe bot moved to position %d\n", pos + 1);
- free(valid_pos); // malloc() allocates to the heap, so we want to free this just in-case.
- }
- // The win conditions for the game.
- int win_conditions(int b)
- {
- int win_flag = 0;
- if (grid[0] == b && grid[1] == b && grid[2] == b && win_flag == 0) // Top row
- {
- win_message(convert_digits(b));
- lost_message(convert_digits(-b));
- win_flag = 1;
- }
- if (grid[0] == b && grid[4] == b && grid[8] == b && win_flag == 0) // Top-left to bottom-right diagonal
- {
- win_message(convert_digits(b));
- lost_message(convert_digits(-b));
- win_flag = 1;
- }
- if (grid[0] == b && grid[3] == b && grid[6] == b && win_flag == 0) // Left row
- {
- win_message(convert_digits(b));
- lost_message(convert_digits(-b));
- win_flag = 1;
- }
- if (grid[1] == b && grid[4] == b && grid[7] == b && win_flag == 0) // Middle row (up-down)
- {
- win_message(convert_digits(b));
- lost_message(convert_digits(-b));
- win_flag = 1;
- }
- if (grid[2] == b && grid[5] == b && grid[8] == b && win_flag == 0) // Right row (up-down)
- {
- win_message(convert_digits(b));
- lost_message(convert_digits(-b));
- win_flag = 1;
- }
- if (grid[3] == b && grid[4] == b && grid[5] == b && win_flag == 0) // Middle row (left-right)
- {
- win_message(convert_digits(b));
- lost_message(convert_digits(-b));
- win_flag = 1;
- }
- if (grid[6] == b && grid[7] == b && grid[8] == b && win_flag == 0) // Bottom row (left-right)
- {
- win_message(convert_digits(b));
- lost_message(convert_digits(-b));
- win_flag = 1;
- }
- if (grid[2] == b && grid[4] == b && grid[6] == b && win_flag == 0) // Top-right to bottom-left diagonal
- {
- win_message(convert_digits(b));
- lost_message(convert_digits(-b));
- win_flag = 1;
- }
- if (win_flag == 0)
- {
- if (check_cat() == 1)
- {
- cat_message();
- }
- return win_flag;
- }
- return win_flag;
- }
- // Prints the digit grid instead of converting the digits to their respective 'X' or 'O' characters.
- void print_digit_grid()
- {
- short b;
- int t;
- for(b = 0; b < GRID_SIZE; b++)
- {
- t = grid[b];
- printf("%d", t);
- }
- }
- // Simply prints the current grid with the corresponding 'X' and 'O' characters for 1's and -1's.
- void print_grid()
- {
- printf("\n");
- short i;
- char x_or_o;
- for(i = 0; i <= GRID_SIZE - 1; i++)
- {
- x_or_o = convert_digits(grid[i]);
- printf("%c", x_or_o);
- if ((i + 1) % 3 == 0) // Format properly
- printf("\n");
- }
- }
- int main(int argc, char* argv[])
- {
- int win_flag = 0;
- while (win_flag != 1 && win_flag != -1)
- {
- pla_move();
- print_grid();
- win_flag = win_conditions(-1); // Check win condition for the player (-1)
- if (win_flag == 1)
- {
- break;
- }
- bot_move();
- print_grid();
- win_flag = win_conditions(1); // Check the win condition for the computer (1)
- }
- if (win_flag == 1)
- {
- print_grid(grid);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement