This code can play a game according to the number of lines you specify, not limited to 3 rows and 3 columns
Design Ideas
- Since this code is more than usual, I use multi-file management to reduce maintenance costs
- Function declaration placed in game.h header file
- Place game-related function definitions in the game.c source file
- The main function is placed in main.c alone
- When designing code, write out the body logic first, then test the correctness of the logic while implementing the code.
The following:
Start with the main function and write the general logic
int main(void) { int input = 0; do { menu(); printf("Please enter your choice:"); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("Exit the game!"); break; default: printf("Input error, please re-enter!"); break; } } while (input); return 0; }
Menu Functions
void menu() { printf("**********************************\n"); printf("***** 1.play 0.exit *****\n"); printf("**********************************\n"); }
Write out the logic of the game function
1. ** You want to play chess on the board, so create a two-dimensional array to act as the board** 1. ** Now you need a function to initialize the board, write it out first ** 1. ** Print the board for players to play, so you need a function to print the board ** 1. ** Now the player can start playing, and you need a function to play the board ** 1. ** Print the board ** 1. ** When the player has finished playing, the computer plays chess, Need a function for computer chess** 1. ** And after the player or computer has finished playing, it needs to be judged 1. Who wins 2. Whether or not the draw (the board is full) continues if none of the above happens, so this is a player's game and computer chess is a cyclic process**
void game() { char board[ROW][COL]; char ret = 0; srand((unsigned)time(NULL)); InitBoard(board, ROW, COL); PrintBoard(board, ROW, COL); while (1) { PlayerMove(board, ROW, COL); PrintBoard(board, ROW, COL); ret = IsWin(board, ROW, COL); board, ROW, COL); PrintBoard(board, ROW, COL); ret = IsWin(board, ROW, COL); } }
Initialize the board
- Initialize the board to a space, which takes up space
void InitBoard(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 board
- Printing a board prints out a frame
Looking closely at the board, you can see that for each line of the board, it consists of two lines, but the last line is not printed.
- First line: Three spaces plus |.....
- Line 2: Three underscores plus |....
So you can write the following code
void PrintBoard(char board[ROW][COL], int row, int col) { int i = 0; int j = 0; for(i=0; i<row; i++) { printf(" %c | %c | %c | %c | %c \n", board[i][0],board[i][1],.. board[i][4]); if(i<row-1) printf("---|---|---|---|---\n"); } }
But the problem with the above code is that the number of columns is fixed, so we have to find out the rules of the columns based on the rules of the rows to write the code.
As we can see from our observations, each column of the board consists of two parts: only the second part of the last column of the board is not printed.
- Part One: Three Spaces
- Part Two: One |
- Similar to split parts
The code is as follows:
void PrintBoard(char board[ROW][COL], int row, int col) { int i = 0; for (i = 0; i < row; i++) { //Part One of the Board Line | | int j = 0; for (j = 0; j < col; j++) { //Part One of the Board Column printf(" %c ", board[i][j]); //Part Two of the Board Column if (j < col - 1) { printf("|"); } } printf("\n"); //Second part of the board line---|---|--- if (i < row - 1) { int j = 0; for (j = 0; j < col; j++) { //Part One of the Board Column printf("---"); //Part Two of the Board Column if (j < col - 1) { printf("|"); } } } printf("\n"); } }
Player Walks
The logic is simple, that is, to determine whether or not to override and whether or not to go beyond the boundaries. Note: Player's coordinates and programmer's coordinates are different
void PlayerMove(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; while (1) { printf("Player Walks:"); scanf("%d %d", &x, &y); if (x >= 0 && x <= row && y >= 0 && y <= col) { if (board[x - 1][y - 1] == ' ') { board[x - 1][y - 1] = '*'; break; } else { printf("This location is occupied!"); } } else { printf("Please re-enter!"); } } }
Computer walk
Just think about coverage when the computer goes
void ComputerMove(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; printf("Computer walk:\n"); while (1) { x = rand() % row; y = rand() % col; if (board[x][y] == ' ') { board[x][y] = '#'; break; } } }
Judge the board
There are four cases:
- Player wins and returns'*'
- Computer wins, return to'#
There are four things to consider when deciding who wins: Return directly to the same character, win if you return * and win if you return #
- Lines are the same:
- Columns are the same:
- The main diagonals are the same:
- The secondary diagonals are the same:
- Draw (is the board full), return to'Q'
- Continue the game and return to -'C'
Perfect game Function Logic
void game() { char board[ROW][COL]; char ret = 0; srand((unsigned)time(NULL)); InitBoard(board, ROW, COL); PrintBoard(board, ROW, COL); while (1) { PlayerMove(board, ROW, COL); PrintBoard(board, ROW, COL); ret = IsWin(board, ROW, COL); if ('C' != ret) break; ComputerMove(board, ROW, COL); PrintBoard(board, ROW, COL); ret = IsWin(board, ROW, COL); if ('C' != ret) break; } if ('#' == ret) printf("Computer wins!\n"); if ('*' == ret) printf("Player wins!\n"); if ('Q' == ret) printf("It ends in a draw!\n"); }
Functions for Judging Board Conditions
char IsWin(char board[ROW][COL], int row, int col) { int i = 0; int j = 0; char flag[ROW]; //Save the data to determine if it's the same int temp = 0; //Identify Lines Same for (i = 0; i < row; i++) { //Pass characters from each line to the flag array for (j = 0; j < col; j++) { flag[j] = board[i][j]; } //Determine if all flag arrays are identical for (j = 0; j < col - 1; j++) { if (flag[j] != flag[j + 1]) { break; } } if (col-1 == j && flag[0] != ' ') //If j=col-1 when jumping out, it means that the comparison is complete and the same { return flag[0]; } } //Identify Columns as Same while (temp < col) { //Pass each class individually to the flag array for (i = 0; i < row; i++) { for (j = 0; j < col; j++) //Win or not for column { if (temp == j) { flag[i] = board[i][j]; break; } } } //Determine if flag is the same for (j = 0; j < col - 1; j++) { if (flag[j] != flag[j + 1]) break; } if (j == col - 1 && flag[0] != ' ') return flag[0]; temp++; } //Judging that the principal diagonals are the same for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { if (i == j) { flag[i] = board[i][j]; } } } for (j = 0; j < col-1; j++) { if (flag[j] != flag[j + 1]) break; } if (j == col - 1 && flag[0] != ' ') return flag[0]; //Judging that the secondary diagonals are the same, since the two coordinates together are exactly equal to the number of columns (rows) -1, you can set them as follows for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { if (i + j == (col - 1)) { flag[i] = board[i][j]; } } } for (j = 0; j < col - 1; j++) { if (flag[j] != flag[j + 1]) break; } if (j == col - 1 && flag[0] != ' ') return flag[0]; //Draw or not, encapsulates a function to determine if the board is full int ret = IsFull(board, row, col); if (1 == ret) return 'Q'; return 'C'; }
Determine if the board is full
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; }
The complete code is as follows:
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> #include<time.h> #define ROW 5 #define COL 5 //Initialize the board void InitBoard(char board[ROW][COL], int row, int col); //Print board void PrintBoard(char board[ROW][COL], int row, int col); //Player Walks void PlayerMove(char board[ROW][COL], int row, int col); //Computer walk void ComputerMove(char board[ROW][COL], int row, int col); //Judge the board char IsWin(char board[ROW][COL], int row, int col);
#define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" void InitBoard(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] = ' '; } } } void PrintBoard(char board[ROW][COL], int row, int col) { int i = 0; for (i = 0; i < row; i++) { int j = 0; for (j = 0; j < col; j++) { printf(" %c ", board[i][j]); if (j < col - 1) { printf("|"); } } printf("\n"); if (i < row - 1) { int j = 0; for (j = 0; j < col; j++) { printf("---"); if (j < col - 1) { printf("|"); } } } printf("\n"); } } void PlayerMove(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; while (1) { printf("Player Walks:"); scanf("%d %d", &x, &y); if (x >= 0 && x <= row && y >= 0 && y <= col) { if (board[x - 1][y - 1] == ' ') { board[x - 1][y - 1] = '*'; break; } else { printf("This location is occupied!"); } } else { printf("Please re-enter!"); } } } void ComputerMove(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; printf("Computer walk:\n"); while (1) { x = rand() % row; y = rand() % col; if (board[x][y] == ' ') { board[x][y] = '#'; break; } } } char IsWin(char board[ROW][COL], int row, int col) { int i = 0; int j = 0; char flag[ROW]; int temp = 0; //Judgement line for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { flag[j] = board[i][j]; } for (j = 0; j < col; j++) { if (j == col - 1) break; if (flag[j] != flag[j + 1]) { break; } } if (col-1 == j && flag[0] != ' ') { return flag[0]; } } //Judgement Column while (temp < col) { for (i = 0; i < row; i++) { for (j = 0; j < col; j++) //Win or not for column { if (temp == j) { flag[i] = board[i][j]; break; } } } for (j = 0; j < col - 1; j++) { if (flag[j] != flag[j + 1]) break; } if (j == col - 1 && flag[0] != ' ') return flag[0]; temp++; } //Principal Diagonal for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { if (i == j) { flag[i] = board[i][j]; } } } for (j = 0; j < col-1; j++) { if (flag[j] != flag[j + 1]) break; } if (j == col - 1 && flag[0] != ' ') return flag[0]; //Paradiagonal for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { if (i + j == (col - 1)) { flag[i] = board[i][j]; } } } for (j = 0; j < col - 1; j++) { if (flag[j] != flag[j + 1]) break; } if (j == col - 1 && flag[0] != ' ') return flag[0]; //Is it a draw int ret = IsFull(board, row, col); if (1 == ret) return 'Q'; return 'C'; } //Determine if the board is full 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; }
#define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" void menu() { printf("**********************************\n"); printf("***** 1.play 0.exit *****\n"); printf("**********************************\n"); } void game() { char board[ROW][COL]; char ret = 0; srand((unsigned)time(NULL)); InitBoard(board, ROW, COL); PrintBoard(board, ROW, COL); while (1) { PlayerMove(board, ROW, COL); PrintBoard(board, ROW, COL); ret = IsWin(board, ROW, COL); if ('C' != ret) break; ComputerMove(board, ROW, COL); PrintBoard(board, ROW, COL); ret = IsWin(board, ROW, COL); if ('C' != ret) break; } if ('#' == ret) printf("Computer wins!\n"); if ('*' == ret) printf("Player wins!\n"); if ('Q' == ret) printf("It ends in a draw!\n"); } int main(void) { int input = 0; do { menu(); printf("Please enter your choice:"); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("Exit the game!"); break; default: printf("Input error, please re-enter!"); break; } } while (input); return 0; }