Basketball brother warm tips ： Don't forget to exercise while programming !
The sky is like fate , It's always on top of everyone's head , No difference .

Let's relax today , A simple game to write —— tic-tac-toe ：

1, Design ideas

* First, there must be a chessboard
* Players enter coordinates by themselves , Computer random chess
* Three cases ： Player wins , Computer win , it ends in a draw
2, code implementation

Since it's a little game , We can set up a simple menu , such as 1 To start the game ,0 To exit the game ：
1,play ----------\n"); printf("---------- 0,exit ----------\n");
printf("-------------------------------\n"); }
With the menu, we are going to implement one of our logic , Of course, it is suggested that students should not write all the contents here main Inside the function , We use multi document writing today ：

First of all, we need to print this menu when the player is running , Player selection required , So we can use it here do while loop , Then it is adjusted according to the value entered by the player switch
Branch judgment , And encapsulate the game implementation part into a function game Inside ：
int main() { int input = 0; do { menu(); printf("Please select :>");
scanf("%d", &input); switch (input) { case 1: game(); break; case 0: break;
default: printf("Input error,please select again!\n"); break; } } while
(input); return 0; }
It can be seen from the above that we are simple main
It's enough to write so much in the function , We can see , You can play the game again and again ! When the player makes an error, he will also be reminded to re-enter ! The main game implementation functions we put game.c
in , We put the declaration of the function game.h Inside .

The preparations are done , Now we are going to implement the specific function !

Since we're playing chess , We must have a chessboard , Here the chessboard is set to 3*3 still 5*5 And ? What if we want to increase the chessboard later ? So let's just put it directly in the header file #define
Define a constant , This is very convenient. If we want to modify the size of the chessboard later, we don't have to modify it one by one !
#define ROW 3 // that 's ok #define COL 3 // column
Then we need to create our chessboard and initialize it !InitBoard Function will initialize all the contents of our chessboard into spaces . Here we use two for
Initialize by looping through a two-dimensional array ：
void InitBoard(char board[ROW][COL], int row, int col) { for (int i = 0; i <
row; ++i) { for (int j = 0; j < COL; ++j) { board[i][j] = ' '; } } }
Come here, our chessboard must have a simple appearance ! This little partner can design at will , So I'll simply design a chessboard today , such as ：

So how do we use it C Language print out ? It's actually very simple ：
void PrintBoard(char board[ROW][COL], int row, int col) { int i = 0; while (i
< row) { for (int j = 0; j < col; ++j) { if (j < col - 1) printf(" %c |",
board[i][j]); else printf(" %c ", board[i][j]); } printf("\n"); for (int j = 0;
j < col; ++j) { if (i < row - 1) { if (j < col - 1) printf("---|"); else
printf("---"); } } if(i < row - 1) printf("\n"); ++i; } }
design sketch ：( Small partners can adjust according to their favorite style )

With a chessboard , We can start playing chess , Then we must make a rule for this three piece chess , For example, players play chess ' * '  express , Chess under computer ' # '
express , Now that we have an appointment , Then you can start implementing the code !

Here we have to consider several issues ：

* Players must understand from 1 Line start , No, 0 that 's ok , But the array subscript is from 0 Started , We should pay attention to this !
* What if the position of playing chess has been played by the player or computer before ?
* If the subscript input is out of bounds , That is, what if the entered subscript is not a valid subscript ?
In fact, these three problems are very easy to solve , First, we ask the player to enter a subscript  x,y
Just subtract one , If the position is repeated , Let's just ask the player or computer to re-enter the new location , If the subscript is out of bounds , It must be a reminder to the player , And re-enter !

code implementation ：
void PlayerMove(char board[ROW][COL], int row, int col) { int x = 0; int y =
0; while (1) { printf("Please enter coordinates (x,y) :>"); scanf("%d,%d", &x,
&y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (board[x - 1][y - 1] ==
' ') { board[x - 1][y - 1] = '*'; break; } else printf("Coordinates
occupied!\n"); } else { printf("Coordinate error!\n"); } } }
Above is our players playing chess , What about computer chess ?

First of all, we should ensure the randomness of computer chess , At the same time, it is also necessary to limit the effective subscript range of the computer , Here we can use srand and rand Function to generate random numbers , The general idea is the same as the logic of players playing chess ：(
srand Setting the starting position will be shown later )
void ComuterMove(char board[ROW][COL], int row, int col) {
printf("ComuterMove:\n"); while (1) { // x, y = [0, 2] int x = rand() % row;
int y = rand() % col; if (board[x][y] == ' ') { board[x][y] = '#'; break; } } }
We have solved the problem of playing chess , The rest is to judge whether to win or lose , as one can imagine , Only players win this game , Computer win , Or draw , So how should we design this ?

If the player wins , Then we'll go back ' * ', If the computer wins , We'll go back ' # ', When the chessboard is full, it proves to be a draw , We'll go back ' d '
, In addition to the above three cases , We all need to continue the game , Then we'll go back ' c ';
/* return '*' PlayerWin return '#' comuterWin return 'c' GameContinue return
'd' GameDogfall */ char IsWin(char board[ROW][COL], int row, int col);
Anyone who has played Sanzi knows the rules , If three lines are connected horizontally , Or three straight lines , And oblique can be connected into a line , So we have to judge these four situations separately ： that 's ok (row), column (col)
, oblique (tilted), it ends in a draw (Dogfall)

The implementation of this function will be a little more difficult than the above , Because we can't write down the judgment conditions directly , for instance : boare[0][0] == boare[0][1]
&&  boare[0][1] == boare[0][2], If that's true , If we want to use 5*5 A chessboard or 8*8
Where's your chessboard ? So here we can use the idea of traversing two-dimensional arrays ：

code implementation ：
char IsWin(char board[ROW][COL], int row, int col) { //row for (int i = 0; i <
row; ++i) { for (int j = 0; j < col; ++j) { if (j < col - 2 && board[i][j] != '
' && board[i][j] == board[i][j + 1] && board[i][j + 1] == board[i][j + 2])
return board[i][j]; } } //col for (int i = 0; i < col; ++i) { for (int j = 0; j
< row; ++j) { if (j < row - 2 && board[j][i] != ' ' && board[j][i] == board[j +
1][i] && board[j + 1][i] == board[j + 2][i]) return board[j][i]; } } //tilted
for (int i = 0; i < row ; ++i) { for (int j = 0; j < col; ++j) { if (j < col -
2 && board[i][j] != ' ' && board[i][j] == board[i + 1][j + 1] && board[i + 1][j
+ 1] == board[i + 2][j + 2]) return board[i][j]; } } for (int i = 0; i < row;
++i) { for (int j = 0; j < col; ++j) { if (j > 1 && board[i][j] != ' ' &&
board[i][j] == board[i + 1][j - 1] && board[i + 1][j - 1] == board[i + 2][j -
2]) return board[i][j]; } } //Dogfall while (1) { int count = 0; for (int i =
0; i < row; ++i) { for (int j = 0; j < col; ++j) { if (board[i][j] == ' ') {
count = 1; } } } if (count == 0) return 'd'; else return 'c'; } }
In fact, the above code has one point to say ： First judge the line (row) We should prevent subscripts from crossing the border when visiting , So need j < col - 2, If you don't write that , Let's imagine , If we only have
3*3 Chessboard , Is it necessary for us to judge those coordinate positions from the second column ? It's not necessary , Because there are at most two valid coordinates from the second column !

I believe you can understand the following code by relying on the above explanation ! If you don't understand or have better suggestions, you can tell me !

The next step is to game Function to call the functions we just wrote ：
void game() { char ret = 0; //The starting value srand((unsigned)time(NULL));
char board[ROW][COL] = { 0 }; InitBoard(board, ROW, COL); printf("Start the
game.\n"); PrintBoard(board, ROW, COL); while (1) { PlayerMove(board, ROW,
COL); ret = IsWin(board, ROW, COL); if (ret != 'c') break; PrintBoard(board,
ROW, COL); ComuterMove(board, ROW, COL); ret = IsWin(board, ROW, COL); if (ret
!= 'c') break; PrintBoard(board, ROW, COL); } if (ret == '*')
printf("PlayerWin!\n"); else if (ret == '#') printf("comuterWin!\n"); else
printf("GameDogfall!\n"); PrintBoard(board, ROW, COL); }
And us game.h The header file of contains the function declaration part ：
#pragma once #include <stdio.h> #include <stdlib.h> #include <time.h> #include
<windows.h> #define ROW 5 #define COL 5 void InitBoard(char board[ROW][COL],
int row, int col); void PrintBoard(char board[ROW][COL], int row, int col);
void PlayerMove(char board[ROW][COL], int row, int col); void ComuterMove(char
board[ROW][COL], int row, int col); /* return '*' PlayerWin return '#'
comuterWin return 'c' GameContinue return 'd' GameDogfall */ char IsWin(char
board[ROW][COL], int row, int col);
okay , The code is finished , Let's try two ：

It may be a bit silly to play chess on the computer , It can only play chess at random , Interested partners can come down and optimize them into intelligent chess players , I didn't put the code with the picture this time , You can also directly copy
Let's play with my code, huh !

In fact, this game is not the main one , The main thing is that I hope my partners can exercise their programming logic through this small case , Like recursion , Write too much , Of course , There's a good saying , It's better to knock once than to see ten times , Take out the computer and knock the code !

Fight for a better tomorrow , Come on , Teenagers !

Technology
Daily Recommendation