c语言实现三子棋游戏(优化电脑落子)
发布日期:2021-05-07 22:55:41 浏览次数:21 分类:原创文章

本文共 6783 字,大约阅读时间需要 22 分钟。

一、问题

c语言实现三子棋游戏

二、解决思路

实现三子棋首先要有一个棋盘,在C语言里,最好的实现方式就是二维数组了。所以第一步就是创建二维数组并对其进行初始化。接着我们需要一个函数,show函数,实现每一次落子过后棋盘的展示。然后是computer__move函数,实现电脑的落子。最后需要一个判断函数,每一次落子过后都要进行判断游戏是否继续。

三、代码实现

第一步,编写game.h头文件,把需要用到的函数声明及一些宏定义写在里面。

#ifndef __GAME_H__#define __GAME_H__#include <stdio.h>#include <windows.h>#include <time.h>#pragma warning(disable:4996)#define SPACE ' '#define ROW 3#define COL 3#define PERSON 'X'#define COMPUTER 'O'void show(char board[][COL]);int computer_move(char board[][COL]);char judge(char board[][COL]);#endif

第二步,编写main函数,从这里调用函数

#include  "game.h"void menu() //menu函数 指引用户输入指令,然后调用相应函数{   	int flag = 1;	while (flag) {   		    system("cls");		printf("###########################\n");		printf("####欢迎来到三子棋联盟! ##\n");		printf("####1: play              ##\n");		printf("####2: exit              ##\n");		printf("###########################\n");		int n = 0;		scanf("%d", &n);		switch(n){    			case 1:				game(); // 用户输入1,开始游戏,调用game函数				break;			case 2:				flag = 0;				printf("Bye bye!\n");// 用户输入0,输出“Bye bye!”,程序结束				break;			default:				printf("输入有误,请重新输入!\n");				break;		}	}}int main() {   	menu(); //main 函数里面调用menu函数	system("pause");	return 0;}

第三步,编写game.c,把需要用到的函数都写在里面。

show函数:

#include "game.h"void show(char board[][COL]) //show函数,展示棋盘。{   	system("cls");	printf("    1  2   3 \n"); //输出列序号	int i = 1;	int j = 0;	for (; i <= ROW; i++) {   		printf(" ------------\n"); // 输出每一行之间的分割线。		printf("%d  |",i); //输出行序号。		for (j = 0; j < COL; j++) {   			printf("%c |",board[i-1][j]);		}//输出棋盘(二维数组)的内容。		printf("\n");	}	printf(" ------------\n");// 输出最后一行的分割线。}
computer__move函数:int computer_move(char board[][COL]) //computer_move函数,实现电脑落子{   	printf("对手思考中...\n");	Sleep(2000);	srand((unsigned long)time(NULL));	if (board[1][1] == SPACE) {   		board[1][1] = COMPUTER;		return 0;	}// 若最中间还没有被占领,就落子在最中间。	int i = 0;	int j = 0;	int count = 0;	for (; i < ROW; i++) {   		for (j = 0; j < COL; j++) {   			if (board[i][j] == COMPUTER) {   				count++;			} // 循环遍历每一列,若发现有电脑的棋子,便记录下来。			if (count == 2 && \				(board[i][0] == SPACE || board[i][1] == SPACE || board[i][2] == SPACE)) {   				while (1) {   					int y = rand() % 3;					if (board[i][y] == SPACE) {   						board[i][y] = COMPUTER;						return 0;					}				}			} // 若此列有两个棋子,且还有一个“空格”,那就落子在空格位置,三子连珠。		}		count = 0;	}	for (j = 0; j < COL; j++) {   		for (i = 0; i < ROW; i++) {   			if (board[i][j] == COMPUTER) {   				count++;			}// 循环遍历每一行,若发现有电脑的棋子,便记录下来。			if (count == 2 && \				(board[0][j] == SPACE || board[1][j] == SPACE || board[2][j] == SPACE)) {   				while (1) {   					int x = rand() % 3;					if (board[x][j] == SPACE) {   						board[x][j] = COMPUTER;						return 0;					}				}			}// 若此行有两个棋子,且还有一个“空格”,那就落子在空格位置,三子连珠。		}		count = 0;	}	if (board[1][1] == COMPUTER) {    // 如果最中间一个是电脑落子,那么		if (board[0][0] == COMPUTER && board[2][2] != PERSON) 	    {   			board[2][2] = COMPUTER;			return 0;		}		if (board[2][2] == COMPUTER && board[0][0] != PERSON) {   			board[0][0] = COMPUTER;			return 0;		}		if (board[0][2] == COMPUTER && board[2][0] == SPACE) {   			board[2][0] = COMPUTER;			return 0;		}		if (board[2][0] == COMPUTER && board[0][2] == SPACE) {   			board[0][2] = COMPUTER;			return 0;		}		if (board[0][2] == COMPUTER && board[2][0] == SPACE) {   			board[2][0] = COMPUTER;			return 0;		} //以上四种情况是电脑落子在四个边角就能获胜。		if (board[0][2] == SPACE && board[2][0] == SPACE) {   			while (1) {   				int x = rand() % 3;				int y = rand() % 3;				if (board[x][y] == SPACE && x != 1 && y != 1 && x != y) {   					board[x][y] = COMPUTER;					return 0;				}			}		} // 到这一步,电脑已经不可能三子连珠,那就考虑二子连珠,先考虑边角,		  // 从左上角到右下角,如果只有中间位置是电脑落子,那就随机落在左上角或者右下角。		if (board[0][0] == SPACE && board[2][2] == SPACE) {   			while (1) {   				int x = rand() % 3;				int y = rand() % 3;				if (board[x][y] == SPACE && x != 1 && y != 1 && x == y) {   					board[x][y] = COMPUTER;					return 0;				}			}		}// 从右上角到左下角,如果只有中间位置是电脑落子,那就随机落在右上角或者左下角。	}	for (i = 0; i < ROW; i++) {   		for (j = 0; j < COL; j++) {   			if (board[i][j] == COMPUTER) {   				if (board[i][0] != PERSON && board[i][1] != PERSON && board[i][2] != PERSON) {   					while (1) {   						int y = rand() % 3;						if (board[i][y] == SPACE) {   							board[i][y] = COMPUTER;							return 0;						}					}				} //遍历棋盘,若该位置有电脑落子,且该行其他两个位置均是“空格”,就随机落在该行				else if (board[0][j] != PERSON && board[1][j] != PERSON && board[2][j] != PERSON) {   					while (1) {   						int x = rand() % 3;						if (board[x][j] == SPACE) {   							board[x][j] = COMPUTER;							return 0;						}					}				} // 若该列其他两个位置均是“空格”,就随机落在该列			}		}	}	while (1) {   		int x = rand() % 3;		int y = rand() % 3;		if (board[x][y] == SPACE) {   			board[x][y] = COMPUTER;			return 0;		}	}//若以上情况都不满足,就随机落在棋盘上未被占领的位置}

judge函数:

char judge(char board[][COL]) // judge函数,判断游戏结果{   	int i = 0;	int j = 0;	if (board[i][j] != SPACE && \		board[i][j] == board[i + 1][j + 1] && \		board[i + 1][j + 1] == board[i + 2][j + 2]) {   		return 'W';//从左上角到右下角,若三个棋子一样,返回“W”,代表游戏结束	}	if (board[i][j + 2] != SPACE && \		board[i][j + 2] == board[i + 1][j + 1] && \		board[i + 1][j + 1] == board[i + 2][j]) {   		return 'W';;//从右上角到左下角,若三个棋子一样,返回“W”,代表游戏结束	}	for (; i < ROW; i++) {   		if (board[i][i] != SPACE &&\			board[i][j] == board[i][j + 1] && \			board[i][j + 1] == board[i][j + 2]) {   			return 'W';		}	}//遍历每一行,若三个棋子一样,返回“W”,游戏结束	for (i = 0; i < COL; i++) {   		if (board[j][i] != SPACE && \			board[j][i] == board[j + 1][i] && \			board[j + 1][i] == board[j + 2][i])			return 'W';	}//遍历每一列,若三个棋子一样,返回“W”,游戏结束	for (i = 0; i < ROW; i++) {   		for (j = 0; j < COL; j++) {   			if (board[i][j] == SPACE) {   				return 'Y';			}		}	}//遍历棋盘,如果还有“空格”,返回“Y”,游戏继续	return 'F';//棋盘没有空格,代表棋盘已满,返回“F”,游戏结束}

game函数:

void game(){   	char board[ROW][COL];	int i = 0;	int j = 0;	for (; i < ROW; i++) {   		for (j = 0; j < COL; j++) {   			board[i][j] = SPACE;		}	}// 定义一个3行3列的二维数组,初始化赋值为“空格”	char result;	printf("请选择谁先手(非0代表你先手,0代表电脑先手):");	int k = 0;	scanf("%d",&k);	if (!k) {   		computer_move(board); // 调用computer_move函数实现电脑落子。		k = 1;	}//根据用户选择来决定谁先手	show(board); //调用show函数展示棋盘。	while (1) {   		printf("请落子(行 列):");		int x = 0;		int y = 0;		scanf("%d %d", &x, &y);		if (x < 1 || x > 3 || y < 1 || y > 3) {   			printf("无效位置,请重新输入!(共三行三列!)\n");			continue;		} // 棋盘只有三行三列,若超出范围则提示用户重新输入。		if (board[x-1][y-1] != SPACE) {   			printf("同一位置不能重复落子!\n");			continue;		} //若该位置不是“空格”,即该位置已被占领,不能重复落子。		board[x-1][y-1] = PERSON;		show(board);		result = judge(board);//调用judge函数,根据返回结果判断下一步执行哪条语句。		if (result == 'W') {   			printf("恭喜你,你赢了!\n");			Sleep(3000);			break;		}		computer_move(board);		show(board);		result = judge(board); 		if (result == 'W') {   			printf("很遗憾,你输了!\");			Sleep(3000);			break;		}		if (result == 'F') {   			printf("还不错,和棋了!\n");			Sleep(3000);			break;		}	}}

四、运行结果

菜单界面:
在这里插入图片描述
用户落子:
在这里插入图片描述
电脑落子:
在这里插入图片描述
游戏结束:
在这里插入图片描述

上一篇:c语言扫雷游戏,可以递归展开非雷位置,第一次不踩雷
下一篇:c语言位操作符&, | , ^(按位与,按位或,按位异或)

发表评论

最新留言

表示我来过!
[***.240.166.169]2025年04月15日 16时39分24秒