/*******************************************************************************************
* *
* ~五子棋小游戏~ *
* 作者:杨帅 学号:1000012850 *
* Created on: 2010-11-29 *
* 设计思路:我最先想到的模型就是我原来手机里的五子棋游戏。那个游戏有界面,能悔棋 *
* ,但只能悔一步棋。界面分为很多选项,如开始、继续、退出等等。于是我就以我的手机 *
* 五子棋为模板模仿那种形式编程。我最先编的就是开机动画和菜单部分。开机动画我觉得 *
* 应该是比较有特色的部分,因为个人比较注重感官,于是就加了个动画和菜单。动画是用 *
* 每一帧的输出画面以及用大整数计算来推延时间达到正常的视觉暂留产生动画的效果。菜 *
* 单的转化耗了一点脑筋,要解决能够不停选择转化菜单的功能的问题,最后想到用循环和 *
* 条件语句来实现。将程序的主函数就写成一个大循环,然后用若干变量来记录每一个层次 *
* 的菜单的选项,然后根据这些变量用条件语句来实现了菜单的转化。 *
* 我觉得另一个特色就是我的失败胜利画面。我从搜狗输入法里找到很多有趣的字符画,把 *
* 它们作为失败胜利的画面,生动而有趣。然后,在一些提示语和介绍方面,我也使用一些 *
* 比较不死板的语言,这样能增加游戏的趣味性。 *
* 在编完五子棋程序后,原来我用的游戏界面是黄老师发给我们的幻灯片上的圈圈叉叉点点 *
* 但是,我觉得不好看,所以我在输出棋盘的函数里加了一段将圈圈叉叉点点 转化为黑棋白 *
* 棋和棋盘的代码,使得最后的感官变得更好。所以我的程序代码里基本上全部都是圈圈叉 *
* 叉点点,但是最后运行时,看到的是黑棋白棋棋盘。也相当于是升级了吧 *
* 最后就是游戏部分的编程。游戏部分的人人对战部分,思路就是通过设定一个变量来记录 *
* 轮到哪一方下了,然后用条件语句进行选择。每次就是循环提示下子,当输入正确时,结 *
* 束循环,并且改变棋盘状态,扫描棋盘,查找是否胜出,没有的话继续循环,有的话输出 *
* 胜利画面,并且结束循环,进入主菜单。 *
* 人机对战部分与人人部分差不多,只不过在每次用户下完的扫面棋盘查看是否胜出后,通 *
* 过智能部分电脑下子,然后再次扫描棋盘判断电脑是否获胜。然后就与人人又一样了。 *
* 智能部分,我是通过对每一个点点的格子进行四周的扫描得出分数,最后在最高分数处下 *
* 子来完成的。每个格子的分数由向八个方向扫描及夹在中间的扫描的分数组成。对我方越 *
* 有利或对对方越有害分数就越高。 *
* 以上就是我的基本设计思路了 *
* 比较独特的地方:开机画面、菜单设计、胜利失败画面设计。。。。 *
* *
*******************************************************************************************
*/
#include<iostream>
#include<stdlib.h>
#include<string>
#include<iomanip>
#include<cmath>
#include<fstream>
using namespace std;
int blackOrWhite=1; //整型变量blackOrWhite用于记录人人对战中轮到的棋手 1代表黑棋棋手 0代表白棋棋手
bool ifwin=0, ifwin2=0; //逻辑变量 ifwin和ifwin2用来分别记录人人对战和人机对战中是否达到退出条件 达到时值为1 否则为0
string player1="黑棋棋手", player2="白棋棋手", player3="黑棋棋手"; //player1 player2和player3分别记录人人对战双方的昵称和人机对战中的昵称
void welcome(void) //声明welcome函数 用于绘制开机动画 此动画是将画面输出 短暂暂停后 清屏输出下一个画面 达到显示动画的作用
{
int i; //声明整型变量i 用于在这个函数welcome中使用 主要功能是对清屏进行时间延迟
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl; //动画的第一帧
for(i=0;i<25000000;)
{
i++;
} //让计算机不停做较大的自加 来达到延时的作用
system("cls"); //清屏
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl; //第二帧
for(i=0;i<25000000;)
{
i++;
}
system("cls");
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" ng. . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl; //第三帧
for(i=0;i<25000000;)
{
i++;
}
system("cls");
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" bang. . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl; //第四帧
for(i=0;i<25000000;)
{
i++;
}
system("cls");
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" Gobang. . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl; //第五帧
for(i=0;i<25000000;)
{
i++;
}
system("cls");
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" e Gobang. . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl; //第六帧
for(i=0;i<25000000;)
{
i++;
}
system("cls");
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" ure Gobang. . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl; //第七帧
for(i=0;i<25000000;)
{
i++;
}
system("cls");
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" isure Gobang. . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl; //第八帧
for(i=0;i<25000000;)
{
i++;
}
system("cls");
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" Leisure Gobang. . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl; //第九帧
for(i=0;i<25000000;)
{
i++;
}
system("cls");
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . Leisure Gobang. . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl; //第十帧
for(i=0;i<25000000;)
{
i++;
}
system("cls");
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . Leisure Gobang. . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl; //第十一帧
for(i=0;i<25000000;)
{
i++;
}
system("cls");
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . Leisure Gobang. . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl; //第十二帧
for(i=0;i<25000000;)
{
i++;
}
system("cls");
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . Leisure Gobang. . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl; //第十三帧
for(i=0;i<25000000;)
{
i++;
}
system("cls");
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . Leisure Gobang. . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . .[Press Enter to start] . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl; //第十四帧 输出操作提示 按回车结束开机画面 进入主菜单目录
for(;;)
{
if(cin.peek()=='\n')
{
system("cls");
break; //当指针扫描到回车 就清屏 跳出循环
}
char k;
cin>>k;
if(k=='\n') break; //如果用户没有按规则输入 则不停循环 直到出现回车时跳出
} //for循环 用于进行暂停 直到按回车时 才break结束此函数welcome
}
void coutboard(int blackOrWhite,char a[15][15]) //声明coutboard函数 用于画出棋盘
{
int i,j; //声明整型变量 用于在此函数coutboard中 表示不停变化的纵坐标、横坐标
string c[15][15]; //声明字符串数组c[15][15]用来记录棋盘符号
cout<<" 0 1 2 3 4 5 6 7 8 9101112131415"<<endl; //首先输出棋盘的横坐标
for(i=1;i<14;i++)
for(j=1;j<14;j++)
{
c[i][j]="┼";
}
for(i=1;i<14;i++)
{
c[i][0]="├";
c[i][14]="┤";
c[0][i]="┬";
c[14][i]="┴";
}
c[0][0]="┌";
c[14][14]="┘";
c[0][14]="┐";
c[14][0]="└"; //c[15][15]用制表符画出棋盘
for(i=0;i<15;i++)
{
cout<<setw(2)<<i+1; //从第二行起 最先输出两位右对齐的纵坐标
for(j=0;j<15;j++)
{
if(a[i][j]=='X') cout<<"○"; //如果该格下了黑棋 则输出"○"
else if(a[i][j]=='O') cout<<"●"; //如果该格下了白棋 则输出"●"
else cout<<c[i][j]; //如果该格没有下子 就输出和c[i][j]
}
cout<<endl; //每一行到最后换行
}
}
int catalogue(void) //声明函数catalogue 用于输出主菜单目录 然后返回用户的选择
{
string k; //声明字符串变量k 用于接收用户的选择 之所以不用其他类型 是防止用户输入错误信息而导致无法识别
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . CATALOGUE . . . . . ."<<endl;
cout<<" . . . . ------------- . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . .1. Man Vs Man. . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . .2. Man Vs PC . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . .3. Introduction .. . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . .4. Key . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . .5. Exit. . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl; //主菜单给出5种选择 分别是 人人对战模式 人机对战模式 游戏介绍 游戏小贴士 及退出选项
cout<<"请输入你想选择的选项前的数字:"<<endl; //提示用户输入选择
for(;;)
{
cin>>k; //输入k
if(k=="1")
{
system("cls");
return 1; //当且仅当输入的k是“1” 时清屏并返回数值1 此数值会用于在主函数中进行判断
}
else if(k=="2")
{
system("cls");
return 2; //当且仅当输入的k是“2” 时清屏并返回数值2
}
else if(k=="3")
{
system("cls");
return 3; //当且仅当输入的k是“3” 时清屏并返回数值3
}
else if(k=="4")
{
system("cls");
return 4; //当且仅当输入的k是“4” 时清屏并返回数值4
}
else if(k=="5")
{
system("cls");
return 5; //当且仅当输入的k是“5” 时清屏并返回数值5
}
else cout<<"输入无效 想玩的话就按照规则输入吧~~~" <<endl; //如果用户输入的不是有效数字 那么提示错误 并继续循环
} //for循环 用于在用户输出正确指令前不停循环 防止用户错误输入
}
int manVsMan(void) //声明函数manVsMan 用于输出人人对战模式的菜单画面 然后返回用户的选择 在主菜单中选择1时弹出
{
string k; //这里的k和主菜单(catalogue)中的k的作用相同
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . (一) Man Vs Man . . . . ."<<endl;
cout<<" . . . . ------------- . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . 1. Continnue. . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . 2. Restart. . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl; //人人模式菜单 提供两种选择 一是继续上次的比赛 二是重新开始
cout<<"请输入你想选择的选项前的数字(如果读档失败 则自动跳为重新开始):"<<endl;
for(;;)
{
cin>>k;
if(k=="1")
{
system("cls");
return 1;
}
else if(k=="2")
{
system("cls");
return 2;
}
else cout<<"输入无效 想玩的话就按照规则输入吧~~~" <<endl; //和主函数(catalogue)中的返回方法一样
}
}
int manVsPC(void) //声明函数manVsPC 用于输出人机对战模式的菜单画面 并返回用户的选择 在主菜单中选择2时弹出
{
string k;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . (二) Man Vs PC. . . . ."<<endl;
cout<<" . . . . ------------- . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . 1. Continnue. . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . 2. Restart. . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl; //人机对战菜单 提供两种选择 一是继续上次的比赛 二是重新开始
cout<<"请输入你想选择的选项前的数字(如果读档失败 则自动跳为重新开始):"<<endl;
for(;;)
{
cin>>k;
if(k=="1")
{
system("cls");
return 1;
}
else if(k=="2")
{
system("cls");
return 2;
}
else cout<<"输入无效 想玩的话就按照规则输入吧~~~" <<endl;
}
}
int manVsPC2(void) //声明函数manVsPC2 这是人际对战模式主菜单下的子菜单 在选择了重新开始后弹出 用于输出菜单画面 并返回用户的选择
{
string k;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . (二) Man Vs PC. . . . ."<<endl;
cout<<" . . . . ------------- . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . 1. on the offensive(先手) . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . 2. defensive position(后手). ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl; //重新开始人机对战模式的菜单提供两个选择 一是用户为先手 二是用户为后手
cout<<"请输入你想选择的选项前的数字:"<<endl;
for(;;)
{
cin>>k;
if(k=="1")
{
system("cls");
return 1;
}
else if(k=="2")
{
system("cls");
return 2;
}
else cout<<"输入无效 想玩的话就按照规则输入吧~~~" <<endl;
}
}
void introduction(void) //声明函数introduction 用于介绍游戏 在主菜单中选择3时弹出
{
string k;
cout<<" . . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . (三) Introduction . . . . ."<<endl;
cout<<" . . . . ------------- . . . . . ."<<endl;
cout<<" .好吧,我英语不好,这一段用中文 ."<<endl;
cout<<" .五子棋嘛,顾名思义,就是在棋盘 ."<<endl;
cout<<" .上双方依次下子,当一方有五个棋 ."<<endl;
cout<<" .子连续连成横排竖排或斜边 ,就获."<<endl;
cout<<" .胜了~~~~~~ . . . . . . . . . . ."<<endl;
cout<<" .OK 大家应该都懂了吧~~~~~~. . . ."<<endl;
cout<<" .哎呀,还空了这么多位子啊 . . . ."<<endl;
cout<<" .那继续写吧………… . . . . . . ."<<endl;
cout<<" .写啥呢?意识流?表现主义? . . ."<<endl;
cout<<" .荒诞派?魔幻现实主义? . . . . ."<<endl;
cout<<" .哎呀,你还在看啊 ?!. . . . . ."<<endl;
cout<<" .还不快点玩游戏!!! . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . . ."<<endl; //以上是程序员的废话 +_+
cout<<"Press Any Key And Enter To Return To The Catalogue: "<<endl; //提示按任意键和回车回到主菜单
for(;;)
{
char k;
cin>>k;
if(cin.peek()=='\n')
{
system("cls");
break; //如果正确输入任意键及回车 则清屏 并且退出循环
}
} //for循环 用于防止用户错误输入
}
void key(void) //声明函数key 用于输出小贴士目录 在菜单中选择4弹出
{
string k;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . .(四) Key . . . . . ."<<endl;
cout<<" . . . . ------------- . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" .[Please Input The Password]. ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . ."<<endl;
cout<<" . . . . . . . . . . . . . . . ."<<endl;
cout<<"提示:密码是游戏作者的英文名字(全小写) "<<endl; //提示用户输入密码 :-D
for(;;)
{
cin>>k;
if(k=="william")
{
cout<<"提示:在输入坐标时,如果输入 take back 可以悔一步棋 不要贪心哦 只能悔一步哦~~"<<endl;
cout<<"注意:选择continue时的第一步是不允许悔棋的~~~~~~~"<<endl;
}
else cout<<"Warning:密码错误~~~~~~~~"<<endl; //如果输入正确密码 就输出提示 悔棋的方法 否则 输出密码错误
for(int i=0;i<500000000;)
{
i++;
}
break; //用i自加使用暂停功能 然后break跳出循环
}
cout<<"Press Any Key And Enter To Return To The Catalogue: "<<endl; //提示退出此菜单 返回主菜单
for(;;)
{
char k;
cin>>k;
if(cin.peek()=='\n')
{
system("cls");
break;
}
}
}
int upOperation(char a[15][15], int i, int j) //声明函数upOperation 用于计算当前格在排除向下扫描的影响后 向上扫描的各种情况的分数
{
if(i-1<0) return 0; //如果此格在第一列 说明向上扫描无意义 返回分数0
if(i+1<15&&(a[i-1][j]==a[i+1][j])) return 0;//如果此格不是最后一格 而它的上下两格相同 则说明 它或者被对方夹住了 这时扫描无意义 返回分数0
//或者上下都是自己的 或者上下没有棋子 这时是下面的函数otherOperation的事情了返回分数还是0
if(a[i-1][j]=='.') return 0; //如果向上扫描的第一个是. 说明暂无危险或者是下面的函数otherOperation的事情 返回分数1
if(i-2>=0) //如果向上能推2行
{
if(a[i-1][j]=='X'&&a[i-2][j]=='O'&&i<12) return 0; //如果是对方下了子 而且又已被堵 而且尚有可能连成5个 则只考虑上方下此格毫无意义 返回 分数0
if(a[i-1][j]=='X'&&a[i-2][j]=='.'&&i<12) return 10;//如果是对方下了子 而且没有被堵住 而且尚有可能连成5个 则产生了威胁 返回分数10
if(a[i-1][j]=='O'&&a[i-2][j]=='X'&&i<12) return 1; //如果是自己下了子 而且又已被堵 而且尚有可能连成5个 则只考虑上方此格近乎没有意义 返回分数1
if(a[i-1][j]=='O'&&a[i-2][j]=='.'&&i<12) return 100;//如果是自己下了子而且又没有被堵 而且尚有可能连成5个 则是进攻的机会 返回分数100
if(i-3>=0) //如果向上能推3行
{
if(a[i-1][j]=='X'&&a[i-2][j]=='X'&&a[i-3][j]=='O'&&i<13) return 11; //如果是对方下了两子 而被自己堵住 而且尚有可能连成5个 则没太大意义 返回分数11
if(a[i-1][j]=='X'&&a[i-2][j]=='X'&&a[i-3][j]=='.'&&i<13) return 1000;//如果是对方下了两子没有被堵 具有较大威胁 会形成3个 而且尚有可能连成5个 返回分数1000
if(a[i-1][j]=='O'&&a[i-2][j]=='O'&&a[i-3][j]=='X'&&i<13) return 101;//如果是自己下了两子 而被堵住 则没太大意义 而且尚有可能连成5个 返回分数101
if(a[i-1][j]=='O'&&a[i-2][j]=='O'&&a[i-3][j]=='.'&&i<13) return 10000;//如果是自己下了两子 而没有被堵 则是凑3的好机会 而且尚有可能连成5个 返回分数10000
if(i-4>=0) //如果向上能推4格
{
if(a[i-1][j]=='X'&&a[i-2][j]=='X'&&a[i-3][j]=='X'&&a[i-4][j]=='O'&&i<14) return 1001; //如果是对方下了3个子 而被堵住 有可能会使用凑4来费自己的棋 而且尚有可能连成5个 返回分数1001
if(a[i-1][j]=='X'&&a[i-2][j]=='X'&&a[i-3][j]=='X'&&a[i-4][j]=='.'&&i<14) return 100000;//如果对方下了3个旗子 而没有被堵住 则为了防止其凑4而稳赢 而且尚有可能连成5个 返回分数100000
if(a[i-1][j]=='O'&&a[i-2][j]=='O'&&a[i-3][j]=='O'&&a[i-4][j]=='X'&&i<14&&a[i+1][j]!='X') return 10001; //如果是自己下了3个子 而被堵住 可以凑4个来浪费对手的子 而且尚有可能连成5个 返回分数10001
if(a[i-1][j]=='O'&&a[i-2][j]=='O'&&a[i-3][j]=='O'&&a[i-4][j]=='X'&&i<14&&a[i+1][j]=='X') return 0; //如果是自己下了3个子 而两边被堵住 则无法连成5个 返回分数0
if(a[i-1][j]=='O'&&a[i-2][j]=='O'&&a[i-3][j]=='O'&&a[i-4][j]=='.'&&i<14&&a[i+1][j]!='X') return 100001;//如果是自己下了3个子 而没有被堵住 而下方是空的 则只要凑4 除非对手已经有4个 否则必赢 而且尚有可能连成5个 返回分数100001
if(a[i-1][j]=='O'&&a[i-2][j]=='O'&&a[i-3][j]=='O'&&a[i-4][j]=='.'&&i<14&&a[i+1][j]=='X') return 10001; //如果是自己下了3个子 而没有被堵住 但下方是对手的子 则下这相当于下了4个有一边被堵的子 而且尚有可能连成5个 返回分数10001
if(a[i-1][j]=='X'&&a[i-2][j]=='X'&&a[i-3][j]=='X'&&a[i-4][j]=='X') return 1000000; //如果对方已经下了4个 则无论如何 除非自己已经有4个 否则都要堵住 返回分数1000000
if(a[i-1][j]=='O'&&a[i-2][j]=='O'&&a[i-3][j]=='O'&&a[i-4][j]=='O') return 10000000;//如果自己已经下了4个 那就是赢了 返回分数10000000
}
}
}
return 0; //如果还有其他疑难情况 暂不予考虑 返回分数0
}
int downOperation(char a[15][15], int i, int j) //声明函数downOperation 用于计算当前格在排除向上扫描的影响后 向下扫描的各种情况的分数
{
if(i+1>14) return 0;
if(i-1>=0&&(a[i-1][j]==a[i+1][j])) return 0;
if(a[i+1][j]=='.') return 0;
if(i+2<15)
{
if(a[i+1][j]=='X'&&a[i+2][j]=='O'&&i>2) return 0;
if(a[i+1][j]=='X'&&a[i+2][j]=='.'&&i>2) return 10;
if(a[i+1][j]=='O'&&a[i+2][j]=='X'&&i>2) return 1;
if(a[i+1][j]=='O'&&a[i+2][j]=='.'&&i>2) return 100;
if(i+3<15)
{
if(a[i+1][j]=='X'&&a[i+2][j]=='X'&&a[i+3][j]=='O'&&i>1) return 11;
if(a[i+1][j]=='X'&&a[i+2][j]=='X'&&a[i+3][j]=='.'&&i>1) return 1000;
if(a[i+1][j]=='O'&&a[i+2][j]=='O'&&a[i+3][j]=='X'&&i>1) return 101;
if(a[i+1][j]=='O'&&a[i+2][j]=='O'&&a[i+3][j]=='.'&&i>1) return 10000;
if(i+4<15)
{
if(a[i+1][j]=='X'&&a[i+2][j]=='X'&&a[i+3][j]=='X'&&a[i+4][j]=='O'&&i>0) return 1001;
if(a[i+1][j]=='X'&&a[i+2][j]=='X'&&a[i+3][j]=='X'&&a[i+4][j]=='.'&&i>0) return 100000;
if(a[i+1][j]=='O'&&a[i+2][j]=='O'&&a[i+3][j]=='O'&&a[i+4][j]=='X'&&i>0&&a[i-1][j]!='X') return 10001;
if(a[i+1][j]=='O'&&a[i+2][j]=='O'&&a[i+3][j]=='O'&&a[i+4][j]=='X'&&i>0&&a[i-1][j]=='X') return 0;
if(a[i+1][j]=='O'&&a[i+2][j]=='O'&&a[i+3][j]=='O'&&a[i+4][j]=='.'&&i>0&&a[i-1][j]!='X') return 100001;
if(a[i+1][j]=='O'&&a[i+2][j]=='O'&&a[i+3][j]=='O'&&a[i+4][j]=='.'&&i>0&&a[i-1][j]=='X') return 10001;
if(a[i+1][j]=='X'&&a[i+2][j]=='X'&&a[i+3][j]=='X'&&a[i+4][j]=='X') return 1000000;
if(a[i+1][j]=='O'&&a[i+2][j]=='O'&&a[i+3][j]=='O'&&a[i+4][j]=='O') return 10000000;
}
}
}
return 0; //这里的分数计算思路与upOperation是一样的
}
int leftOperation(char a[15][15], int i, int j)//声明函数leftOperation 用于计算当前格在排除向右扫描的影响后 向左扫描的各种情况的分数
{
if(j-1<0) return 0;
if(j+1<15&&(a[i][j+1]==a[i][j-1])) return 0;
if(a[i][j-1]=='.') return 0;
if(j-2>=0)
{
if(a[i][j-1]=='X'&&a[i][j-2]=='O'&&j<12) return 0;
if(a[i][j-1]=='X'&&a[i][j-2]=='.'&&j<12) return 10;
if(a[i][j-1]=='O'&&a[i][j-2]=='X'&&j<12) return 1;
if(a[i][j-1]=='O'&&a[i][j-2]=='.'&&j<12) return 100;
if(j-3>=0)
{
if(a[i][j-1]=='X'&&a[i][j-2]=='X'&&a[i][j-3]=='O'&&j<13) return 11;
if(a[i][j-1]=='X'&&a[i][j-2]=='X'&&a[i][j-3]=='.'&&j<13) return 1000;
if(a[i][j-1]=='O'&&a[i][j-2]=='O'&&a[i][j-3]=='X'&&j<13) return 101;
if(a[i][j-1]=='O'&&a[i][j-2]=='O'&&a[i][j-3]=='.'&&j<13) return 10000;
if(j-4>=0)
{
if(a[i][j-1]=='X'&&a[i][j-2]=='X'&&a[i][j-3]=='X'&&a[i][j-4]=='O'&&j<14) return 1001;
if(a[i][j-1]=='X'&&a[i][j-2]=='X'&&a[i][j-3]=='X'&&a[i][j-4]=='.'&&j<14) return 100000;
if(a[i][j-1]=='O'&&a[i][j-2]=='O'&&a[i][j-3]=='O'&&a[i][j-4]=='X'&&j<14&&a[i][j+1]!='X') return 10001;
if(a[i][j-1]=='O'&&a[i][j-2]=='O'&&a[i][j-3]=='O'&&a[i][j-4]=='X'&&j<14&&a[i][j+1]=='X') return 0;
if(a[i][j-1]=='O'&&a[i][j-2]=='O'&&a[i][j-3]=='O'&&a[i][j-4]=='.'&&j<14&&a[i][j+1]!='X') return 100001;
if(a[i][j-1]=='O'&&a[i][j-2]=='O'&&a[i][j-3]=='O'&&a[i][j-4]=='.'&&j<14&&a[i][j+1]=='X') return 10001;
if(a[i][j-1]=='X'&&a[i][j-2]=='X'&&a[i][j-3]=='X'&&a[i][j-4]=='X') return 1000000;
if(a[i][j-1]=='O'&&a[i][j-2]=='O'&&a[i][j-3]=='O'&&a[i][j-4]=='O') return 10000000;
}
}
}
return 0; //这里的分数计算思路与upOperation是一样的
}
int rightOperation(char a[15][15], int i, int j)//声明函数rightOperation 用于计算当前格在排除向左扫描的影响后 向右扫描的各种情况的分数
{
if(j+1>14) return 0;
if(j-1>=0&&(a[i][j-1]==a[i][j+1])) return 0;
if(a[i][j+1]=='.') return 0;
if(j+2<15)
{
if(a[i][j+1]=='X'&&a[i][j+2]=='O'&&j>2) return 0;
if(a[i][j+1]=='X'&&a[i][j+2]=='.'&&j>2) return 10;
if(a[i][j+1]=='O'&&a[i][j+2]=='X'&&j>2) return 1;
if(a[i][j+1]=='O'&&a[i][j+2]=='.'&&j>2) return 100;
if(j+3<15)
{
if(a[i][j+1]=='X'&&a[i][j+2]=='X'&&a[i][j+3]=='O'&&j>1) return 11;
if(a[i][j+1]=='X'&&a[i][j+2]=='X'&&a[i][j+3]=='.'&&j>1) return 1000;
if(a[i][j+1]=='O'&&a[i][j+2]=='O'&&a[i][j+3]=='X'&&j>1) return 101;
if(a[i][j+1]=='O'&&a[i][j+2]=='O'&&a[i][j+3]=='.'&&j>1) return 10000;
if(j+4<15)
{
if(a[i][j+1]=='X'&&a[i][j+2]=='X'&&a[i][j+3]=='X'&&a[i][j+4]=='O'&&j>0) return 1001;
if(a[i][j+1]=='X'&&a[i][j+2]=='X'&&a[i][j+3]=='X'&&a[i][j+4]=='.'&&j>0) return 100000;
if(a[i][j+1]=='O'&&a[i][j+2]=='O'&&a[i][j+3]=='O'&&a[i][j+4]=='X'&&j>0&&a[i][j-1]!='X') return 10001;
if(a[i][j+1]=='O'&&a[i][j+2]=='O'&&a[i][j+3]=='O'&&a[i][j+4]=='X'&&j>0&&a[i][j-1]=='X') return 0;
if(a[i][j+1]=='O'&&a[i][j+2]=='O'&&a[i][j+3]=='O'&&a[i][j+4]=='.'&&j>0&&a[i][j-1]!='X') return 100001;
if(a[i][j+1]=='O'&&a[i][j+2]=='O'&&a[i][j+3]=='O'&&a[i][j+4]=='.'&&j>0&&a[i][j-1]=='X') return 10001;
if(a[i][j+1]=='X'&&a[i][j+2]=='X'&&a[i][j+3]=='X'&&a[i][j+4]=='X') return 1000000;
if(a[i][j+1]=='O'&&a[i][j+2]=='O'&&a[i][j+3]=='O'&&a[i][j+4]=='O') return 10000000;
}
}
}
return 0; //这里的分数计算思路与upOperation是一样的
}
int northwestOperation(char a[15][15], int i, int j)//声明函数northwestOperation 用于计算当前格在排除向右下扫描的影响后 向左上扫描的各种情况的分数
{
if(j-1<0||i-1<0) return 0;
if(j+1<15&&i+1<15&&(a[i-1][j-1]==a[i+1][j+1])) return 0;
if(a[i-1][j-1]=='.') return 0;
if(i-2>=0&&j-2>=0)
{
if(a[i-1][j-1]=='X'&&a[i-2][j-2]=='O'&&i<12&&j<12) return 0;
if(a[i-1][j-1]=='X'&&a[i-2][j-2]=='.'&&i<12&&j<12) return 10;
if(a[i-1][j-1]=='O'&&a[i-2][j-2]=='X'&&i<12&&j<12) return 1;
if(a[i-1][j-1]=='O'&&a[i-2][j-2]=='.'&&i<12&&j<12) return 100;
if(i-3>=0&&j-3>=0)
{
if(a[i-1][j-1]=='X'&&a[i-2][j-2]=='X'&&a[i-3][j-3]=='O'&&i<13&&j<13) return 11;
if(a[i-1][j-1]=='X'&&a[i-2][j-2]=='X'&&a[i-3][j-3]=='.'&&i<13&&j<13) return 1000;
if(a[i-1][j-1]=='O'&&a[i-2][j-2]=='O'&&a[i-3][j-3]=='X'&&i<13&&j<13) return 101;
if(a[i-1][j-1]=='O'&&a[i-2][j-2]=='O'&&a[i-3][j-3]=='.'&&i<13&&j<13) return 10000;
if(i-4>=0&&j-4>=0)
{
if(a[i-1][j-1]=='X'&&a[i-2][j-2]=='X'&&a[i-3][j-3]=='X'&&a[i-4][j-4]=='O'&&i<14&&j<14) return 1001;
if(a[i-1][j-1]=='X'&&a[i-2][j-2]=='X'&&a[i-3][j-3]=='X'&&a[i-4][j-4]=='.'&&i<14&&j<14) return 100000;
if(a[i-1][j-1]=='O'&&a[i-2][j-2]=='O'&&a[i-3][j-3]=='O'&&a[i-4][j-4]=='X'&&i<14&&j<14&&a[i+1][j+1]!='X') return 10001;
if(a[i-1][j-1]=='O'&&a[i-2][j-2]=='O'&&a[i-3][j-3]=='O'&&a[i-4][j-4]=='X'&&i<14&&j<14&&a[i+1][j+1]=='X') return 0;
if(a[i-1][j-1]=='O'&&a[i-2][j-2]=='O'&&a[i-3][j-3]=='O'&&a[i-4][j-4]=='.'&&i<14&&j<14&&a[i+1][j+1]!='X') return 100001;
if(a[i-1][j-1]=='O'&&a[i-2][j-2]=='O'&&a[i-3][j-3]=='O'&&a[i-4][j-4]=='.'&&i<14&&j<14&&a[i+1][j+1]=='X') return 10001;
if(a[i-1][j-1]=='X'&&a[i-2][j-2]=='X'&&a[i-3][j-3]=='X'&&a[i-4][j-4]=='X') return 1000000;
if(a[i-1][j-1]=='O'&&a[i-2][j-2]=='O'&&a[i-3][j-3]=='O'&&a[i-4][j-4]=='O') return 10000000;
}
}
}
return 0; //这里的分数计算思路与upOperation是一样的
}
int southeastOperation(char a[15][15], int i, int j)//声明函数southeastOperation 用于计算当前格在排除向左上扫描的影响后 向右下扫描的各种情况的分数
{
if(j+1>14||i+1>14) return 0;
if(i-1>=0&&j-1>=0&&(a[i-1][j-1]==a[i+1][j+1])) return 0;
if(a[i+1][j+1]=='.') return 0;
if(i+2<15&&j+2<15)
{
if(a[i+1][j+1]=='X'&&a[i+2][j+2]=='O'&&i>2&&j>2) return 0;
if(a[i+1][j+1]=='X'&&a[i+2][j+2]=='.'&&i>2&&j>2) return 10;
if(a[i+1][j+1]=='O'&&a[i+2][j+2]=='X'&&i>2&&j>2) return 1;
if(a[i+1][j+1]=='O'&&a[i+2][j+2]=='.'&&i>2&&j>2) return 100;
if(i+3<15&&j+3<15)
{
if(a[i+1][j+1]=='X'&&a[i+2][j+2]=='X'&&a[i+3][j+3]=='O'&&i>1&&j>1) return 11;
if(a[i+1][j+1]=='X'&&a[i+2][j+2]=='X'&&a[i+3][j+3]=='.'&&i>1&&j>1) return 1000;
if(a[i+1][j+1]=='O'&&a[i+2][j+2]=='O'&&a[i+3][j+3]=='X'&&i>1&&j>1) return 101;
if(a[i+1][j+1]=='O'&&a[i+2][j+2]=='O'&&a[i+3][j+3]=='.'&&i>1&&j>1) return 10000;
if(i+4<15&&j+4<15)
{
if(a[i+1][j+1]=='X'&&a[i+2][j+2]=='X'&&a[i+3][j+3]=='X'&&a[i+4][j+4]=='O'&&i>0&&j>0) return 1001;
if(a[i+1][j+1]=='X'&&a[i+2][j+2]=='X'&&a[i+3][j+3]=='X'&&a[i+4][j+4]=='.'&&i>0&&j>0) return 100000;
if(a[i+1][j+1]=='O'&&a[i+2][j+2]=='O'&&a[i+3][j+3]=='O'&&a[i+4][j+4]=='X'&&i>0&&j>0&&a[i-1][j-1]!='X') return 10001;
if(a[i+1][j+1]=='O'&&a[i+2][j+2]=='O'&&a[i+3][j+3]=='O'&&a[i+4][j+4]=='X'&&i>0&&j>0&&a[i-1][j-1]=='X') return 0;
if(a[i+1][j+1]=='O'&&a[i+2][j+2]=='O'&&a[i+3][j+3]=='O'&&a[i+4][j+4]=='.'&&i>0&&j>0&&a[i-1][j-1]!='X') return 100001;
if(a[i+1][j+1]=='O'&&a[i+2][j+2]=='O'&&a[i+3][j+3]=='O'&&a[i+4][j+4]=='.'&&i>0&&j>0&&a[i-1][j-1]=='X') return 10001;
if(a[i+1][j+1]=='X'&&a[i+2][j+2]=='X'&&a[i+3][j+3]=='X'&&a[i+4][j+4]=='X') return 1000000;
if(a[i+1][j+1]=='O'&&a[i+2][j+2]=='O'&&a[i+3][j+3]=='O'&&a[i+4][j+4]=='O') return 10000000;
}
}
}
return 0; //这里的分数计算思路与upOperation是一样的
}
int northeastOperation(char a[15][15], int i, int j)//声明函数northeastOperation 用于计算当前格在排除向左下扫描的影响后 向右上扫描的各种情况的分数
{
if(j+1>14||i-1<0) return 0;
if(i+1<15&&j-1>=0&&(a[i-1][j+1]==a[i+1][j-1])) return 0;
if(a[i-1][j+1]=='.') return 0;
if(i-2>=0&&j+2<15)
{
if(a[i-1][j+1]=='X'&&a[i-2][j+2]=='O'&&i<12&&j>2) return 0;
if(a[i-1][j+1]=='X'&&a[i-2][j+2]=='.'&&i<12&&j>2) return 10;
if(a[i-1][j+1]=='O'&&a[i-2][j+2]=='X'&&i<12&&j>2) return 1;
if(a[i-1][j+1]=='O'&&a[i-2][j+2]=='.'&&i<12&&j>2) return 100;
if(i-3>=0&&j+3<15)
{
if(a[i-1][j+1]=='X'&&a[i-2][j+2]=='X'&&a[i-3][j+3]=='O'&&i<13&&j>1) return 11;
if(a[i-1][j+1]=='X'&&a[i-2][j+2]=='X'&&a[i-3][j+3]=='.'&&i<13&&j>1) return 1000;
if(a[i-1][j+1]=='O'&&a[i-2][j+2]=='O'&&a[i-3][j+3]=='X'&&i<13&&j>1) return 101;
if(a[i-1][j+1]=='O'&&a[i-2][j+2]=='O'&&a[i-3][j+3]=='.'&&i<13&&j>1) return 10000;
if(i-4>=0&&j+4<15)
{
if(a[i-1][j+1]=='X'&&a[i-2][j+2]=='X'&&a[i-3][j+3]=='X'&&a[i-4][j+4]=='O'&&i<14&&j>0) return 1001;
if(a[i-1][j+1]=='X'&&a[i-2][j+2]=='X'&&a[i-3][j+3]=='X'&&a[i-4][j+4]=='.'&&i<14&&j>0) return 100000;
if(a[i-1][j+1]=='O'&&a[i-2][j+2]=='O'&&a[i-3][j+3]=='O'&&a[i-4][j+4]=='X'&&i<14&&j>0&&a[i+1][j-1]!='X') return 10001;
if(a[i-1][j+1]=='O'&&a[i-2][j+2]=='O'&&a[i-3][j+3]=='O'&&a[i-4][j+4]=='X'&&i<14&&j>0&&a[i+1][j-1]=='X') return 0;
if(a[i-1][j+1]=='O'&&a[i-2][j+2]=='O'&&a[i-3][j+3]=='O'&&a[i-4][j+4]=='.'&&i<14&&j>0&&a[i+1][j-1]!='X') return 100001;
if(a[i-1][j+1]=='O'&&a[i-2][j+2]=='O'&&a[i-3][j+3]=='O'&&a[i-4][j+4]=='.'&&i<14&&j>0&&a[i+1][j-1]=='X') return 10001;
if(a[i-1][j+1]=='X'&&a[i-2][j+2]=='X'&&a[i-3][j+3]=='X'&&a[i-4][j+4]=='X') return 1000000;
if(a[i-1][j+1]=='O'&&a[i-2][j+2]=='O'&&a[i-3][j+3]=='O'&&a[i-4][j+4]=='O') return 10000000;
}
}
}
return 0; //这里的分数计算思路与upOperation是一样的
}
int southwestOperation(char a[15][15], int i, int j)//声明函数southwestOperation 用于计算当前格在排除向右上扫描的影响后 向左下扫描的各种情况的分数
{
if(j-1<0||i+1>14) return 0;
if(i-1>=0&&j+1<15&&(a[i+1][j-1]==a[i-1][j+1])) return 0;
if(a[i+1][j-1]=='.') return 0;
if(j-2>=0&&i+2<15)
{
if(a[i+1][j-1]=='X'&&a[i+2][j-2]=='O'&&i>2&&j<12) return 0;
if(a[i+1][j-1]=='X'&&a[i+2][j-2]=='.'&&i>2&&j<12) return 10;
if(a[i+1][j-1]=='O'&&a[i+2][j-2]=='X'&&i>2&&j<12) return 1;
if(a[i+1][j-1]=='O'&&a[i+2][j-2]=='.'&&i>2&&j<12) return 100;
if(i+3<15&&j-3>=0)
{
if(a[i+1][j-1]=='X'&&a[i+2][j-2]=='X'&&a[i+3][j-3]=='O'&&i>1&&j<13) return 11;
if(a[i+1][j-1]=='X'&&a[i+2][j-2]=='X'&&a[i+3][j-3]=='.'&&i>1&&j<13) return 1000;
if(a[i+1][j-1]=='O'&&a[i+2][j-2]=='O'&&a[i+3][j-3]=='X'&&i>1&&j<13) return 101;
if(a[i+1][j-1]=='O'&&a[i+2][j-2]=='O'&&a[i+3][j-3]=='.'&&i>1&&j<13) return 10000;
if(i+4<15&&j-4>=0)
{
if(a[i+1][j-1]=='X'&&a[i+2][j-2]=='X'&&a[i+3][j-3]=='X'&&a[i+4][j-4]=='O'&&i>0&&j<14) return 1001;
if(a[i+1][j-1]=='X'&&a[i+2][j-2]=='X'&&a[i+3][j-3]=='X'&&a[i+4][j-4]=='.'&&i>0&&j<14) return 100000;
if(a[i+1][j-1]=='O'&&a[i+2][j-2]=='O'&&a[i+3][j-3]=='O'&&a[i+4][j-4]=='X'&&i>0&&j<14&&a[i-1][j+1]!='X') return 10001;
if(a[i+1][j-1]=='O'&&a[i+2][j-2]=='O'&&a[i+3][j-3]=='O'&&a[i+4][j-4]=='X'&&i>0&&j<14&&a[i-1][j+1]=='X') return 0;
if(a[i+1][j-1]=='O'&&a[i+2][j-2]=='O'&&a[i+3][j-3]=='O'&&a[i+4][j-4]=='.'&&i>0&&j<14&&a[i-1][j+1]!='X') return 100001;
if(a[i+1][j-1]=='O'&&a[i+2][j-2]=='O'&&a[i+3][j-3]=='O'&&a[i+4][j-4]=='.'&&i>0&&j<14&&a[i-1][j+1]=='X') return 10001;
if(a[i+1][j-1]=='X'&&a[i+2][j-2]=='X'&&a[i+3][j-3]=='X'&&a[i+4][j-4]=='X') return 1000000;
if(a[i+1][j-1]=='O'&&a[i+2][j-2]=='O'&&a[i+3][j-3]=='O'&&a[i+4][j-4]=='O') return 10000000;
}
}
}
return 0; //这里的分数计算思路与upOperation是一样的
}
int otherOperation(char a[15][15], int i, int j)//声明函数otherOperation 用于计算无法只考虑一个方向的情况的分数
{
if(i==0||i==14||j==0||j==14) return 0; //如果该格在边界上 则不予考虑 返回分数0
else if((j-4>=0&&a[i][j-4]!='X'&&a[i][j-3]=='O'&&a[i][j-2]=='O'&&a[i][j-1]=='.')+
(j+4<15&&a[i][j+4]!='X'&&a[i][j+3]=='O'&&a[i][j+2]=='O'&&a[i][j+1]=='.')+
(i-4>=0&&a[i-4][j]!='X'&&a[i-3][j]=='O'&&a[i-2][j]=='O'&&a[i-1][j]=='.')+
(i+4<15&&a[i+4][j]!='X'&&a[i+3][j]=='O'&&a[i+2][j]=='O'&&a[i+1][j]=='.')+
(j-4>=0&&i-4>=0&&a[i-4][j-4]!='X'&&a[i-3][j-3]=='O'&&a[i-2][j-2]=='O'&&a[i-1][j-1]=='.')+
(j+4<15&&i+4<15&&a[i+4][j+4]!='X'&&a[i+3][j+3]=='O'&&a[i+2][j+2]=='O'&&a[i+1][j+1]=='.')+
(j-4>=0&&i+4<15&&a[i+4][j-4]!='X'&&a[i+3][j-3]=='O'&&a[i+2][j-2]=='O'&&a[i+1][j-1]=='.')+
(j+4<15&&i-4>=0&&a[i-4][j+4]!='X'&&a[i-3][j+3]=='O'&&a[i-2][j+2]=='O'&&a[i-1][j+1]=='.')>=2)
return 100001; //如果产生至少两个向外延伸分别为.OOX的情况 则下这里相当于给自己一个三个不被堵的子 返回分数100001
else if((i-2>=0&&i+2<15&&a[i+2][j]=='O'&&a[i+1][j]=='O'&&a[i-2][j]=='O'&&a[i-1][j]=='O')||
(j-2>=0&&j+2<15&&a[i][j+2]=='O'&&a[i][j+1]=='O'&&a[i][j-1]=='O'&&a[i][j-2]=='O')||
(i-2>=0&&i+2<15&&j-2>=0&&j+2<15&&a[i-2][j-2]=='O'&&a[i-1][j-1]=='O'&&a[i+1][j+1]=='O'&&a[i+2][j+2]=='O')||
(i-2>=0&&i+2<15&&j-2>=0&&j+2<15&&a[i-2][j+2]=='O'&&a[i-1][j+1]=='O'&&a[i+1][j-1]=='O'&&a[i+2][j-2]=='O')||
(i-3>=0&&i+1<15&&a[i-3][j]=='O'&&a[i-2][j]=='O'&&a[i-1][j]=='0'&&a[i+1][j]=='O')||
(i-1>=0&&i+3<15&&a[i+3][j]=='O'&&a[i+2][j]=='O'&&a[i+1][j]=='0'&&a[i-1][j]=='O')||
(j-3>=0&&j+1<15&&a[i][j-3]=='O'&&a[i][j-2]=='O'&&a[i][j-1]=='0'&&a[i][j+1]=='O')||
(j-1>=0&&j+3<15&&a[i][j+3]=='O'&&a[i][j+2]=='O'&&a[i][j+1]=='0'&&a[i][j-1]=='O')||
(i-3>=0&&i+1<15&&j-3>=0&&j+1<15&&a[i-3][j-3]=='O'&&a[i-2][j-2]=='O'&&a[i-1][j-1]=='0'&&a[i+1][j+1]=='O')||
(i-1>=0&&i+3<15&&j-1>=0&&j+3<15&&a[i+3][j+3]=='O'&&a[i+2][j+2]=='O'&&a[i+1][j+1]=='0'&&a[i-1][j-1]=='O')||
(i-3>=0&&i+1<15&&j-1>=0&&j+3<15&&a[i-3][j+3]=='O'&&a[i-2][j+2]=='O'&&a[i-1][j+1]=='0'&&a[i+1][j-1]=='O')||
(i-1>=0&&i+3<15&&j-3>=0&&j+1<15&&a[i+3][j-3]=='O'&&a[i+2][j-2]=='O'&&a[i+1][j-1]=='0'&&a[i-1][j+1]=='O'))
return 10000000; //如果有夹在中间自己成为5个的 则无论如何都会赢 返回分数10000000
else if((i-2>=0&&i+2<15&&a[i+2][j]=='X'&&a[i+1][j]=='X'&&a[i-2][j]=='X'&&a[i-1][j]=='X')||
(j-2>=0&&j+2<15&&a[i][j+2]=='X'&&a[i][j+1]=='X'&&a[i][j-1]=='X'&&a[i][j-2]=='X')||
(i-2>=0&&i+2<15&&j-2>=0&&j+2<15&&a[i-2][j-2]=='X'&&a[i-1][j-1]=='X'&&a[i+1][j+1]=='X'&&a[i+2][j+2]=='X')||
(i-2>=0&&i+2<15&&j-2>=0&&j+2<15&&a[i-2][j+2]=='X'&&a[i-1][j+1]=='X'&&a[i+1][j-1]=='X'&&a[i+2][j-2]=='X')||
(i-3>=0&&i+1<15&&a[i-3][j]=='X'&&a[i-2][j]=='X'&&a[i-1][j]=='X'&&a[i+1][j]=='X')||
(i-1>=0&&i+3<15&&a[i+3][j]=='X'&&a[i+2][j]=='X'&&a[i+1][j]=='X'&&a[i-1][j]=='X')||
(j-3>=0&&j+1<15&&a[i][j-3]=='X'&&a[i][j-2]=='X'&&a[i][j-1]=='X'&&a[i][j+1]=='X')||
(j-1>=0&&j+3<15&&a[i][j+3]=='X'&&a[i][j+2]=='X'&&a[i][j+1]=='X'&&a[i][j-1]=='X')||
(i-3>=0&&i+1<15&&j-3>=0&&j+1<15&&a[i-3][j-3]=='X'&&a[i-2][j-2]=='X'&&a[i-1][j-1]=='X'&&a[i+1][j+1]=='X')||
(i-1>=0&&i+3<15&&j-1>=0&&j+3<15&&a[i+3][j+3]=='X'&&a[i+2][j+2]=='X'&&a[i+1][j+1]=='X'&&a[i-1][j-1]=='X')||
(i-3>=0&&i+1<15&&j-1>=0&&j+3<15&&a[i-3][j+3]=='X'&&a[i-2][j+2]=='X'&&a[i-1][j+1]=='X'&&a[i+1][j-1]=='X')||
(i-1>=0&&i+3<15&&j-3>=0&&j+1<15&&a[i+3][j-3]=='X'&&a[i+2][j-2]=='X'&&a[i+1][j-1]=='X'&&a[i-1][j+1]=='X'))
return 1000000; //如果有夹在中间对方成为5个的 在自己尚未4个的情况下 必须堵 返回分数1000000
else if((i-3>=0&&i+2<15&&a[i-3][j]=='.'&&a[i-2][j]=='O'&&a[i-1][j]=='O'&&a[i+1][j]=='O'&&a[i+2][j]=='.')||
(i-2>=0&&i+3<15&&a[i-2][j]=='.'&&a[i-1][j]=='O'&&a[i+1][j]=='O'&&a[i+2][j]=='O'&&a[i+3][j]=='.')||
(j-3>=0&&j+2<15&&a[i][j-3]=='.'&&a[i][j-2]=='O'&&a[i][j-1]=='O'&&a[i][j+1]=='O'&&a[i][j+2]=='.')||
(j-2>=0&&j+3<15&&a[i][j-2]=='.'&&a[i][j-1]=='O'&&a[i][j+1]=='O'&&a[i][j+2]=='O'&&a[i][j+3]=='.')||
(i-3>=0&&i+2<15&&j-3>=0&&j+2<15&&a[i-3][j-3]=='.'&&a[i-2][j-2]=='O'&&a[i-1][j-1]=='O'&&a[i+1][j+1]=='O'&&a[i+2][j+2]=='.')||
(i-2>=0&&i+3<15&&j-2>=0&&j+3<15&&a[i-2][j-2]=='.'&&a[i-1][j-1]=='O'&&a[i+1][j+1]=='O'&&a[i+2][j+2]=='O'&&a[i+3][j+3]=='.')||
(i-3>=0&&i+2<15&&j-2>=0&&j+3<15&&a[i-3][j+3]=='.'&&a[i-2][j+2]=='O'&&a[i-1][j+1]=='O'&&a[i+1][j-1]=='O'&&a[i+2][j-2]=='.')||
(i-2>=0&&i+3<15&&j-3>=0&&j+2<15&&a[i+3][j-3]=='.'&&a[i+2][j-2]=='O'&&a[i+1][j-1]=='O'&&a[i-1][j+1]=='O'&&a[i-2][j+2]=='.'))
return 100001; //如果有自己夹在中间构成4个的并且能连成5个的 并且两边都没被堵 则返回分数100001
else if((i-3>=0&&i+2<15&&a[i-3][j]=='.'&&a[i-2][j]=='X'&&a[i-1][j]=='X'&&a[i+1][j]=='X'&&a[i+2][j]=='.')||
(i-2>=0&&i+3<15&&a[i-2][j]=='.'&&a[i-1][j]=='X'&&a[i+1][j]=='X'&&a[i+2][j]=='X'&&a[i+3][j]=='.')||
(j-3>=0&&j+2<15&&a[i][j-3]=='.'&&a[i][j-2]=='X'&&a[i][j-1]=='X'&&a[i][j+1]=='X'&&a[i][j+2]=='.')||
(j-2>=0&&j+3<15&&a[i][j-2]=='.'&&a[i][j-1]=='X'&&a[i][j+1]=='X'&&a[i][j+2]=='X'&&a[i][j+3]=='.')||
(i-3>=0&&i+2<15&&j-3>=0&&j+2<15&&a[i-3][j-3]=='.'&&a[i-2][j-2]=='X'&&a[i-1][j-1]=='X'&&a[i+1][j+1]=='X'&&a[i+2][j+2]=='.')||
(i-2>=0&&i+3<15&&j-2>=0&&j+3<15&&a[i-2][j-2]=='.'&&a[i-1][j-1]=='X'&&a[i+1][j+1]=='X'&&a[i+2][j+2]=='X'&&a[i+3][j+3]=='.')||
(i-3>=0&&i+2<15&&j-2>=0&&j+3<15&&a[i-3][j+3]=='.'&&a[i-2][j+2]=='X'&&a[i-1][j+1]=='X'&&a[i+1][j-1]=='X'&&a[i+2][j-2]=='.')||
(i-2>=0&&i+3<15&&j-3>=0&&j+2<15&&a[i+3][j-3]=='.'&&a[i+2][j-2]=='X'&&a[i+1][j-1]=='X'&&a[i-1][j+1]=='X'&&a[i-2][j+2]=='.'))
return 100000; //如果有对方夹在中间构成4个的并且能连成5个的 并且两边都没被堵 则返回分数100000
else if((i-3>=0&&i+2<15&&a[i-2][j]=='O'&&a[i-1][j]=='O'&&a[i+1][j]=='O'&&((a[i+2][j]=='.'&&a[i-3][j]=='X')||(a[i+2][j]=='X'&&a[i-3][j]=='.')))||
(i-2>=0&&i+3<15&&a[i-1][j]=='O'&&a[i+1][j]=='O'&&a[i+2][j]=='O'&&((a[i+3][j]=='.'&&a[i-2][j]=='X')||(a[i+3][j]=='X'&&a[i-2][j]=='.')))||
(j-3>=0&&j+2<15&&a[i][j-2]=='O'&&a[i][j-1]=='O'&&a[i][j+1]=='O'&&((a[i][j+2]=='.'&&a[i][j-3]=='X')||(a[i][j+2]=='X'&&a[i][j-3]=='.')))||
(j-2>=0&&j+3<15&&a[i][j-1]=='O'&&a[i][j+1]=='O'&&a[i][j+2]=='O'&&((a[i][j+3]=='.'&&a[i][j-2]=='X')||(a[i][j+3]=='X'&&a[i][j-2]=='.')))||
(i-3>=0&&i+2<15&&j-3>=0&&j+2<15&&a[i-2][j-2]=='O'&&a[i-1][j-1]=='O'&&a[i+1][j+1]=='O'&&((a[i+2][j+2]=='.'&&a[i-3][j-3]=='X')||(a[i+2][j+2]=='X'&&a[i-3][j-3]=='.')))||
(i-2>=0&&i+3<15&&j-2>=0&&j+3<15&&a[i-1][j-1]=='O'&&a[i+1][j+1]=='O'&&a[i+2][j+2]=='O'&&((a[i+3][j+3]=='.'&&a[i-2][j-2]=='X')||(a[i+3][j+3]=='X'&&a[i-2][j-2]=='.')))||
(i-3>=0&&i+2<15&&j-2>=0&&j+3<15&&a[i-2][j+2]=='O'&&a[i-1][j+1]=='O'&&a[i+1][j-1]=='O'&&((a[i+2][j-2]=='.'&&a[i-3][j+3]=='X')||(a[i+2][j-2]=='X'&&a[i-3][j+3]=='.')))||
(i-2>=0&&i+3<15&&j-3>=0&&j+2<15&&a[i+2][j-2]=='O'&&a[i+1][j-1]=='O'&&a[i-1][j+1]=='O'&&((a[i-2][j+2]=='.'&&a[i+3][j-3]=='X')||(a[i-2][j+2]=='X'&&a[i+3][j-3]=='.'))))
return 10001; //如果有自己夹在中间构成4个并且能连成5个 但有一边被堵的 返回分数10001
else if((i-3>=0&&i+2<15&&a[i-2][j]=='X'&&a[i-1][j]=='X'&&a[i+1][j]=='X'&&((a[i+2][j]=='.'&&a[i-3][j]=='O')||(a[i+2][j]=='O'&&a[i-3][j]=='.')))||
(i-2>=0&&i+3<15&&a[i-1][j]=='X'&&a[i+1][j]=='X'&&a[i+2][j]=='X'&&((a[i+3][j]=='.'&&a[i-2][j]=='O')||(a[i+3][j]=='O'&&a[i-2][j]=='.')))||
(j-3>=0&&j+2<15&&a[i][j-2]=='X'&&a[i][j-1]=='X'&&a[i][j+1]=='X'&&((a[i][j+2]=='.'&&a[i][j-3]=='O')||(a[i][j+2]=='O'&&a[i][j-3]=='.')))||
(j-2>=0&&j+3<15&&a[i][j-1]=='X'&&a[i][j+1]=='X'&&a[i][j+2]=='X'&&((a[i][j+3]=='.'&&a[i][j-2]=='O')||(a[i][j+3]=='O'&&a[i][j-2]=='.')))||
(i-3>=0&&i+2<15&&j-3>=0&&j+2<15&&a[i-2][j-2]=='X'&&a[i-1][j-1]=='X'&&a[i+1][j+1]=='X'&&((a[i+2][j+2]=='.'&&a[i-3][j-3]=='O')||(a[i+2][j+2]=='O'&&a[i-3][j-3]=='.')))||
(i-2>=0&&i+3<15&&j-2>=0&&j+3<15&&a[i-1][j-1]=='X'&&a[i+1][j+1]=='X'&&a[i+2][j+2]=='X'&&((a[i+3][j+3]=='.'&&a[i-2][j-2]=='O')||(a[i+3][j+3]=='O'&&a[i-2][j-2]=='.')))||
(i-3>=0&&i+2<15&&j-2>=0&&j+3<15&&a[i-2][j+2]=='X'&&a[i-1][j+1]=='X'&&a[i+1][j-1]=='X'&&((a[i+2][j-2]=='.'&&a[i-3][j+3]=='O')||(a[i+2][j-2]=='O'&&a[i-3][j+3]=='.')))||
(i-2>=0&&i+3<15&&j-3>=0&&j+2<15&&a[i+2][j-2]=='X'&&a[i+1][j-1]=='X'&&a[i-1][j+1]=='X'&&((a[i-2][j+2]=='.'&&a[i+3][j-3]=='O')||(a[i-2][j+2]=='O'&&a[i+3][j-3]=='.'))))
return 1001; //如果有对方夹在中间构成4个并且能连成5个 但有一边被堵的 返回分数1001
else if((i-2>=0&&i+2<15&&a[i-2][j]=='.'&&a[i-1][j]=='O'&&a[i+1][j]=='O'&&a[i+2][j]=='.')||
(j-2>=0&&j+2<15&&a[i][j-2]=='.'&&a[i][j-1]=='O'&&a[i][j+1]=='O'&&a[i][j+2]=='.')||
(i-2>=0&&i+2<15&&j-2>=0&&j+2<15&&a[i-2][j-2]=='.'&&a[i-1][j-1]=='O'&&a[i+1][j+1]=='O'&&a[i+2][j+2]=='.')||
(i-2>=0&&i+2<15&&j-2>=0&&j+2<15&&a[i+2][j-2]=='.'&&a[i+1][j-1]=='O'&&a[i-1][j+1]=='O'&&a[i-2][j+2]=='.'))
return 1001; //如果有自己夹在中间构成3个的 并且能连成5个 两边有没有被堵 返回分数10000
else if((i-2>=0&&i+2<15&&a[i-2][j]=='.'&&a[i-1][j]=='X'&&a[i+1][j]=='X'&&a[i+2][j]=='.')||
(j-2>=0&&j+2<15&&a[i][j-2]=='.'&&a[i][j-1]=='X'&&a[i][j+1]=='X'&&a[i][j+2]=='.')||
(i-2>=0&&i+2<15&&j-2>=0&&j+2<15&&a[i-2][j-2]=='.'&&a[i-1][j-1]=='X'&&a[i+1][j+1]=='X'&&a[i+2][j+2]=='.')||
(i-2>=0&&i+2<15&&j-2>=0&&j+2<15&&a[i+2][j-2]=='.'&&a[i+1][j-1]=='X'&&a[i-1][j+1]=='X'&&a[i-2][j+2]=='.'))
return 1000; //如果有对方夹在中间构成3个的 并且能连成5个 两边有没有被堵 返回分数1000
else if((i-2>=0&&i+2<15&&a[i-1][j]=='O'&&a[i+1][j]=='O'&&((a[i+2][j]=='.'&&a[i-2][j]=='X')||(a[i+2][j]=='X'&&a[i-2][j]=='.')))||
(j-2>=0&&j+2<15&&a[i][j-1]=='O'&&a[i][j+1]=='O'&&((a[i][j+2]=='.'&&a[i][j-2]=='X')||(a[i][j+2]=='X'&&a[i][j-2]=='.')))||
(i-2>=0&&i+2<15&&j-2>=0&&j+2<15&&a[i-1][j-1]=='O'&&a[i+1][j+1]=='O'&&((a[i+2][j+2]=='.'&&a[i-2][j-2]=='X')||(a[i+2][j+2]=='X'&&a[i-2][j-2]=='.')))||
(i-2>=0&&i+2<15&&j-2>=0&&j+2<15&&a[i+1][j-1]=='O'&&a[i-1][j+1]=='O'&&((a[i-2][j+2]=='.'&&a[i+2][j-2]=='X')||(a[i-2][j+2]=='X'&&a[i+2][j-2]=='.'))))
return 101; //如果有自己夹在中间构成3个的 并且能连成5个 但有一边被堵 返回分数101
else if((i-2>=0&&i+2<15&&a[i-1][j]=='X'&&a[i+1][j]=='X'&&((a[i+2][j]=='.'&&a[i-2][j]=='O')||(a[i+2][j]=='O'&&a[i-2][j]=='.')))||
(j-2>=0&&j+2<15&&a[i][j-1]=='X'&&a[i][j+1]=='X'&&((a[i][j+2]=='.'&&a[i][j-2]=='O')||(a[i][j+2]=='O'&&a[i][j-2]=='.')))||
(i-2>=0&&i+2<15&&j-2>=0&&j+2<15&&a[i-1][j-1]=='X'&&a[i+1][j+1]=='X'&&((a[i+2][j+2]=='.'&&a[i-2][j-2]=='O')||(a[i+2][j+2]=='O'&&a[i-2][j-2]=='.')))||
(i-2>=0&&i+2<15&&j-2>=0&&j+2<15&&a[i+1][j-1]=='X'&&a[i-1][j+1]=='X'&&((a[i-2][j+2]=='.'&&a[i+2][j-2]=='O')||(a[i-2][j+2]=='O'&&a[i+2][j-2]=='.'))))
return 11; //如果有对方夹在中间构成3个的 并且能连成5个 但有一边被堵 返回分数11
else return 0; //其他的返回分数0
}
void operation(char a[15][15], int b[15][15]) //声明函数operation 用于对每一格的分数进行计算 并附到另一个数组b[][]中
{
int i3, j3; //声明整型变量 用于在此函数中 对横坐标和纵坐标进行枚举
for(i3=0;i3<15;i3++)
for(j3=0;j3<15;j3++)
{
if(a[i3][j3]!='.') b[i3][j3]=0; //如果不是空的 此格的分数为0
else b[i3][j3]=upOperation(a, i3, j3)+downOperation(a, i3, j3)+
leftOperation(a, i3, j3)+rightOperation(a, i3, j3)+
northwestOperation(a, i3, j3)+southeastOperation(a, i3, j3)+
northeastOperation(a, i3, j3)+southwestOperation(a, i3, j3)+
otherOperation(a, i3, j3); //每一格的分数等于它在各个方向上的分数之和
}
}
void winPicture(bool blackOrWhite) //声明函数winPicture 用于对人人对战的胜方进行祝贺
{
string winner; //声明字符串 winner 用于储存胜方的昵称
if(blackOrWhite==1)
winner=player1;
else winner=player2; //通过blackOrWhite的值来给winner赋值
cout<<"------- 我是华丽丽的分割线------"<<endl;
cout<<" "<<endl;
cout<<" .\"\". .\"\", "<<endl;
cout<<" | | / / "<<endl;
cout<<" | | / / "<<endl;
cout<<" | | / / "<<endl;
cout<<" | |/ ;-._ "<<endl;
cout<<" } ` _/ / ; "<<endl;
cout<<" | /` ) / / "<<endl;
cout<<" | / /_/\\_/\\ "<<endl;
cout<<" |/ / | "<<endl;
cout<<" ( ' \\ '- | "<<endl;
cout<<" \\ `. / "<<endl;
cout<<" | | "<<endl;
cout<<" | | "<<endl;
cout<<" "<<endl; //输出字符画 “胜利的手”
cout<<" Congratulation to "<<endl;
cout<<" "<<winner<<endl; //对胜方表示祝贺
cout<<" "<<endl;
cout<<"Press Any Key And Enter To Return To The Catalogue: "<<endl;
for(;;)
{
char k;
cin>>k;
if(cin.peek()=='\n')
{
system("cls");
break;
}
} //按任意键和回车 退出胜利画面 返回主菜单
}
void losePicture() //声明函数losePicture 用于提示在人机对战中用户输掉了
{
cout<<"------- 我是华丽丽的分割线------"<<endl;
cout<<" "<<endl;
cout<<endl;
cout<<" .----------."<<endl;
cout<<" / \\"<<endl;
cout<<" | |"<<endl;
cout<<" |, .-. .-. ,|"<<endl;
cout<<" | )(__/ \\__)( |"<<endl;
cout<<" |/ /\\ \\| "<<endl;
cout<<" (@_ (_ ^^ _)"<<endl;
cout<<" _ ) \\_______\\__|IIIIII|__/__________________________"<<endl;
cout<<" (_)@8@8{}<________|-\\IIIIII/-|___________________________ >"<<endl;
cout<<" )_/ \\ /"<<endl;
cout<<" (@ `--------` "<<endl;
cout<<" "<<endl;
cout<<" No!!! 你的大脑被电脑吃掉了!!! "<<endl; //输出字符画“骷髅头”
cout<<" "<<endl; //植物大战僵尸的经典语录
cout<<"Press Any Key And Enter To Return To The Catalogue: "<<endl;
for(;;)
{
char k;
cin>>k;
if(cin.peek()=='\n')
{
system("cls");
break;
}
} //按任意键和回车 退出失败画面 返回主菜单
}
void winPicture2(string player3) //声明函数winPicture2 用于对人机对战胜利的用户进行祝贺
{
cout<<"------- 我是华丽丽的分割线------"<<endl;
cout<<" "<<endl;
cout<<" .\"\". .\"\", "<<endl;
cout<<" | | / / "<<endl;
cout<<" | | / / "<<endl;
cout<<" | | / / "<<endl;
cout<<" | |/ ;-._ "<<endl;
cout<<" } ` _/ / ; "<<endl;
cout<<" | /` ) / / "<<endl;
cout<<" | / /_/\\_/\\ "<<endl;
cout<<" |/ / | "<<endl;
cout<<" ( ' \\ '- | "<<endl;
cout<<" \\ `. / "<<endl;
cout<<" | | "<<endl;
cout<<" | | "<<endl;
cout<<" "<<endl;//输出字符画 “胜利的手”
cout<<" Congratulation to "<<endl;
cout<<" "<<player3<<endl; //对用户表示祝贺
cout<<" "<<endl;
cout<<"Press Any Key And Enter To Return To The Catalogue: "<<endl;
for(;;)
{
char k;
cin>>k;
if(cin.peek()=='\n')
{
system("cls");
break;
}
} //按任意键和回车 退出胜利画面 返回主菜单
}
int main() //终于到主函数了 ⊙﹏⊙
{
//0-1 显示开机动画
welcome();
//0-2 声明接下来要用到的各种变量 a[15][15]储存人人对战中棋盘的棋子 a1[15][15]储存人机对战中棋盘的棋子 b[15][15]储存人机对战中各格的分数
// winOrLose表示人人对战中是否有胜出的 开始时定为0 表示没有 winOrLose2表示人机对战中是否有胜出的 开始时定为0 表示没有 1表示用户胜利 2表示计算机胜利
// i和j用于表示棋盘的纵坐标和横坐标 i1和j1用于记录人人对战每一步下的棋的坐标 用于悔棋 i11和j11用于记录人机对战每一局用户下的棋的坐标
// selection用于记录用户在主菜单下选择的数字 choose用于记录用户在人人对战和人机对战模式主菜单下选择的数字
// choose2用于记录人机对战模式的重新开始菜单里用户选择的数字 iMax jMax表示的是b[15][15]中分数最高项的纵坐标和横坐标 takeback表示是否用了悔棋操作
char a[15][15], a1[15][15];
int winOrLose=0, winOrLose2=0, b[15][15];
int i, j, n, i1, j1, i11, j11, selection=0, choose=0, choose2=0, iMax=0, jMax=0, takeback=0;
for(i=0;i<15;i++)
for(j=0;j<15;j++)
{
a[i][j]='.';
a1[i][j]='.';
}//对两个棋盘进行初始化 使若读档失误则可以重新开始
//0-3 主菜单与各分菜单之间的转化 用for循环来完成 每一次选项都会给selection一个值 对应不同的选项 用if语句来判断并执行相应的菜单函数
for(;;)
{
//1 主菜单 当selection=0(默认为0)时 调用函数catalogue 弹出主菜单 并将用户的选择赋给selection
if(selection==0)
{
selection=catalogue();
}
//2 人人对战模式菜单 主菜单中当用户选择1时 赋给selection值1 用if语句判断后 调用函数manVsMan 弹出人人对战模式菜单
if(selection==1)
{
//2-0 准备工作 声明文件输入输出流 用于对每次的棋局进行存储 在再次打开时 可以导入从而达到自动存档和读档的效果
ofstream outfileone("manVsMan.txt",ios::app);
if(! outfileone)
{
cerr<<"抱歉!您的存档崩溃了~~~"<<endl;
exit(1);
} //打开文件失败提醒
outfileone.close(); //声明文件输出流outfileone 并让它与文件manVsMan.txt关联 来将棋盘a[15][15]存到该文件中
ifstream infileone("manVsMan.txt");
if(! infileone)
{
cerr<<"抱歉!您的存档崩溃了~~~"<<endl;
exit(1);
} //打开文件失败提醒
infileone.close();//声明文件输入流infileone 并让它与文件manVsMan.txt关联 来将该文件中的信息导入到a[15][15]中
ofstream outfileone1("blackOrWhite1.txt",ios::app);
if(! outfileone1)
{
cerr<<"抱歉!您的存档崩溃了~~~"<<endl;
exit(1);
} //打开文件失败提醒
outfileone1.close();//声明文件输出流outfileone1 并让它与文件blackOrWhite1.txt关联 来将该局下棋方存到该文件中
ifstream infileone1("blackOrWhite1.txt");
if(! infileone1)
{
cerr<<"抱歉!您的存档崩溃了~~~"<<endl;
exit(1);
} //打开文件失败提醒
infileone1.close();//声明文件输入流infileone1 并让它与文件blackOrWhite1.txt关联 来将该文件中的下棋方导入到blackOrWhite中
ofstream outfileone2("players.txt",ios::app);
if(! outfileone2)
{
cerr<<"抱歉!您的存档崩溃了~~~"<<endl;
exit(1);
} //打开文件失败提醒
outfileone2.close();//声明文件输出流outfileone2 并让它与文件players.txt关联 来将双方昵称存到该文件中
ifstream infileone2("players.txt");
if(! infileone2)
{
cerr<<"抱歉!您的存档崩溃了~~~"<<endl;
exit(1);
} //打开文件失败提醒
infileone2.close();//声明文件输入流infileone2 并让它与文件players.txt关联 来将文件中的昵称信息导入到player1和player2中
//2-1 铺棋盘工序 进入人人对战模式后 选择是重新开始 还是继续上次的比赛
choose=manVsMan(); //调用manVsMan函数 用choose来储存用户的选择
//2-1-1 选择重新开始后 棋盘置空 并且提醒双方输入昵称
if(choose==2) //如果用户选择2 就执行以下操作
{
for(i=0;i<15;i++)
for(j=0;j<15;j++)
{
a[i][j]='.';
} //1.棋盘置空 全部为'.'
cout<<"请输入对战双方的昵称(以空格间隔,输入”0 0“使用默认昵称)"<<endl;
cin>>player1>>player2; //2.请用户输入对战双方的昵称
if(player1=="0"&&player2=="0") player1="黑棋棋手", player2="白棋棋手"; //如果输入0 0 则默认为默认昵称
outfileone2.open("players.txt");
outfileone2<<player1<<" "<<player2;
outfileone2.close(); //打开文件players.txt 将输入的昵称输出到文件中 用于存档 结束后关闭文件
system("cls"); //清屏 以便开始棋局
}
//2-1-2 选择继续 棋盘从文件读入上次的棋盘布局 轮到方 及昵称 然后开始棋局
if(choose==1) //如果用户选择1 就执行以下操作
{
infileone.open("manVsMan.txt");
for(i=0;i<15;i++)
for(j=0;j<15;j++)
{
infileone>>a[i][j];
}
infileone.close(); //打开文件manVsMan.txt 将其中每一格的信息导入到a[15][15]中 结束后关闭文件
infileone1.open("blackOrWhite1.txt");
infileone1>>blackOrWhite;
infileone1.close(); //打开文件blackOrWhite1.txt 将其中轮到的棋手信息导入到blackOrWhite中 结束后关闭文件
infileone2.open("players.txt");
infileone2>>player1;
infileone2>>player2;
infileone2.close(); //打开文件players.txt 将其中的对战双方的昵称导入到player1 player2中 结束后关闭文件
ifwin=0; //让ifwin=0 表示每次读档时 默认胜负未分 避免上次游戏的影响
}
//2-2 进入人人对战模式的棋局 开始对战
for(n=0;;n++) //for循环用于使对战持续进行下去 直到产生特定条件(胜利、认输……)退出 n表示下棋数
{
//2-2-1 打开每一轮下棋后的棋局 并记录棋局 用于存档
coutboard(blackOrWhite,a); //调用函数coutboard
outfileone.open("manVsMan.txt");
for(i=0;i<15;i++)
for(j=0;j<15;j++)
{
outfileone<<a[i][j]<<" ";
}
outfileone.close();
outfileone1.open("blackOrWhite1.txt");
outfileone1<<blackOrWhite;
outfileone1.close(); //打开文件manVsMan.txt和blackOrWhite1.txt 并将棋盘信息导出到文件里 然后关闭文件
//2-2-2 给出提示语 获得下棋命令
for(int tips;;tips++) //用for循环来使提示部分当且仅当命令输入有效时退出 否则不停循环
{
if(blackOrWhite==1) cout<<player1;
if(blackOrWhite==0) cout<<player2; //用blackOrWhite的值来判断此局应该由哪方下
cout<<" 请输入棋子的纵坐标和横坐标,以空格间隔(输入“0 0”返回主菜单 输入“give up”认输):";//提醒该方输入命令
string x,y; //声明字符串变量x y 用于接收用户的命令 用字符串 可以接收用户的错误命令 以方便判断
cin>>x;
cin>>y;
i=atoi(x.c_str());
j=atoi(y.c_str()); //将x y转化为其对应的数字
if(x=="0"&&y=="0")
{
selection=0;
ifwin=1;
break;
} //如果输入的是0 0 即用户想要暂时退出对战 则将selection赋值0 表示选择主菜单 将ifwin赋值1 表示有人胜利(当然没有) 可以结束循环了 最后break跳出提示循环
//2-2-2-1 人人对战模式中 棋局轮到黑棋棋手下子
if(blackOrWhite==1)
{
if(x=="take"&&y=="back"&&n!=0)
{
a[i1-1][j1-1]='.';
blackOrWhite=abs(blackOrWhite-1);
n--;
break;
} //如果该棋轮到黑棋棋手 且存在上一步 输入的是take back 即用户想要悔棋 那么让上一步的棋子变成‘.’ 让blackOrWhite变成0 棋局数减一 最后break跳出提示循环
else if(x=="give"&&y=="up")
{
winOrLose=1;
break;
} //如果用户输入give up 那么winOrLose变为1 表明对手胜利 break 跳出循环
else if((x=="1"||x=="2"||x=="3"||x=="4"||x=="5"||x=="6"||x=="7"||x=="8"||x=="9"||x=="10"||x=="11"||x=="12"||x=="13"||x=="14"||x=="15")&&
(y=="1"||y=="2"||y=="3"||y=="4"||y=="5"||y=="6"||y=="7"||y=="8"||y=="9"||y=="10"||y=="11"||y=="12"||y=="13"||y=="14"||y=="15")&&a[i-1][j-1]=='.')
{
a[i-1][j-1]='X';
blackOrWhite=abs(blackOrWhite-1);
i1=i;
j1=j;
break;
} //当且仅当用户输入的x y是1到15的数字时并且该格是空的 让该格变成'X' 棋局轮到白棋棋手 用i1 j1记录此局改变的格子的坐标 最后break跳出提示循环
else if((x=="1"||x=="2"||x=="3"||x=="4"||x=="5"||x=="6"||x=="7"||x=="8"||x=="9"||x=="10"||x=="11"||x=="12"||x=="13"||x=="14"||x=="15")&&
(y=="1"||y=="2"||y=="3"||y=="4"||y=="5"||y=="6"||y=="7"||y=="8"||y=="9"||y=="10"||y=="11"||y=="12"||y=="13"||y=="14"||y=="15")&&a[i-1][j-1]=='X')
cout<<"别闹了 不要在自己的黑子上下子啊 难道你想制作双层汉堡么? 重新输入吧~~~"<<endl;
else if((x=="1"||x=="2"||x=="3"||x=="4"||x=="5"||x=="6"||x=="7"||x=="8"||x=="9"||x=="10"||x=="11"||x=="12"||x=="13"||x=="14"||x=="15")&&
(y=="1"||y=="2"||y=="3"||y=="4"||y=="5"||y=="6"||y=="7"||y=="8"||y=="9"||y=="10"||y=="11"||y=="12"||y=="13"||y=="14"||y=="15")&&a[i-1][j-1]=='O')
cout<<"呵呵 做人不要太嚣张 怎么能在白子上下黑子 我会代表月亮 命令你重新输入!"<<endl;
else cout<<"思想有多远 我们就能走多远 但你输入坐标也不能离谱得这么远吧~~请重新输入吧"<<endl; //如果输入的坐标上有已有黑棋或已有白棋 或输入无效 那么给出相应的提示语 然后继续循环
}
//2-2-2-2 人人对战模式中 棋局轮到白棋棋手下子
if(blackOrWhite==0)
{
if(x=="take"&&y=="back"&&n!=0)
{
a[i1-1][j1-1]='.';
blackOrWhite=abs(blackOrWhite-1);
n--;
break;
} //如果该棋轮到白棋棋手并且存在上一步 输入的是take back 即用户想要悔棋 那么让上一步的棋子变成‘.’ 让blackOrWhite变成1 棋局数减一 最后break跳出提示循环
else if(x=="give"&&y=="up")
{
winOrLose=1;
break;
}//如果用户输入give up 那么winOrLose变为1 表明对手胜利 break 跳出循环
else if((x=="1"||x=="2"||x=="3"||x=="4"||x=="5"||x=="6"||x=="7"||x=="8"||x=="9"||x=="10"||x=="11"||x=="12"||x=="13"||x=="14"||x=="15")&&
(y=="1"||y=="2"||y=="3"||y=="4"||y=="5"||y=="6"||y=="7"||y=="8"||y=="9"||y=="10"||y=="11"||y=="12"||y=="13"||y=="14"||y=="15")&&a[i-1][j-1]=='.')
{
a[i-1][j-1]='O';
i1=i;
j1=j;
blackOrWhite=abs(blackOrWhite-1);
break;
} //当且仅当用户输入的x y是1到15的数字时并且该格是空的 让该格变成'X' 棋局轮到黑棋棋手 用i1 j1记录此局改变的格子的坐标 最后break跳出提示循环
else if((x=="1"||x=="2"||x=="3"||x=="4"||x=="5"||x=="6"||x=="7"||x=="8"||x=="9"||x=="10"||x=="11"||x=="12"||x=="13"||x=="14"||x=="15")&&
(y=="1"||y=="2"||y=="3"||y=="4"||y=="5"||y=="6"||y=="7"||y=="8"||y=="9"||y=="10"||y=="11"||y=="12"||y=="13"||y=="14"||y=="15")&&a[i-1][j-1]=='O')
cout<<"别闹了 不要在自己的白子上下子啊 难道你想制作双层汉堡么? 重新输入吧~~~"<<endl;
else if((x=="1"||x=="2"||x=="3"||x=="4"||x=="5"||x=="6"||x=="7"||x=="8"||x=="9"||x=="10"||x=="11"||x=="12"||x=="13"||x=="14"||x=="15")&&
(y=="1"||y=="2"||y=="3"||y=="4"||y=="5"||y=="6"||y=="7"||y=="8"||y=="9"||y=="10"||y=="11"||y=="12"||y=="13"||y=="14"||y=="15")&&a[i-1][j-1]=='X')
cout<<"呵呵 做人不要太嚣张 怎么能在黑子上下白子 我会代表月亮 命令你重新输入!"<<endl;
else cout<<"思想有多远 我们就能走多远 但你输入坐标也不能离谱得这么远吧~~请重新输入吧"<<endl;
}//如果输入的坐标上有已有白棋或已有黑棋 或输入无效 那么给出相应的提示语 然后继续循环
}
//2-2-3 清屏 离开提示部分
system("cls");
//2-2-4 判断胜负 向胜方表示祝贺 和判断是否要结束棋局
//2-2-4-1 判断胜负 并作出相应的反应
for(i=0;i<15;i++)
for(j=0;j<=10;j++)
{
if((a[i][j]=='X'&&a[i][j+1]=='X'&&a[i][j+2]=='X'&&a[i][j+3]=='X'&&a[i][j+4]=='X')||
(a[i][j]=='O'&&a[i][j+1]=='O'&&a[i][j+2]=='O'&&a[i][j+3]=='O'&&a[i][j+4]=='O')||
(a[j][i]=='X'&&a[j+1][i]=='X'&&a[j+2][i]=='X'&&a[j+3][i]=='X'&&a[j+4][i]=='X')||
(a[j][i]=='O'&&a[j+1][i]=='O'&&a[j+2][i]=='O'&&a[j+3][i]=='O'&&a[j+4][i]=='O'))
winOrLose=1;
} //如果存在横纵方向的5个连续的棋子 那么winOrLose变为1 表示已经有玩家胜利
for(i=0;i<=10;i++)
for(j=0;j<=10;j++)
{
if((a[i][j]=='X'&&a[i+1][j+1]=='X'&&a[i+2][j+2]=='X'&&a[i+3][j+3]=='X'&&a[i+4][j+4]=='X')||
(a[i][j]=='O'&&a[i+1][j+1]=='O'&&a[i+2][j+2]=='O'&&a[i+3][j+3]=='O'&&a[i+4][j+4]=='O')||
(a[i][j+4]=='X'&&a[i+1][j+3]=='X'&&a[i+2][j+2]=='X'&&a[i+3][j+1]=='X'&&a[i+4][j]=='X')||
(a[i][j+4]=='O'&&a[i+1][j+3]=='O'&&a[i+2][j+2]=='O'&&a[i+3][j+1]=='O'&&a[i+4][j]=='O'))
winOrLose=1;
} //如果存在斜方向的5个连续的棋子 那么winOrLose变为1 表示已经有玩家胜利
if(winOrLose==1)
{
ifwin=1;
coutboard(blackOrWhite,a);
blackOrWhite=abs(blackOrWhite-1);
winPicture(blackOrWhite);
winOrLose=0;
} //如果经过前面的判断 已经有胜出方 那么ifwin变为1 表示确实有人胜利 可以退出人人对战模式的循环 同时输出棋盘 将blackOrWhite再次转换 变回胜利用户 再调用函数winPicture 表示祝贺 最后 winOrLose返回默认值0
if(n==225)
{
ifwin=1;
coutboard(blackOrWhite,a);
cout<<"势均力敌啊 平局~~~"<<endl;
cout<<"Press Any Key And Enter To Return To The Catalogue: "<<endl;
for(;;)
{
char k;
cin>>k;
if(cin.peek()=='\n')
{
system("cls");
break;
}
}
} //如果n=225 表示已经全部下满了 这就是平局 然后提示用户按任意键和回车来结束循环
//2-2-4-2 有获胜方 或 表示要退出时 结束人人对战模式的棋局 结束循环 回到主菜单
if(ifwin==1)
{
ifwin=0;
break;
}
} //如果ifwin=1 表示前面的操作让游戏达到了需要退出的条件 这时ifwin返回默认值 并break跳出对战循环
selection=0; //跳出对战循环后 selection自动赋值0 表示自动回到主菜单
}
//3 人机对战模式菜单 主菜单中当用户选择2时 赋给selection值2 用if语句判断后 调用函数manVsPC 弹出人机对战模式菜单
if(selection==2)
{
//3-0 准备工作 声明文件输入输出流 用于对每次的棋局进行存储 在再次打开时 可以导入从而达到自动存档和读档的效果
ofstream outfiletwo("manVsPC.txt",ios::app);
if(!outfiletwo)
{
cerr<<"抱歉!您的存档崩溃了~~~"<<endl;
exit(1);
} //打开文件失败提醒
outfiletwo.close(); //声明文件输出流outfiletwo 并让它与文件manVsPC.txt关联 来将棋盘a1[15][15]存到该文件中
ifstream infiletwo("manVsPC.txt");
if(!infiletwo)
{
cerr<<"抱歉!您的存档崩溃了~~~"<<endl;
exit(1);
} //打开文件失败提醒
infiletwo.close(); //声明文件输入流infiletwo 并让它与文件manVsPC.txt关联 来将该文件中的棋盘信息导入到a[15][15]中
ofstream outfiletwo1("player.txt",ios::app);
if(!outfiletwo1)
{
cerr<<"抱歉!您的存档崩溃了~~~"<<endl;
exit(1);
} //打开文件失败提醒
outfiletwo1.close();//声明文件输出流outfiletwo1 并让它与文件player.txt关联 来将用户昵称存到该文件中
ifstream infiletwo1("player.txt");
if(!infiletwo1)
{
cerr<<"抱歉!您的存档崩溃了~~~"<<endl;
exit(1);
} //打开文件失败提醒
infiletwo1.close();//声明文件输入流infiletwo1 并让它与文件player.txt关联 来将该文件中的用户昵称导入到player3中
//3-1 铺棋盘工序 进入人机对战模式后 选择是重新开始 还是继续上次的比赛
choose=manVsPC();
int state=0, state2=0; //state state2分别用于记录人机对战先手和后手中 是否是第一局 从而方便给出提示 0表示是第一局 1表示不是
//3-1-1 选择重新开始后 棋盘置空 并且提醒用户输入昵称 并提示用户选择先手还是后手
if(choose==2)
{
choose2=manVsPC2(); //调用函数manVsPC2 用来给choose2赋值用户的选择
//3-1-1-1 用户选择人机对战模式中重新开始的先手
if(choose2==1)
{
for(i=0;i<15;i++)
for(j=0;j<15;j++)
{
a1[i][j]='.';
}
} //如果选择1 即先手 那么棋盘清空
//3-1-1-2 用户选择人机对战模式中重新开始的后手
if(choose2==2)
{
for(i=0;i<15;i++)
for(j=0;j<15;j++)
{
a1[i][j]='.';
}
a1[7][7]='O'; //计算机下子
} //如果选择2 即后手 那么棋盘清空 计算机默认先下棋盘中心
cout<<"请输入您的昵称(输入“0”使用默认昵称)"<<endl;
cin>>player3;
if(player3=="0") player3="黑棋棋手"; //如果输入0 则使用默认昵称
outfiletwo1.open("player.txt");
outfiletwo1<<player3;
outfiletwo1.close();//打开文件player.txt 将输入的昵称输出到文件中 用于存档 结束后关闭文件
system("cls"); //清屏 以便开始棋局
}
//3-1-2 选择继续 棋盘从文件读入上次的棋盘布局 及昵称 然后开始棋局
if(choose==1) //如果用户选择1 则执行以下操作
{
infiletwo.open("manVsPC.txt");
for(i=0;i<15;i++)
for(j=0;j<15;j++)
{
infiletwo>>a1[i][j];
}
infiletwo.close(); //打开文件manVsPC.txt 将其中每一格的信息导入到a1[15][15]中 结束后关闭文件
infiletwo1.open("player.txt");
infiletwo1>>player3;//打开文件player.txt 将其中的用户的昵称导入到player3中 结束后关闭文件
infiletwo1.close();
ifwin2=0; //让ifwin2=0 表示每次读档时 默认胜负未分 避免上次游戏的影响
}
//3-2 进入人机对战模式的棋局 开始对战
for(n=0;;n++) //for循环用于使对战持续进行下去 直到产生特定条件(胜利、认输……)退出 n表示棋局数
{
//3-2-1 打开每一轮下棋后的棋局 并记录棋局 用于存档
coutboard(blackOrWhite,a1); //调用函数coutboard
outfiletwo.open("manVsPC.txt");
for(i=0;i<15;i++)
for(j=0;j<15;j++)
{
outfiletwo<<a1[i][j]<<" ";
}
outfiletwo.close(); //打开文件manVsPC.txt 将棋盘信息导出到文件里 然后关闭文件
//3-2-2 给出用户提示语 获得下棋命令
for(int tips2;;tips2++) //用for循环来使提示部分当且仅当命令输入有效时退出 否则不停循环
{
//3-2-2-1-1 人机对战模式中 计算机先手
if(choose2==2)
{
if(state2==0&&choose==2)
cout<<"电脑刚刚下在了纵横坐标分别为(7,7)的位置上 它有什么企图?仔细考虑考虑吧~~~~~~"<<endl;
if(state2==1)
cout<<"电脑刚刚下在了纵横坐标分别为("<<iMax+1<<","<<jMax+1<<")的位置上 它有什么企图?仔细考虑考虑吧~~~~~~"<<endl;
state2=1;
} //如果用户选择后手 那么如果这是第一局并且是选择重新开始 那么提示计算机下子坐标为(7,7) 如果不是第一局 则提示上一局计算机下子的坐标
//3-2-2-1-2 人机对战模式中 计算机后手
if(choose2==1)
{
if(state==1)
cout<<"电脑刚刚下在了纵横坐标分别为("<<iMax+1<<","<<jMax+1<<")的位置上 它有什么企图?仔细考虑考虑吧~~~~~~"<<endl;
state=1;
} //如果用户选择先手 那么如果只是第一局 就不显示计算机的下子信息 如果不是第一局 则提示上一局计算机下子的坐标
//3-2-2-2 人机对战模式中 轮到用户下棋
cout<<player3<<" 请输入棋子的纵坐标和横坐标,以空格间隔(输入“0 0”返回主菜单 输入“give up”认输):"; //提示用户下命令
string x,y; //声明字符串变量x y 用于接收用户的命令 用字符串 可以接收用户的错误命令 以方便判断
cin>>x;
cin>>y;
i=atoi(x.c_str());
j=atoi(y.c_str()); //将x y转化为其对应的数字
takeback=0;
if(x=="0"&&y=="0")
{
selection=0;
ifwin2=1;
break;
}//如果输入的是0 0 即用户想要暂时退出对战 则将selection赋值0 表示选择主菜单 将ifwin2赋值1 表示达到退出条件 可以结束循环了 最后break跳出提示循环
else if(x=="give"&&y=="up")
{
winOrLose2=2;
break;
}
else if(x=="take"&&y=="back"&&n!=0)
{
a1[i11-1][j11-1]='.';
a1[iMax][jMax]='.';
takeback=1;
n--;
break;
}//如果该棋轮到黑棋棋手 并且存在上一步 输入的是take back 即用户想要悔棋 那么让上一局用户和计算机的棋子变成‘.’ 棋局数减一 最后break跳出提示循环
else if((x=="1"||x=="2"||x=="3"||x=="4"||x=="5"||x=="6"||x=="7"||x=="8"||x=="9"||x=="10"||x=="11"||x=="12"||x=="13"||x=="14"||x=="15")&&
(y=="1"||y=="2"||y=="3"||y=="4"||y=="5"||y=="6"||y=="7"||y=="8"||y=="9"||y=="10"||y=="11"||y=="12"||y=="13"||y=="14"||y=="15")&&a1[i-1][j-1]=='.')
{
a1[i-1][j-1]='X';
i11=i;
j11=j;
break;
} //当且仅当用户输入的x y是1到15的数字时并且该格是空的 让该格变成'X' 用i11 j11记录此局改变的格子的坐标 最后break跳出提示循环
else if((x=="1"||x=="2"||x=="3"||x=="4"||x=="5"||x=="6"||x=="7"||x=="8"||x=="9"||x=="10"||x=="11"||x=="12"||x=="13"||x=="14"||x=="15")&&
(y=="1"||y=="2"||y=="3"||y=="4"||y=="5"||y=="6"||y=="7"||y=="8"||y=="9"||y=="10"||y=="11"||y=="12"||y=="13"||y=="14"||y=="15")&&a1[i-1][j-1]=='X')
cout<<"别闹了 不要在自己的黑子上下子啊 难道你想制作双层汉堡么? 重新输入吧~~~"<<endl;
else if((x=="1"||x=="2"||x=="3"||x=="4"||x=="5"||x=="6"||x=="7"||x=="8"||x=="9"||x=="10"||x=="11"||x=="12"||x=="13"||x=="14"||x=="15")&&
(y=="1"||y=="2"||y=="3"||y=="4"||y=="5"||y=="6"||y=="7"||y=="8"||y=="9"||y=="10"||y=="11"||y=="12"||y=="13"||y=="14"||y=="15")&&a1[i-1][j-1]=='O')
cout<<"呵呵 做人不要太嚣张 怎么能在白子上下黑子 我会代表月亮 命令你重新输入!"<<endl;
else cout<<"思想有多远 我们就能走多远 但你输入坐标也不能离谱得这么远吧~~请重新输入吧"<<endl;
} //如果输入的坐标上有已有黑棋或已有白棋 或输入无效 那么给出相应的提示语 然后继续循环
//3-2-3 清屏 离开提示部分
system("cls");
//3-2-4 判断用户是否胜利 向用户表示祝贺 和判断是否要结束棋局
//3-2-4-1 判断用户是否胜利 并作出相应的反应
for(i=0;i<15;i++)
for(j=0;j<=10;j++)
{
if((a1[i][j]=='X'&&a1[i][j+1]=='X'&&a1[i][j+2]=='X'&&a1[i][j+3]=='X'&&a1[i][j+4]=='X')||
(a1[j][i]=='X'&&a1[j+1][i]=='X'&&a1[j+2][i]=='X'&&a1[j+3][i]=='X'&&a1[j+4][i]=='X'))
winOrLose2=1;
}//如果存在横纵方向的5个连续的棋子 那么winOrLose2变为1 表示用户胜利
for(i=0;i<=10;i++)
for(j=0;j<=10;j++)
{
if((a1[i][j]=='X'&&a1[i+1][j+1]=='X'&&a1[i+2][j+2]=='X'&&a1[i+3][j+3]=='X'&&a1[i+4][j+4]=='X')||
(a1[i][j+4]=='X'&&a1[i+1][j+3]=='X'&&a1[i+2][j+2]=='X'&&a1[i+3][j+1]=='X'&&a1[i+4][j]=='X'))
winOrLose2=1;
}//如果存在斜方向的5个连续的棋子 那么winOrLose2变为1 表示用户胜利
if(winOrLose2==1)
{
ifwin2=1;
coutboard(blackOrWhite,a1);
winPicture2(player3);
winOrLose2=0;
}//如果经过前面的判断 用户已经胜出 那么ifwin2变为1 表示用户胜利 可以退出人机对战模式的循环 同时输出棋盘 再调用函数winPicture2 表示祝贺 最后 winOrLose2返回默认值0
//3-2-5 轮到计算机下棋 并判断胜负
if(winOrLose2==0&&takeback!=1) //如果用户还没有胜利 并且没有悔棋 则计算机下棋
{
operation(a1,b); //调用函数operation 计算出每格的分数
int i4, j4; //声明整型变量i4 j4 用于表示不断变化的棋盘的纵横坐标
for(i4=0;i4<15;i4++)
for(j4=0;j4<15;j4++)
{
if(a1[i4][j4]=='.')
{
iMax=i4;
jMax=j4;
break; //先找到第一个空格 记录下它的坐标
}
}
for(i4=0;i4<15;i4++)
for(j4=0;j4<15;j4++)
{
if(b[i4][j4]>b[iMax][jMax]&&a1[i4][j4]=='.')
{
iMax=i4;
jMax=j4;
} //对之后的每一格空格与之前记录下的那一个空格进行比较 留下分数最大的格的坐标
}
a1[iMax][jMax]='O'; //在分数最大的格下白棋
}
//3-2-6 判断计算机是否胜利 和判断是否要结束棋局
//3-2-6-1 判断计算机是否胜利 并作出相应的反应
for(i=0;i<15;i++)
for(j=0;j<=10;j++)
{
if((a1[i][j]=='O'&&a1[i][j+1]=='O'&&a1[i][j+2]=='O'&&a1[i][j+3]=='O'&&a1[i][j+4]=='O')||
(a1[j][i]=='O'&&a1[j+1][i]=='O'&&a1[j+2][i]=='O'&&a1[j+3][i]=='O'&&a1[j+4][i]=='O'))
winOrLose2=2;
}//如果存在横纵方向的5个连续的棋子 那么winOrLose2变为2 表示计算机胜利
for(i=0;i<=10;i++)
for(j=0;j<=10;j++)
{
if((a1[i][j]=='O'&&a1[i+1][j+1]=='O'&&a1[i+2][j+2]=='O'&&a1[i+3][j+3]=='O'&&a1[i+4][j+4]=='O')||
(a1[i][j+4]=='O'&&a1[i+1][j+3]=='O'&&a1[i+2][j+2]=='O'&&a1[i+3][j+1]=='O'&&a1[i+4][j]=='O'))
winOrLose2=2;
}//如果存在斜方向的5个连续的棋子 那么winOrLose2变为2 表示计算机胜利
if(winOrLose2==2)
{
ifwin2=1;
coutboard(blackOrWhite,a1);
losePicture();
winOrLose2=0;
} //如果经过前面的判断 如果计算机胜出 那么ifwin2变为1 表示计算机胜利 可以退出人机对战模式的循环 同时输出棋盘 再调用函数losePicture 表示失败 最后 winOrLose2返回默认值0
if(n==113)
{
ifwin2=1;
coutboard(blackOrWhite,a1);
cout<<"势均力敌啊 平局~~~"<<endl;
cout<<"Press Any Key And Enter To Return To The Catalogue: "<<endl;
for(;;)
{
char k;
cin>>k;
if(cin.peek()=='\n')
{
system("cls");
break;
}
}
} //如果n=113 表示已经全部下满了 这就是平局 然后提示用户按任意键和回车来结束循环
//3-2-6-2 有获胜方 或 表示要退出时 结束人机对战模式的棋局 结束循环 回到主菜单
if(ifwin2==1)
{
ifwin2=0;
break;
}//如果ifwin2=1 表示前面的操作让游戏达到了需要退出的条件 这时ifwin2返回默认值 并break跳出对战循环
}
selection=0;//跳出对战循环后 selection自动赋值0 表示自动回到主菜单
}
//3 介绍菜单 主菜单中当用户选择3时 赋给selection值3 用if语句判断后 调用函数introduction 弹出介绍菜单
if(selection==3)
{
introduction();
selection=0; //从介绍菜单退出后 selection自动变为默认值0 返回主菜单
}
//4 小贴士菜单 主菜单中当用户选择4时 赋给selection值4 用if语句判断后 调用函数key 弹出小贴士菜单
if(selection==4)
{
key();
selection=0; //从小贴士菜单退出后 selection自动变为默认值0 返回主菜单
}
//5 退出程序 主菜单中用户选择5时 赋给selection值5 用if语句判断后 直接退出
if(selection==5)
{
exit(0); //直接退出
}
}
return 0; //终于返回
} //主函数终于结束了~~~~~~⊙﹏⊙b汗