tic-tac-toe
catalogue
1, Problem introduction
Sanzi chess is also called Jingzi chess in the folk. Because people often don't draw the frame of the chessboard when playing, just like the word "well" in Chinese characters, it is often called "well chess".
The rules of the game are very simple:
In 3 × Both sides of the chessboard of 3 take turns to play chess (the first hand's general pieces are "X" and the second hand is "O"). When the pieces played by one side are connected into a straight line, it is victory!
2, Realization idea
- Create game menu
- Initialize chessboard
- Print chessboard
- Players play chess (judge whether they win)
- Computer chess (judge whether to win)
- game over
3, Implementation process
1. Create game menu
//Menu function void menu(void) { printf("|---------------|\n"); printf("|--- 1.START ---|\n"); printf("|--- 0.EXIT ---|\n"); printf("|---------------|\n"); }
1. Start the game 0. Exit the game
2. Initialize the chessboard
Create 3 using global variables × 3 chessboard
Reasons for using global variables:
- It is more convenient to modify the size of the chessboard later
- Enhanced code readability
//Define rows and columns #define ROW 3 #define COL 3
//Initialize checkerboard function void InitChessBoard(char Board[ROW][COL], int row, int col) { int i = 0; int j = 0; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { //Initializes each element in the array as a space Board[i][j] = ' '; } } }
3. Print chessboard
Here, in order to facilitate the subsequent change of the size of the chessboard, the split lines are printed separately
//Print checkerboard function void DisplayChessBoard(char Board[ROW][COL], int row, int col) { int i = 0; int j = 0; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { //Print "character | character | character" printf(" %c ", Board[i][j]); if (j < col - 1) { printf("|"); } } //Wrap after printing a line printf("\n"); if (i <row-1) { //Print "---" --- "---" for (j = 0; j < row; j++) { printf("---"); if (j < col - 1) { printf("|"); } } } //Wrap after printing a line printf("\n"); } }
4. Players play chess
Players need to enter the number in [1, 3] to place "x"
- When the player enters coordinates beyond the size of the chessboard, remind the player of the wrong coordinates and re-enter them
- When the player enters the occupied chessboard coordinates, remind the player of the wrong coordinates and re-enter
//Player chess function void PlayerMove(char Board[ROW][COL], int row, int col) { int x = 0; int y = 0; while (1) { printf("player(ranks):>"); //Players enter coordinates scanf("%d %d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { //The player input range is [1, 3] if (Board[x - 1][y - 1] == ' ') { Board[x - 1][y - 1] = 'x'; break; } else { printf("This coordinate has been occupied, please re-enter!\a\n\n"); } } else { printf("The coordinates entered are illegal. Please re-enter!\a\n\n"); } } }
5. Computer chess
Computer chess needs to generate random number seeds, and ensure that the computer falls on empty coordinates
Use the generated random number function in the main function, Ensure that the generated random number is random:
srand((unsigned int)time(NULL)); //The function return type of time is time_t //Cast type (unsigned int) is used here
//Computer chess function void ComputerMove(char Board[ROW][COL], int row, int col) { int x = 0; int y = 0; printf("computer:\n"); while (1) { //Get time random number x = rand() % row; y = rand() % col; if (Board[x][y] == ' ') { Board[x][y] = 'o'; break; } } }
6. Judge the victory of the game
In this step, we need to define two functions:
- IsWin function (judge whether to win or not)
- IsFull function (judge whether the chessboard is full)
We agreed that the player would win when returning to "x"
Computer wins when returning to "o"
Return "q" for a draw
Returning to "c" means that the board is not filled and the game continues
//Judge whether victory function char IsWin(char Board[ROW][COL], int row, int col) { int i = 0; //Judgment line for (i = 0; i < row; i++) { if (Board[i][0] == Board[i][1] && Board[i][1] == Board[i][2] && Board[i][1] != ' ') { return Board[i][1]; } } //Judgment column for (i = 0; i < col; i++) { if (Board[0][i] == Board[1][i] && Board[1][i] == Board[2][i] && Board[1][i] != ' ') { return Board[1][i]; } } //Judge diagonal "\" if (Board[0][0] == Board[1][1] && Board[1][1] == Board[2][2] && Board[1][1] != ' ') { return Board[1][1]; } //Judge diagonal "/" if (Board[0][2] == Board[1][1] && Board[1][1] == Board[2][0] && Board[1][1] != ' ') { return Board[1][1]; } //Check that the chessboard is full if (IsFull == 1) { //Return to a draw return 'q'; } //Return to continue return 'c'; }
//Function to determine whether the chessboard is filled int IsFull(char Board[ROW][COL], int row, int col) { int i = 0; int j = 0; for(i = 0; i < row; i++) { for (j = 0; j < col; j++) { if (Board[i][j] == ' ') return 0; } } return 1; }
7. Game function and main tone function
//Game implementation function void Game(char Board[ROW][COL], int row, int col) { InitChessBoard(Board, ROW, COL); DisplayChessBoard(Board, ROW, COL); while (1) { PlayerMove(Board, ROW, COL); DisplayChessBoard(Board, ROW, COL); if (IsWin(Board, ROW, COL) != 'c') break; ComputerMove(Board, ROW, COL); DisplayChessBoard(Board, ROW, COL); if (IsWin(Board, ROW, COL) != 'c') break; } if (IsWin(Board, ROW, COL) == 'x') printf("PLAYER WIN!\n\n"); else if (IsWin(Board, ROW, COL) == 'o') printf("COMPUTER WIN!\n\n"); else printf("it ends in a draw!\n\n"); }
//calling function int main(void) { srand((unsigned int)time(NULL)); char Board[ROW][COL] = { 0 }; int input = 0; do { menu(); printf("please enter:>"); scanf("%d", &input); switch (input) { case 1: printf("GAME START\n"); Game(Board, ROW, COL); break; case 0: printf("GAME EXIT\n\a"); break; default: printf("ERROR!\n\a"); } } while (input); return 0; }
4, Code overview
#define _CRT_SECURE_NO_WARNINGS 1 //Header file required by the program #include <stdio.h> #include <stdlib.h> #include <time.h> //Define rows and columns #define ROW 3 #define COL 3 //Menu function void menu(void) { printf("|---------------|\n"); printf("|--- 1.START ---|\n"); printf("|--- 0.EXIT ---|\n"); printf("|---------------|\n"); } //Initialize checkerboard function void InitChessBoard(char Board[ROW][COL], int row, int col) { int i = 0; int j = 0; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { Board[i][j] = ' '; } } } //Print checkerboard function void DisplayChessBoard(char Board[ROW][COL], int row, int col) { int i = 0; int j = 0; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { printf(" %c ", Board[i][j]); if (j < col - 1) { printf("|"); } } printf("\n");//Wrap after printing a line if (i <row-1) { for (j = 0; j < row; j++) { printf("---"); if (j < col - 1) { printf("|"); } } } printf("\n"); } } //Player chess function void PlayerMove(char Board[ROW][COL], int row, int col) { int x = 0; int y = 0; while (1) { printf("player(ranks):>"); //Players enter coordinates scanf("%d %d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { //The player input range is [1, 3] if (Board[x - 1][y - 1] == ' ') { Board[x - 1][y - 1] = 'x'; break; } else { printf("This coordinate has been occupied, please re-enter!\a\n\n"); } } else { printf("The coordinates entered are illegal. Please re-enter!\a\n\n"); } } } //Computer chess function void ComputerMove(char Board[ROW][COL], int row, int col) { int x = 0; int y = 0; printf("computer:\n"); while (1) { //Get time random number x = rand() % row; y = rand() % col; if (Board[x][y] == ' ') { Board[x][y] = 'o'; break; } } } //Function to determine whether the chessboard is filled int IsFull(char Board[ROW][COL], int row, int col) { int i = 0; int j = 0; for(i = 0; i < row; i++) { for (j = 0; j < col; j++) { if (Board[i][j] == ' ') return 0; } } return 1; } //Judge whether victory function char IsWin(char Board[ROW][COL], int row, int col) { int i = 0; //Judgment line for (i = 0; i < row; i++) { if (Board[i][0] == Board[i][1] && Board[i][1] == Board[i][2] && Board[i][1] != ' ') { return Board[i][1]; } } //Judgment column for (i = 0; i < col; i++) { if (Board[0][i] == Board[1][i] && Board[1][i] == Board[2][i] && Board[1][i] != ' ') { return Board[1][i]; } } //Judge diagonal "\" if (Board[0][0] == Board[1][1] && Board[1][1] == Board[2][2] && Board[1][1] != ' ') { return Board[1][1]; } //Judge diagonal "/" if (Board[0][2] == Board[1][1] && Board[1][1] == Board[2][0] && Board[1][1] != ' ') { return Board[1][1]; } //Check that the chessboard is full if (IsFull == 1) { //Return to a draw return 'q'; } //Return to continue return 'c'; } //Game implementation function void Game(char Board[ROW][COL], int row, int col) { InitChessBoard(Board, ROW, COL); DisplayChessBoard(Board, ROW, COL); while (1) { PlayerMove(Board, ROW, COL); DisplayChessBoard(Board, ROW, COL); if (IsWin(Board, ROW, COL) != 'c') break; ComputerMove(Board, ROW, COL); DisplayChessBoard(Board, ROW, COL); if (IsWin(Board, ROW, COL) != 'c') break; } if (IsWin(Board, ROW, COL) == 'x') printf("PLAYER WIN!\n\n"); else if (IsWin(Board, ROW, COL) == 'o') printf("COMPUTER WIN!\n\n"); else printf("it ends in a draw!\n\n"); } //calling function int main(void) { srand((unsigned int)time(NULL)); char Board[ROW][COL] = { 0 }; int input = 0; do { menu(); printf("please enter:>"); scanf("%d", &input); switch (input) { case 1: printf("GAME START\n"); Game(Board, ROW, COL); break; case 0: printf("GAME EXIT\n\a"); break; default: printf("ERROR!\n\a"); } } while (input); return 0; }
5, Code considerations
- Where loops need to be used in the program and where loops do not need to be used should be carefully distinguished
- In the Game() function, whenever a player plays chess or a computer plays chess, he needs to judge whether he wins or not