Simple Tic Tac Toe game inside terminal Hello fellow programmers. I started learning C last week and today I wanted to see if I can make a working program, so I made this game:
/*
 * TESTED IN LINUX - 2020
*/

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

int player = 1, choice;
int places[10] = {'o', '1', '2', '3', '4', '5', '6', '7', '8', '9'};

void switchPlayers();
void displayBoard();
int markBoard(char mark);
int checkForWin();

int main() {


    while (!checkForWin()){
        system(&quot;clear&quot;);
        displayBoard();
        switchPlayers();
    }
    system(&quot;clear&quot;);
    displayBoard();
    checkForWin();

    return 0;
}


void switchPlayers(){
    if (player == 1) {
        printf(&quot;     Player 1 choose: &quot;);
        scanf(&quot;%d&quot;, &amp;choice);
        if (markBoard('X'))
            player = 1;
        else
            player = 2;

    }
    else if (player == 2){
        printf(&quot;     Player 2 choose: &quot;);
        scanf(&quot;%d&quot;, &amp;choice);
        if (markBoard('O'))
            player = 2;
        else
            player = 1;

    }
}

void displayBoard(){
    printf(&quot;\n             X &amp; O           \n Player 1 (X) - Player 2 (O)\n\n&quot;);

    printf(&quot;\t    |   |   \n&quot;
           &quot;\t  %c | %c | %c \n&quot;
           &quot;\t ___|___|___\n&quot;
           &quot;\t    |   |   \n&quot;
           &quot;\t  %c | %c | %c \n&quot;
           &quot;\t ___|___|___\n&quot;
           &quot;\t    |   |   \n&quot;
           &quot;\t  %c | %c | %c \n&quot;
           &quot;\t    |   |   \n\n&quot;
           ,  places[1], places[2],
           places[3], places[4], places[5],
           places[6], places[7], places[8], places[9]);
}

int markBoard(char mark){
    for (int i = 1; i &lt; 10; ++i) {
        if (choice == i &amp;&amp; places[i]-48 == i) {
            places[i] = mark;
            return 0;
        }
    }
    return 1;
}

int checkForWin() {
    short draw = 0;

    //Horizontal check
    for (int i = 1; i &lt; 10; i += 3) {
        if (places[i] == places[i + 1] &amp;&amp; places[i + 1] == places[i + 2]) {
            printf(&quot;\tYou won!\n&quot;);
            return 1;
        }
    }
    //Vertical check
    for (int i = 1; i &lt; 4; i += 1) {
        if (places[i] == places[i + 3] &amp;&amp; places[i + 3] == places[i + 6]) {
            printf(&quot;\tYou won!\n&quot;);
            return 1;
        }
    }
    //Diagonal check
    if (places[1] == places[5] &amp;&amp; places[5] == places[9]) {
        printf(&quot;\tYou won!\n&quot;);
        return 1;
    } else if (places[3] == places[5] &amp;&amp; places[5] == places[7]) {
        printf(&quot;\tYou won!\n&quot;);
        return 1;
    }
    //Check for draw
    for (int j = 1; j &lt; 10; ++j) {
        if (places[j] - 48 != j)
            draw++;
    }
    if (draw == 9){
        printf(&quot;\t  Draw!\n&quot;);
        return 1;
    }

    return 0;
}

Do you have any tips on how I could make it more efficient or fix something I did wrong?
On the whole this is nicely done for an application made during your first week of C programming. The functions are generally reasonably-sized, the code is comprehensible and the design decisions are understandable given the size and purpose of the application.
My remarks mostly center around improving the design to support new features and avoid bugs. The merit of many of my points may be negligible if you're never planning on adding to the application beyond what you have, but if you'd like to add (for example) even fairly unassuming improvements like an AI opponent or arbitrary board sizes, the current design would be pushed beyond its narrow limits.
Avoid globals
Your core state variables
int player = 1, choice;
int places[10] = {'o', '1', '2', '3', '4', '5', '6', '7', '8', '9'};

should all be scoped to main at minimum. The problem with the existing design is that all functions operating on these global variables are non-idempotent. This means they are unsafe in a multithreaded environment and modify state outside of themselves which makes the application difficult to reason about and may lead to bugs.
The parameterless functions in your original code creates an illusion of simplicity. But in reality these functions are quite unsafe and would inhibit a larger application significantly.
Encapsulate related data
int player = 1, choice;
int places[10] = {'o', '1', '2', '3', '4', '5', '6', '7', '8', '9'};

Are loose variables that are conceptually attributes of the same entity and as such should be grouped in a TicTacToePosition structure along with a set of functions that operate on this structure. This makes it easier to understand the purpose and relationship between these pieces of data. Taken out of context, a variable name like places has non-obvious purpose, but as a struct member, position.places or ttt_state.squares is a bit clearer.
Separate UI from game logic
If you want to generalize and expand on your code, you'll need to detach user interaction from game logic. Doing so makes the code maintainable and expandable through looser coupling.
There are many subtle manifestations of the strong UI-game logic coupling throughout the app, like:
int markBoard(char mark){
    for (int i = 1; i &lt; 10; ++i) {
        //       ^
        if (choice == i &amp;&amp; places[i]-48 == i) {
            //                      ^^^
            places[i] = mark;
            return 0;
        }
    }
    return 1;
}

In the above code, the 1-indexing seems to be a convenience measure to avoid having to normalize 1-indexed user input to internal logic. But this convenience leads to an awkward board design for the programmer and a confusing magic 'o' character at the 0-th index.
Additionally, -48 is a conversion between external UI and internal game logic that markBoard shouldn't be responsible for. The correct name for this function is convertFromUserInputCharAndMarkBoard, which is overburdened. Normalize/sanitize user input outside of the tic tac toe board logic. This lets you keep the interface user-centric while supporting an intuitive internal representation for the programmer.
switchPlayers does more than switch players: it also takes user input. Those are two distinct things that should be separate.
checkForWin does win checking but also does IO, a side effect. Better to just return the result and let the caller handle the IO. In fact, checkForWin is called twice in the main function, once to check for a win and the second time to display the winning player after clearing the screen.
UX
I recommend spelling out the input format more precisely and using X wins! or O wins! instead of You won!.
Instead of Player 1 and Player 2, using X and O throughout removes ambiguity and lets you avoid a layer of indirection by having to display/explain Player 1 (X) - Player 2 (O) which asks the user to mentally translate between multiple terms for the players.
Bad input into scanf spams the console and there are no error messages or handling to speak of. scanf isn't the right tool here; use fgets to pull the line in as a string and parse the number out of it.
I'm not really crazy about system(&quot;clear&quot;). It feels invasive. If you're committed to this sort of interface, I'd go all in with curses. Or just keep it simple and keep printing without clearing.
Avoid convoluted logic
In checkForWin, the draw logic is somewhat hard to follow:
//Check for draw
for (int j = 1; j &lt; 10; ++j) {
    if (places[j] - 48 != j)
        draw++;
}
if (draw == 9){
    printf(&quot;\t  Draw!\n&quot;);
    return 1;
}

Once again, the -48 is an artifact of user input conversion that really doesn't belong in the game engine. Instead of a player variable and this manual draw check logic, most two-player board games use a single number, ply, which counts the turn. A draw check then becomes ply &gt;= length of board assuming is_won is called first, figuring out whose turn it is becomes ply % 2 and switching sides is ply++.
Ply can be used to avoid pointless win checks if not enough moves have been played. In tic tac toe, it seems like a minor optimization but it can speed up an AI that's running win checks thousands of times per turn, and it's a single extra line of code.
Consider breaking commented code out into functions
The checkForWin function has 4 distinct parts to it: checking horizontals, verticals, diagonals and draws. Each could be a separate function instead of delimiting the areas with comments. Otherwise, some of these loops could be merged and the logic simplified (it's debatable which is best).
Code style

Keep your braces consistent: void switchPlayers(){ should be void switchPlayers() {.

Use #include &lt;stdbool.h&gt;:
  if (draw == 9){
      printf(&quot;\t  Draw!\n&quot;);
      return 1;
  }

could then be
  if (draw == 9){
      printf(&quot;\t  Draw!\n&quot;);
      return true;
  }

which is easier for the programmer to understand.


Possible rewrite
While I'd prefer to use a bitboard and bitmasks to check win patterns, I think it's most instructive to keep the array format to avoid too radical of a departure from your design.
Feel free to accuse this code of being prematurely future-proof or anticipating adding AI and other features. Fair enough--it is more code. While I've gone somewhat deep into generalizing board sizes and so forth, you can cherry-pick the techniques that make sense for you and take the rest with a grain of salt.
Future steps might be adding a GUI, generalizing the board sizes with malloc or a FAM, adding an AI, adding a variant or network play.
#include &lt;stdbool.h&gt;
#include &lt;stdint.h&gt;
#include &lt;stdio.h&gt;

struct TicTacToePosition {
    uint8_t ply;
    uint8_t board_len;
    uint8_t side_len;
    char board[3][3];
};

struct TicTacToePosition ttt_init() {
    struct TicTacToePosition ttt_pos = {};
    ttt_pos.board_len = sizeof ttt_pos.board;
    ttt_pos.side_len = sizeof ttt_pos.board[0];
    return ttt_pos;
}

char ttt_current_player(const struct TicTacToePosition *pos) {
    return pos-&gt;ply % 2 ? 'O' : 'X';
}

char ttt_last_player(const struct TicTacToePosition *pos) {
    return pos-&gt;ply % 2 ? 'X' : 'O';
}

bool ttt_is_board_full(const struct TicTacToePosition *pos) {
    return pos-&gt;ply &gt;= pos-&gt;board_len;
}

bool ttt_legal_move(const struct TicTacToePosition *pos, int row, int col) {
    return row &gt;= 0 &amp;&amp; row &lt; pos-&gt;side_len &amp;&amp; 
           col &gt;= 0 &amp;&amp; col &lt; pos-&gt;side_len &amp;&amp; !pos-&gt;board[row][col];
}

bool ttt_try_move(struct TicTacToePosition *pos, int row, int col) {
    if (!ttt_legal_move(pos, row, col)) {
        return false;
    }

    pos-&gt;board[row][col] = ttt_current_player(pos);
    pos-&gt;ply++;
    return true;
}

bool ttt_line_win(const unsigned int len, const char *arr) {
    for (int i = 1; i &lt; len; i++) {
        if (!arr[0] || !arr[i] || arr[0] != arr[i]) {
            return false;
        }
    }
    
    return true;
}

bool ttt_is_won(const struct TicTacToePosition *pos) {
    if (pos-&gt;ply &lt; 5) return false;

    const uint8_t len = pos-&gt;side_len;
    char left_diag[len];
    char right_diag[len];

    for (int i = 0; i &lt; len; i++) {
        char column[len];
        left_diag[i] = pos-&gt;board[i][i];
        right_diag[i] = pos-&gt;board[i][len-i-1];

        for (int j = 0; j &lt; len; j++) {
            column[j] = pos-&gt;board[j][i];
        }

        if (ttt_line_win(len, pos-&gt;board[i]) || ttt_line_win(len, column)) {
            return true;
        }
    }

    return ttt_line_win(len, left_diag) || ttt_line_win(len, right_diag);
}

char ttt_fmt_square(const struct TicTacToePosition *pos, int i, int j) {
    return pos-&gt;board[i][j] ? pos-&gt;board[i][j] : i * pos-&gt;side_len + j + '1';
}

void ttt_print_board(const struct TicTacToePosition *pos) {
    puts(&quot;&quot;);

    for (int i = 0; i &lt; pos-&gt;side_len; i++) {
        for (int j = 0; j &lt; pos-&gt;side_len - 1; j++) {
            printf(&quot;   |&quot;);
        }

        printf(&quot;\n %c &quot;, ttt_fmt_square(pos, i, 0));

        for (int j = 1; j &lt; pos-&gt;side_len; j++) {
            printf(&quot;| %c &quot;, ttt_fmt_square(pos, i, j));
        }

        if (i &lt; pos-&gt;side_len - 1) {
            printf(&quot;\n___&quot;);

            for (int j = 1; j &lt; pos-&gt;side_len; j++) {
                printf(&quot;|___&quot;);
            }
        }

        puts(&quot;&quot;);
    }

    for (int i = 0; i &lt; pos-&gt;side_len - 1; i++) {
        printf(&quot;   |&quot;);
    }

    puts(&quot;\n&quot;);
}

int ttt_get_num(const char *failure_prompt) {
    for (;;) {
        int result;
        char buf[128];
        fgets(buf, sizeof buf, stdin);

        if (sscanf(buf, &quot;%d&quot;, &amp;result)) {
            return result;
        }
        
        printf(&quot;%s&quot;, failure_prompt);
    }
}

void ttt_get_move(struct TicTacToePosition *ttt_pos) {
    for (;;) {
        printf(&quot;Choose a square for %c's move: &quot;, 
               ttt_current_player(ttt_pos));
        int move = ttt_get_num(&quot;Invalid input. Try again: &quot;) - 1;
        int row = move / ttt_pos-&gt;side_len;
        int col = move % ttt_pos-&gt;side_len;

        if (ttt_try_move(ttt_pos, row, col)) {
            break;
        }

        puts(&quot;Invalid move. Pick an empty square between 1 and 9.&quot;);
    }
}

void ttt_play_game() {
    for (struct TicTacToePosition ttt_pos = ttt_init();;) {
        ttt_print_board(&amp;ttt_pos);
        ttt_get_move(&amp;ttt_pos);

        if (ttt_is_won(&amp;ttt_pos)) {
            ttt_print_board(&amp;ttt_pos);
            printf(&quot;%c won!\n&quot;, ttt_last_player(&amp;ttt_pos));
            break;
        }
        else if (ttt_is_board_full(&amp;ttt_pos)) {
            ttt_print_board(&amp;ttt_pos);
            puts(&quot;The game is a draw&quot;);
            break;
        }
    }
}

int main() {
    ttt_play_game();
    return 0;
}