This is a tic-tac-toe game that I made in C. It works the way that I want it to but I feel like I could have done it better or shorter. Any input as to how I did would be appreciated.
Include Statements and Prototypes
#include <stdio.h> #include <stdlib.h> #include <string.h> //Creating the prototypes int init(char ttt1[3][3]); int display_board(char ttt2[3][3]); int turn(int *player_turns); int get_move(char ttt3[3][3], int player_turns2, int *move, char player1[], char player2[]); int validate_move(int move); int check_win(char ttt[3][3], int turns); int update_board(char ttt[3][3], const int * move, int turn); int menu(); Main Function
int main(void) { int play_again = 1; //set up the loop if(menu() == 1){ //calling the menu while(play_again == 1) { //as long as the player wants to play again, loop int player_turn = 1; int move = 0; int turns = 1; char player1[20]; char player2[20]; char ttt[3][3]; //create the array init(ttt); //initialize the board printf("Enter Player 1 name(without using spaces): "); scanf(" %s", player1); printf("%s, you are 'X'\n", player1); printf("Enter Player 2 name(without using spaces): "); scanf(" %s", player2); printf("%s, you are 'O'\n", player2); while (check_win(ttt, turns) == 0) { get_move(ttt, player_turn, &move, player1, player2); //receive the moves from the player validate_move(move); //call the function to validate the moves update_board(ttt, &move, player_turn); //call the function which updates the board based on the players move display_board(ttt); //redisplay the board turn(&player_turn); //call the function to change whose turn it is turns++; //increment turns } printf("Would you like to play again?(1 for yes, 2 for no) "); scanf(" %d", &play_again); } } return 0; } Board Initializer
//set up the board for use in the game int init(char ttt1[3][3]){ ttt1[0][0] = '1'; ttt1[0][1] = '2'; ttt1[0][2] = '3'; ttt1[1][0] = '4'; ttt1[1][1] = '5'; ttt1[1][2] = '6'; ttt1[2][0] = '7'; ttt1[2][1] = '8'; ttt1[2][2] = '9'; return 0; } Board Display
This does display the board the way it should but I need a way to clear the screen. I have tried a few ways that I found online but since I am on Mac OS none of it worked. What is a good way to clear the screen that is portable?
//showing the board on the screen int display_board(char ttt2[3][3]){ printf("%c | %c | %c\n", ttt2[0][0], ttt2[0][1], ttt2[0][2]); //displays the top row printf("----------\n"); printf("%c | %c | %c\n", ttt2[1][0], ttt2[1][1], ttt2[1][2]); //displays the middle row printf("----------\n"); printf("%c | %c | %c\n", ttt2[2][0], ttt2[2][1], ttt2[2][2]); //displays the bottom row return 0; } Which Turn
int turn(int *player_turns1){ if(*player_turns1 == 1){ //if it is player one's turn *player_turns1 = 2; //change it to player two's turn } else if(*player_turns1 == 2){ //if it is player two's turn *player_turns1 = 1; // change it to player one's turn } return 0; } Move Retrieval
//get the move from the player depending on whose turn it is int get_move(char ttt3[3][3], int player_turns2, int *move, char player1_1[], char player2_1[]){ if(player_turns2 == 1){ //if it is player one's turn display_board(ttt3); //display the board printf("%s, please enter where you would like to move: ", player1_1); //ask for the move scanf(" %d", move);//get the move from the player } else if(player_turns2 == 2){ //if it is player two's turn display_board(ttt3); //display the board printf("%s, please enter where you would like to move: ", player2_1); //ask for the move scanf(" %d", move); //get the move from the player } return *move; } Move Validator
int validate_move(int move1){ if (move1 < 1 || move1 > 9) { //if the move is on the board return 0; } else //if the move does not fall on the board return 1; } Update the Board
//function that updates the board with the user's move int update_board(char ttt[3][3], const int *move, int turn){ if(*move == 1 && turn == 1) //top left is chosen by player one ttt[0][0] = 'X'; //set the square to x else if(*move == 1 && turn == 2) //top left is chosen by player two ttt[0][0] = 'O'; //set the square to o else if(*move == 2 && turn == 1) //top middle is chosen by player one ttt[0][1] = 'X'; //set the square to x else if(*move == 2 && turn == 2) //top middle is chosen by player two ttt[0][1] = 'O'; //set the square to o else if(*move == 3 && turn == 1) //top right is chosen by player one ttt[0][2] = 'X'; //set the square to x else if(*move == 3 && turn == 2) //top right is chosen by player two ttt[0][2] = 'O'; //set the square to o else if(*move == 4 && turn == 1) //middle left is chosen by player one ttt[1][0] = 'X'; //set the square to x else if(*move == 4 && turn == 2) //middle left is chosen by player two ttt[1][0] = 'O'; //set the square to o else if(*move == 5 && turn == 1) //middle is chosen by player one ttt[1][1] = 'X'; //set the square to x else if(*move == 5 && turn == 2) //middle is chosen by player two ttt[1][1] = 'O'; //set the square to o else if(*move == 6 && turn == 1) //middle right is chosen by player one ttt[1][2] = 'X'; //set the square to x else if(*move == 6 && turn == 2) //middle right is chosen by player two ttt[1][2] = 'O'; //set the square to o else if(*move == 7 && turn == 1) //bottom right is chosen by player one ttt[2][0] = 'X'; //set the square to x else if(*move == 7 && turn == 2) //bottom right is chosen by player two ttt[2][0] = 'O'; //set the square to o else if(*move == 8 && turn == 1) //bottom middle is chosen by player one ttt[2][1] = 'X'; //set the square to x else if(*move == 8 && turn == 2) //bottom middle is chosen by player two ttt[2][1] = 'O';//set the square to o else if(*move == 9 && turn == 1) //bottom right is chosen by player one ttt[2][2] = 'X'; //set the square to x else if(*move == 9 && turn == 2) //bottom right is chosen by player two ttt[2][2] = 'O'; //set the square to o return 0; } Victory/Tie Check
//check the board to see if there is a winner int check_win(char ttt[3][3], int turns1){ if(ttt[0][0] == ttt[0][1] && ttt[0][1] == ttt[0][2]) { //top row horizontal check printf("Congratulations, You Won!\n"); return 1; } else if(ttt[1][0] == ttt[1][1] && ttt[1][1] == ttt[1][2]) { //middle row horizontal check printf("Congratulations, You Won!\n"); return 1; } else if(ttt[2][0] == ttt[2][1] && ttt[2][1] == ttt[2][2]) { //bottom row horizontal check printf("Congratulations, You Won!\n"); return 1; } else if(ttt[0][0] == ttt[1][0] && ttt[1][0] == ttt[2][0]) { //left column vertical check printf("Congratulations, You Won!\n"); return 1; } else if(ttt[0][1] == ttt[1][1] && ttt[1][1] == ttt[2][1]) { //middle column vertical check printf("Congratulations, You Won!\n"); return 1; } else if(ttt[0][2] == ttt[1][2] && ttt[1][2] == ttt[2][2]) { //right column vertical check printf("Congratulations, You Won!\n"); return 1; } else if(ttt[0][0] == ttt[1][1] && ttt[1][1] == ttt[2][2]) { //top left to bottom right diagonal check printf("Congratulations, You Won!\n"); return 1; } else if(ttt[2][0] == ttt[1][1] && ttt[1][1] == ttt[0][2]) { //top right to bottom left diagonal check printf("Congratulations, You Won!\n"); return 1; } else if(turns1 >= 10) //checks to see if the game ends in a tie printf("The game ends in a draw, no one wins.\n"); else return 0; } Menu Function
Switch/Case seemed to be the best way that I could think of to do a menu. Options 2-4 are my next projects to be working on.
//the function that controls the menu int menu(){ int state = 0; //establish the state variable printf("Welcome to my Tic Tac Toe Game!\n"); printf("How would you like to play?\n"); printf("1. 2D Player vs. Player\n"); printf("2. 2D Player vs. Computer(Not ready yet)\n"); printf("3. 3D Player vs. Player(Not ready yet)\n"); printf("3. 3D Player vs. Computer(Not ready yet)\n"); printf("Enter your choice: "); scanf(" %d", &state); //get the user's choice for the menu switch(state){ case 1: //option 1 in the menu return 1; case 2: //option 2 in the menu return 2; case 3: //option 3 in the menu return 3; case 4: //option 4 in the menu return 4; default: //if an invalid option is chosen printf("There was an error. Please try again."); } } I know that this code works as I want it to but I feel like it's too long or that there are easier ways to achieve some of the tasks. Again, any help or input is much appreciated.