
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; } }}
四、运行结果
菜单界面:
用户落子:
电脑落子:
游戏结束:
发表评论
最新留言
表示我来过!
[***.240.166.169]2025年04月15日 16时39分24秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
java 多态类型转换
2019-03-04
常用正则表达式
2019-03-04
XML:采用XHTML和CSS设计可重用可换肤的WEB站点
2019-03-04
Java判断字符串是否为金额
2019-03-04
angr学习笔记(7)(malloc地址单元符号化)
2019-03-04
结构型设计在工作中的一些经验总结
2019-03-04
如何提升员工体验 助力企业业务增长?这个棘手的问题终于被解决了!
2019-03-04
2020 AI 产业图谱启动,勾勒中国 AI 技术与行业生态
2019-03-04
Netty4服务端入门代码示例
2019-03-04
Spring源码:prepareBeanFactory(beanFactory);方法
2019-03-04
AcWing 828. 模拟栈
2019-03-04
(20200328已解决)从docker容器内复制文件到宿主机
2019-03-04
理解Docker ulimit参数
2019-03-04
OpenAI Gym简介及初级实例
2019-03-04
int 转 CString
2019-03-04
Edit编辑框自动换行与长度
2019-03-04
Java面向对象
2019-03-04
JAVA带标签的break和continue
2019-03-04
Java获取线程基本信息的方法
2019-03-04
vue源码分析(MVVM篇)
2019-03-04