【C语言】三子棋的实现
一、理清逻辑
首先我们先来理一理三子棋实现的逻辑 1.打印游戏菜单 2.创建并初始化二维数组 3.打印棋盘 4.双方下棋 5.判断胜负
二、创建文件
我创建了三个文件,分别为test.c、game.h和game.c test.c文件用于实现进入游戏、退出游戏、判断输赢、打印菜单等逻辑 game.c用于编写游戏的主要实现方法 game.h存放头文件和函数的声明
三、具体步骤
1.创建菜单和实现方法
写在test.c文件中
void menu() { printf("******************************** "); printf("********* 1.play *********** "); printf("********* 0.exit *********** "); printf("******************************** "); } void test() { srand((unsigned int)time(NULL)); int input = 0; do { menu(); printf(":>"); scanf("%d", &input); switch (input) { case 1: printf("三子棋游戏开始 "); game(); break; case 0: printf("结束游戏 "); break; default: printf("输入错误 "); break; } } while (input); }
2.创建并初始化二维数组
在test.c中创建二维数组并引用初始化数组的方法
void game() { //创建二维数组 char board[ROW][COL] = { 0 }; //初始化二维数组 InitBoard(board, ROW, COL); }
在game.h中用宏定义定义行列,声明函数,填写需要的头文件
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> #define ROW 3 #define COL 3
在game.c中定义初始化数组的方法
#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] = ; } } }
3.打印棋盘
在game.c中定义打印棋盘的方法,需要注意的是每打印一行后要进行换行
void DisplayBoard(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(" "); if (i < row - 1) { for (j = 0; j < row; j++) { printf("---"); if (j < col - 1) { printf("|"); } } } printf(" "); } }
在test.c中game方法中引用此函数
4.双方下棋
人机双方轮流下棋,所以应该在test.c中将人机下棋的步骤放入循环
//下棋 while (1) { //玩家下棋 player_move(board, ROW, COL); DisplayBoard(board, ROW, COL); //电脑下棋 computer_move(board, ROW, COL); DisplayBoard(board, ROW, COL); ret = is_win(board, ROW, COL); }
1)玩家下棋
在game.c中定义实现玩家下棋的方法,要考虑到下棋是否在范围内和位置是否重复落子的情况, 因为我们是通过二维数组来实现的,所以我们输入的坐标x,y所对应的数组下标应该是x-1,y-1
void player_move(char board[ROW][COL], int row, int col) { printf("玩家下棋:>"); int x = 0; int y = 0; while (1) { 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("该坐标被占用,请重新输入! "); } else printf("坐标非法,请重新输入! "); } }
2)电脑下棋
在game.c中定义电脑下棋的方法,我用的是比较简单的用rand函数生成随机数来随机建立坐标,当然这个ai算法是可以优化的。
void computer_move(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; printf("电脑下棋:> "); while (1) { x = rand() % ROW; y = rand() % COL; if (board[x][y]== ) { board[x][y] = #; break; } } }
5.判断胜负
三子棋的结果无非就是三种,玩家赢,电脑赢,平局 我们先在game.c中定义一个实现判断结果的方法 任意一行相同或任意一列相同或对角线相同则视为胜利
//玩家赢:* //电脑赢:# //平局:Q //继续:C int is_full(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; } char is_win(char board[ROW][COL], int row, int col) { int i = 0; 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]; } } for (i = 0; i < row; i++) { if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ) { return board[1][i]; } } if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ) { return board[1][1]; } if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ) { return board[1][1]; } if (is_full(board, row, col)==1) { return Q; } //继续 return C; }
在test.c中实现判断胜负的逻辑
char ret = 0; while (1) { //玩家下棋 player_move(board, ROW, COL); DisplayBoard(board, ROW, COL); ret = is_win(board, ROW, COL); if (ret != C) { break; } //电脑下棋 computer_move(board, ROW, COL); DisplayBoard(board, ROW, COL); ret = is_win(board, ROW, COL); if (ret != C) { break; } } //判断胜负 if (ret == *) { printf("玩家赢了! "); } else if (ret == #) { printf("电脑赢了! "); } else { printf("平局 "); } }
四、运行结果
下面就来展示一下我和人工智障的精彩对局吧
嗯,看来我创造出来的ai已经强大到可以击败我了,我真厉害!
五、完整代码展示
game.h
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> #define ROW 3 #define COL 3 void InitBoard(char board[ROW][COL], int row, int col); void DisplayBoard(char board[ROW][COL], int row, int col); void player_move(char board[ROW][COL], int row, int col); void computer_move(char board[ROW][COL], int row, int col); char is_win(char board[ROW][COL], int row, int col);
test.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" void menu() { printf("******************************** "); printf("********* 1.play *********** "); printf("********* 0.exit *********** "); printf("******************************** "); } void game() { //创建二维数组 char board[ROW][COL] = { 0 }; //初始化二维数组 InitBoard(board, ROW, COL); //打印棋盘 DisplayBoard(board, ROW, COL); //下棋 char ret = 0; while (1) { //玩家下棋 player_move(board, ROW, COL); DisplayBoard(board, ROW, COL); ret = is_win(board, ROW, COL); if (ret != C) { break; } //电脑下棋 computer_move(board, ROW, COL); DisplayBoard(board, ROW, COL); ret = is_win(board, ROW, COL); if (ret != C) { break; } } //判断胜负 if (ret == *) { printf("玩家赢了! "); } else if (ret == #) { printf("电脑赢了! "); } else { printf("平局 "); } } void test() { srand((unsigned int)time(NULL)); int input = 0; do { menu(); printf(":>"); scanf("%d", &input); switch (input) { case 1: printf("三子棋游戏开始 "); game(); break; case 0: printf("结束游戏 "); break; default: printf("输入错误 "); break; } } while (input); } int main() { test(); return 0; }
game.c
#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 DisplayBoard(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(" "); if (i < row - 1) { for (j = 0; j < row; j++) { printf("---"); if (j < col - 1) { printf("|"); } } } printf(" "); } } void player_move(char board[ROW][COL], int row, int col) { printf("玩家下棋:>"); int x = 0; int y = 0; while (1) { 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("该坐标被占用,请重新输入! "); } else printf("坐标非法,请重新输入! "); } } void computer_move(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; printf("电脑下棋:> "); while (1) { x = rand() % ROW; y = rand() % COL; if (board[x][y]== ) { board[x][y] = #; break; } } } int is_full(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; } char is_win(char board[ROW][COL], int row, int col) { int i = 0; 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]; } } for (i = 0; i < row; i++) { if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ) { return board[1][i]; } } if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ) { return board[1][1]; } if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ) { return board[1][1]; } if (is_full(board, row, col)==1) { return Q; } //继续 return C; }
当然,随着所学的知识不断增加,这个游戏可以不断的被优化。
上一篇:
多线程四大经典案例
下一篇:
2022年软件设计师考试知识点:软件设计