1、使用二维数组和循环
最常见的实现方法,使用一个二维数组表示棋盘,使用循环和条件判断来控制游戏逻辑。
#include <stdio.h>
#define SIZE 3
void displayBoard(char board[SIZE][SIZE]) {
printf("\n");
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
printf(" %c ", board[i][j]);
if (j < SIZE - 1) printf("|");
}
if (i < SIZE - 1) printf("\n---|---|---\n");
}
printf("\n");
}
int checkWin(char board[SIZE][SIZE]) {
for (int i = 0; i < SIZE; i++) {
// 行检查
if (board[i][0] == board[i][1] && board[i][1] == board[i][2]) {
return (board[i][0] == 'X') ? 1 : (board[i][0] == 'O') ? 2 : 0;
}
// 列检查
if (board[0][i] == board[1][i] && board[1][i] == board[2][i]) {
return (board[0][i] == 'X') ? 1 : (board[0][i] == 'O') ? 2 : 0;
}
}
// 对角线检查
if (board[0][0] == board[1][1] && board[1][1] == board[2][2]) {
return (board[0][0] == 'X') ? 1 : (board[0][0] == 'O') ? 2 : 0;
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0]) {
return (board[0][2] == 'X') ? 1 : (board[0][2] == 'O') ? 2 : 0;
}
return 0;
}
int main() {
char board[SIZE][SIZE] = {{'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}};
int player = 1, choice, row, col, result = 0;
char mark;
while (result == 0) {
displayBoard(board);
player = (player % 2) ? 1 : 2;
mark = (player == 1) ? 'X' : 'O';
printf("Player %d, enter the number where you want to place %c: ", player, mark);
scanf("%d", &choice);
row = (choice - 1) / SIZE;
col = (choice - 1) % SIZE;
if (choice >= 1 && choice <= 9 && board[row][col] != 'X' && board[row][col] != 'O') {
board[row][col] = mark;
} else {
printf("Invalid move, try again.\n");
player--;
}
result = checkWin(board);
player++;
}
displayBoard(board);
if (result == 1) {
printf("Player 1 wins!\n");
} else if (result == 2) {
printf("Player 2 wins!\n");
} else {
printf("It's a draw!\n");
}
return 0;
}
2、使用递归
使用递归来处理游戏循环,通过递归函数进行多次调用直到游戏结束。
#include <stdio.h>
#define SIZE 3
void displayBoard(char board[SIZE][SIZE]) {
printf("\n");
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
printf(" %c ", board[i][j]);
if (j < SIZE - 1) printf("|");
}
if (i < SIZE - 1) printf("\n---|---|---\n");
}
printf("\n");
}
int checkWin(char board[SIZE][SIZE]) {
for (int i = 0; i < SIZE; i++) {
if (board[i][0] == board[i][1] && board[i][1] == board[i][2]) {
return (board[i][0] == 'X') ? 1 : (board[i][0] == 'O') ? 2 : 0;
}
if (board[0][i] == board[1][i] && board[1][i] == board[2][i]) {
return (board[0][i] == 'X') ? 1 : (board[0][i] == 'O') ? 2 : 0;
}
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2]) {
return (board[0][0] == 'X') ? 1 : (board[0][0] == 'O') ? 2 : 0;
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0]) {
return (board[0][2] == 'X') ? 1 : (board[0][2] == 'O') ? 2 : 0;
}
return 0;
}
void playGame(char board[SIZE][SIZE], int player) {
int choice, row, col, result = checkWin(board);
char mark = (player == 1) ? 'X' : 'O';
if (result != 0) {
displayBoard(board);
if (result == 1) {
printf("Player 1 wins!\n");
} else if (result == 2) {
printf("Player 2 wins!\n");
} else {
printf("It's a draw!\n");
}
return;
}
displayBoard(board);
printf("Player %d, enter the number where you want to place %c: ", player, mark);
scanf("%d", &choice);
row = (choice - 1) / SIZE;
col = (choice - 1) % SIZE;
if (choice >= 1 && choice <= 9 && board[row][col] != 'X' && board[row][col] != 'O') {
board[row][col] = mark;
} else {
printf("Invalid move, try again.\n");
playGame(board, player);
return;
}
playGame(board, (player % 2) + 1);
}
int main() {
char board[SIZE][SIZE] = {{'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}};
printf("Welcome to Tic Tac Toe!\n");
playGame(board, 1);
return 0;
}
3、使用位运算和状态存储
通过位运算来跟踪玩家的获胜条件,利用较少的空间处理状态。
#include <stdio.h>
#define SIZE 3
#define FULL_BOARD (1 << (SIZE * SIZE)) - 1
int board = 0, player1 = 0, player2 = 0;
void displayBoard(int p1, int p2) {
printf("\n");
for (int i = 0; i < SIZE * SIZE; i++) {
if (p1 & (1 << i)) {
printf(" X ");
} else if (p2 & (1 << i)) {
printf(" O ");
} else {
printf(" %d ", i + 1);
}
if ((i + 1) % SIZE == 0 && i != SIZE * SIZE - 1) {
printf("\n---|---|---\n");
} else if ((i + 1) % SIZE != 0) {
printf("|");
}
}
printf("\n");
}
int checkWin(int player) {
int wins[] = {
0b111000000, // Row 1
0b000111000, // Row 2
0b000000111, // Row 3
0b100100100, // Col 1
0b010010010, // Col 2
0b001001001, // Col 3
0b100010001, // Diagonal 1
0b001010100 // Diagonal 2
};
for (int i = 0; i < 8; i++) {
if ((player & wins[i]) == wins[i]) {
return 1;
}
}
return 0;
}
int main() {
int currentPlayer = 1, choice;
printf("Welcome to Tic Tac Toe!\n");
while (board != FULL_BOARD) {
displayBoard(player1, player2);
printf("Player %d, enter your move (1-9): ", currentPlayer);
scanf("%d", &choice);
if (choice < 1 || choice > 9 || (board & (1 << (choice - 1)))) {
printf("Invalid move, try again.\n");
continue;
}
board |= (1 << (choice - 1));
if (currentPlayer == 1) {
player1 |= (1 << (choice - 1));
if (checkWin(player1)) {
displayBoard(player1, player2);
printf("Player 1 wins!\n");
return 0;
}
} else {
player2 |= (1 << (choice - 1));
if (checkWin(player2)) {
displayBoard(player1, player2);
printf("Player 2 wins!\n");
return 0;
}
}
currentPlayer = 3 - currentPlayer; // Alternate between player 1 and 2
}
printf("It's a draw!\n");
return 0;
}