在做这个项目之前就曾经用C++写过五子棋,不过当时只实现了一个简单的人人对战模式,现在又写了5天,虽然已经实现了更多的功能,但仍然有些许BUG,人机还有些智障,但我会继续改进,完善项目
#include<easyx.h>
#include<graphics.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
//注意 项目->属性->配置属性->高级->字符集 要选择使用多字节字符集
int igwide = 641, igwigh = 640;//主界面窗口长宽
int buttw = 215, buttg = 130, butth = 80;//按钮距主界面左间距,上间距,按钮高
int qpw = 898, qph = 894;//棋盘宽和高
//函数声明部分
void playDouble();
void creat_first();
void playAI();
void Drawchess(int, int);
#pragma comment(lib,"Winmm.lib")
struct member {//储存玩家信息的结构体
int step;//战胜AI所用的步数
char name[100];//玩家名称
char qizi[100];//战胜AI所用棋子颜色
}num[101];
int coutall;//当前保存在num数组中的信息个数
int openphbfile(member* a) {//打开排行榜文件读取信息到member数组中,a指向数组第一个元素,返回读取玩家信息的个数
FILE* bs;
if ((bs = fopen("member.dat", "rb")) == NULL) {//使用fopen会有报错C4996,在项目->属性->配置属性->c/c++ ->预处理器中添加定义:_CRT_SECURE_NO_WARNINGS即可解决
bs=fopen("member.dat", "wb");//新建文件
return 0;
}
int count = 1;
while (true) {
if (fread(&a[count], sizeof(member), 1, bs) != 1) {//从文件读数据读入num数组,读完结束
break;
}
count++;
}
for (int i = 1; i <= count - 1; i++) {//给读到的结构体数组排序
for (int p = i + 1; p <= count - 1; p++) {
if (num[i].step > num[p].step) {
member ui = num[i];
num[i] = num[p];
num[p] = ui;
}
}
}
return count - 1;
}
void downphbfile(member* a, int all) {//保存玩家信息保存到排行榜文件,a指向结构体数组第一个元素,all表示玩家总数
FILE* sb;//定义文件指针
if ((sb = fopen("member.dat", "wb")) == NULL) {
printf("File not open!");//提示打开文件失败
return;
}
for (int i = 1; i <= all; i++) {
if (fwrite(&a[i], sizeof(member), 1, sb) != 1) {//一个个写入数据
printf("File write error");//提示写入文件失败
return;
}
}
fclose(sb);//关闭文件
}
struct xy {//记录棋子信息
int x, y;//棋子在Chess数组中的信息
}chessxy[225];
int step;//表示棋盘上棋子总数,数组模拟栈,方便悔棋
int AS;//当前下棋方,-1表示黑方,1表示白方
int Chess[16][16];//记录棋盘标记,0表示为空,-1表示黑棋,1表示白棋
int Chessscore[16][16];//人机对战时计算各点得分
int fx[8] = { 0,1,1,1,0,-1,-1,-1 };
int fy[8] = { 1,1,0,-1,-1,-1,0,1 };//方向数组
void creatchess(int mande, int AIas) {//创建棋盘,mande表示当前模式,mande为1表示当前是人机局,AIas人机执棋色
initgraph(qpw, qph);
IMAGE qp_img;//定义一个图片名
loadimage(&qp_img, "res/qp.jpg", 898, 894);//加载图片,并与qp_img绑定
putimage(0, 0, &qp_img);//插入图片
setbkmode(TRANSPARENT);//设置字体背景模式
settextstyle(20, 0, "楷体");//设置字体
settextcolor(RGB(705, 79, 79));//设置字体颜色
outtextxy(10, 10, "提示:按下鼠标左键落子,按下鼠标右键悔棋,按下鼠标中键返回主菜单");
settextcolor(RGB(0, 275, 70));//设置字体颜色
if (mande == 1) {//是人机局则提示人机局
outtextxy(630, 865, "当前为人机对战,");
settextcolor(RGB(0, 675, 70));//设置字体颜色
if (AIas == 1) {//人机执白棋
outtextxy(780, 865, "人机执白棋");
}
else {//人机执黑棋
outtextxy(780, 865, "人机执黑棋");
}
}
else {
outtextxy(750, 865, "当前为人人对战");
}
settextcolor(RGB(0, 575, 70));//设置字体颜色
if (AS == 1) {//显示当前执子方
outtextxy(10, 865, "执棋方:白方");
}
else {
outtextxy(10, 865, "执棋方:黑方");
}
}
void findpos(double sx, double sy, int* tx, int* ty) {//sx,sy为鼠标方位,tx,ty为在Chess数组中的方位
double m = (sx - 38) / 58.6, n = (sy - 38) / 58.6;
int ad = (int)(m + 0.5), ah = (int)(n + 0.5);
*tx = ad + 1, * ty = ah + 1;
}
void init() {
step = 0;
memset(Chess, 0, sizeof(Chess));//棋盘清0
AS = -1;//默认黑棋先下
}
void mango(int mande, int AIas) {//玩家走棋,mande表示是否是人机模式,AIas表示人机执棋
MOUSEMSG on;//定义鼠标信息状态on
while (1) {//用户输入
on = GetMouseMsg();//输入鼠标信息
int a, b;
findpos(on.x, on.y, &a, &b);
if (on.uMsg == WM_MBUTTONDOWN) {
closegraph();//关闭棋盘
creat_first();
}
if (on.uMsg == WM_LBUTTONDOWN) {//鼠标按下左键
if (Chess[a][b] != 0) {//坐标有子
mciSendString("play res/wuxiao.mp3", 0, 0, 0);
continue;
}
else {
Chess[a][b] = AS;//下子
mciSendString("play res/select.wav", 0, 0, 0);
step++;
AS = -AS;//换执棋方
Drawchess(mande, AIas);//重新绘制
chessxy[step].x = a, chessxy[step].y = b;//记录棋子信息
break;
}
}
if (on.uMsg == WM_RBUTTONDOWN && step > 0) {//鼠标按下右键悔棋
mciSendString("play res/select.wav", 0, 0, 0);
Chess[chessxy[step].x][chessxy[step].y] = 0;//出栈
step--;
AS = -AS;
Drawchess(mande, AIas);//悔棋后绘制棋子
}
}
}
void AIscore(int AIas) {
memset(Chessscore, 0, sizeof(Chessscore));//先清空得分
for (int i = 1; i <= 15; i++) {//正方计算每个点得分
for (int p = 1; p <= 15; p++) {
if (Chess[i][p] == 0) {//是个空白点
int mynum = 0, emptynum = 0;//分别为己方棋子数,空白数
for (int ir = 0; ir < 4; ir++) {//4个方向,包括每个方向的正反方向
for (int ip = 1; ip <= 4; ip++) {//正方向
int tx = ip * fx[ir] + i, ty = ip * fy[ir] + p;
if (tx > 0 && ty > 0 && ty < 16 && tx < 16 && Chess[tx][ty] != -AIas) {//不越界,不被占
if (Chess[tx][ty] == AIas) {//连子
mynum++;
}
else if (Chess[tx][ty] == 0) {//空白子
emptynum++;
break;
}
}
else {
break;
}
}
for (int ip = 1; ip <= 4; ip++) {//正方向
int tx = -ip * fx[ir] + i, ty = -ip * fy[ir] + p;
if (tx > 0 && ty > 0 && ty < 16 && tx < 16 && Chess[tx][ty] != -AIas) {//不越界,不被占
if (Chess[tx][ty] == AIas) {//连子
mynum++;
}
else if (Chess[tx][ty] == 0) {//空白子
emptynum++;
break;
}
}
else {
break;
}
}
if (mynum == 4) {//活5
Chessscore[i][p] += 30000;
}
else {
if (mynum == 3) {
if (emptynum == 2) {//活4
Chessscore[i][p] += 1000;
}
if (emptynum == 1) {//冲4
Chessscore[i][p] += 100;
}
}
if (mynum == 2) {
if (emptynum == 2) {//活3
Chessscore[i][p] += 100;
}
if (emptynum == 1) {//死3
Chessscore[i][p] += 50;
}
}
if (mynum == 1 && emptynum == 2) {//连2
Chessscore[i][p] += 20;
}
}
}
}
}
}
AIas = -AIas;
for (int i = 1; i <= 15; i++) {//以敌方计算每个点得分
for (int p = 1; p <= 15; p++) {
if (Chess[i][p] == 0) {//是个空白点
int mynum = 0, emptynum = 0;//分别为己方棋子数,空白数
for (int ir = 0; ir < 4; ir++) {//4个方向,包括每个方向的正反方向
for (int ip = 1; ip <= 4; ip++) {//正方向
int tx = ip * fx[ir] + i, ty = ip * fy[ir] + p;
if (tx > 0 && ty > 0 && ty < 16 && tx < 16 && Chess[tx][ty] != -AIas) {//不越界,不被占
if (Chess[tx][ty] == AIas) {//连子
mynum++;
}
else if (Chess[tx][ty] == 0) {//空白子
emptynum++;
break;
}
}
else {
break;
}
}
for (int ip = 1; ip <= 4; ip++) {//正方向
int tx = -ip * fx[ir] + i, ty = -ip * fy[ir] + p;
if (tx > 0 && ty > 0 && ty < 16 && tx < 16 && Chess[tx][ty] != -AIas) {//不越界,不被占
if (Chess[tx][ty] == AIas) {//连子
mynum++;
}
else if (Chess[tx][ty] == 0) {//空白子
emptynum++;
break;
}
}
else {
break;
}
}
if (mynum == 4) {//活4
Chessscore[i][p] += 20000;
}
else {
if (mynum == 3) {
if (emptynum == 2) {//活4
Chessscore[i][p] += 20000;
}
if (emptynum == 1) {//冲4
Chessscore[i][p] += 100;
}
}
if (mynum == 2) {
if (emptynum == 2) {//活3
Chessscore[i][p] += 100;
}
if (emptynum == 1) {//死3
Chessscore[i][p] += 50;
}
}
if (mynum == 1 && emptynum == 2) {//连2
Chessscore[i][p] += 20;
}
}
}
}
}
}
}
void AIgo(int as, int* x, int* y) {//人机走棋,as表示人机执子颜色,返回AI选择的落子坐标
AIscore(as);
int max = 0, mx, my;
if (step == 0) {//先手第一次落子
srand((unsigned)time(NULL));//将时间设置为随机数种子
int a = rand() % 10 + 2, b = rand() % 10 + 2;
*x = a, * y = b;
return;
}
int maxnum = 1;//若有相同权值,记录具有相同最大权值的数量
xy temp[235];
for (int i = 1; i <= 15; i++) {
for (int p = 1; p <= 15; p++) {
if (max < Chessscore[i][p]) {
maxnum = 1;
max = Chessscore[i][p];
temp[maxnum].x = i;
temp[maxnum].y = p;
mx = i, my = p;
}
if (max == Chessscore[i][p]) {
maxnum++;
temp[maxnum].x = i;
temp[maxnum].y = p;
}
}
}
if (maxnum > 1) {
srand((unsigned)time(NULL));//将时间设置为随机数种子
int swlect = rand() % maxnum;
while (swlect == 0) {
int y = rand();
swlect = (y * rand() + 1) % maxnum;
}
mx = temp[swlect].x, my = temp[swlect].y;
}
*x = mx, * y = my;
}
int tempscore[16][16];
int endscore[16][16];
void dfsgo(int num, int AIas, int* unmax) {//num表示从原先棋局开始走完了的步数
if (num == 9) {//走完5步,开始计算当前棋局中的得分最大值
AIscore(AIas);//开始记算
int maxnum = 1;//若有相同权值,记录具有相同最大权值的数量
xy temp[235];
int max = 0, mx, my;
for (int i = 1; i <= 15; i++) {
for (int y = 1; y <= 15; y++) {
if (Chessscore[i][y] > max) {
max = Chessscore[i][y];
mx = i, my = y;
}
}
}
*unmax = max;
}
for (int i = 1; i <= 15; i++) {
for (int p = 1; p <= 15; p++) {
if (tempscore[i][p] != 0 && Chess[i][p] == 0) {//找到一个得分不为0空白点
for (int si = 1; si <= 15; si++) {//找到另外一个得分不为0的空白点点
for (int sp = 1; sp <= 15; sp++) {
if (tempscore[si][sp] != 0 && Chess[si][sp] == 0) {
Chess[i][p] = AIas, Chess[i][p] = -AIas;//模拟AI下棋和玩家下棋
if (num == 0) {//记录该种棋局走的第一步坐标以及走该种棋局可以得到的最大分值
int oknum;
dfsgo(num + 1, AIas, &oknum);
if (endscore[i][p] < oknum) {
endscore[i][p] = oknum;
}
}
else {
dfsgo(num + 1, AIas, unmax);
}
Chess[i][p] = 0, Chess[i][p] = 0;
}
}
}
}
}
}
}
void AIdfsgo(int AIas, int* x, int* y) {
if (step == 0) {//先手第一次落子
srand((unsigned)time(NULL));//将时间设置为随机数种子
int a = rand() % 10 + 2, b = rand() % 10 + 2;
*x = a, * y = b;
return;
}
//从当前棋局开始,AI走完5步之后得到各种棋局,将各种棋局棋盘中分值最大点值作为该此棋局的分值
//然后依据各种棋局的得分找出得分最大的棋局,返回这个棋局所下的点
AIscore(AIas);//进行评分初始化
for (int i = 1; i <= 15; i++) {//先把初始得分地图复制到tempscore中
for (int y = 1; y <= 15; y++) {
tempscore[i][y] = Chessscore[i][y];
}
}
memset(endscore, 0, sizeof(endscore));
dfsgo(0, AIas, NULL);
int max = 0, mx = 0, my = 0;
int maxnum = 1;//若有相同权值,记录具有相同最大权值的数量
xy temp[7235];
for (int i = 1; i <= 15; i++) {//找走各点5步之后所能得到的最大分数的点
for (int y = 1; y <= 15; y++) {
if (max < endscore[i][y]) {
max = endscore[i][y];
mx = i, my = y;
maxnum = 1;
}
if (max == endscore[i][y]) {
temp[maxnum].x = i;
temp[maxnum].y = y;
maxnum++;
}
}
}
if (maxnum > 1) {
srand((unsigned)time(NULL));//将时间设置为随机数种子
int swlect = rand() % maxnum;
while (swlect == 0) {
int y = rand();
swlect = (y * rand() + 1) % maxnum;
}
mx = temp[swlect].x, my = temp[swlect].y;
}
*x = mx, * y = my;
}
void AIwingo(int AIas, int* x, int* y) {
}
int fs(int as, int x, int y) {//查找从此(x,y)坐标开始最大连子数
for (int i = 0; i < 8; i++) {//查找8个方向
int tx = x, ty = y;
int po = 0;
while (1) {//往一个方向延伸
tx += fx[i], ty += fy[i];
if (Chess[tx][ty] != as) {
break;
}
po++;
if (po == 4) {//有5个连在一起
return po;
}
}
}
return 0;
}
int findwin(int as) {//查找五子连棋,有5子返回1
for (int i = 1; i <= 15; i++) {
for (int l = 1; l <= 15; l++) {
if (Chess[l][i] == as && fs(as, l, i) == 4) {//是要查找的棋子,查找
return 1;
}
}
}
return 0;
}
int check() {//检查胜负平局,分别返回-1表示黑子胜,1表示白子胜,0表示无胜负方或平局,6表示平局
if (findwin(-1)) {//查看黑子是否胜利
return -1;
}
if (findwin(1)) {//查看白子是否胜利
return 1;
}
if (step == 225) {//棋盘全部下满表示平局
return 6;
}
return 0;//以上情况都不是
}
void shenfu(int as, int mande, int AIas) {//提示胜负平局,as为-1表示黑子胜,为1表示白子胜,0表示平局,mande表示是否是人机局,AIas表示人机执棋色
if (mande == 1) { //是人机局
if (as == AIas) {//人机胜
mciSendString("play res/shibai.mp3", 0, 0, 0);
HWND tip = GetHWnd();
int windo = MessageBox(tip, "您输给了了AI,是否继续下一局?", "胜负已分", MB_OKCANCEL);//弹出窗口,获取信息赋值给windo
if (windo == IDOK) {
init();//棋盘初始化
playAI();
}
else {
closegraph();//关闭棋盘
creat_first();
}
}
else {//玩家胜
mciSendString("play res/shengfu.mp3", 0, 0, 0);
mciSendString("play res/good.mp3", 0, 0, 0);
HWND tip = GetHWnd();
int windo = MessageBox(tip, "您战胜了AI,是否继续下一局?", "胜负已分", MB_OKCANCEL);//弹出窗口,获取信息赋值给windo
if (windo == IDOK) {
init();//棋盘初始化
playAI();
}
else {
closegraph();//关闭棋盘
creat_first();
}
}
}
else {//不是人机局
mciSendString("play res/shengfu.mp3", 0, 0, 0);
mciSendString("play res/good.mp3", 0, 0, 0);
if (as == 1) {
HWND tip = GetHWnd();
int windo = MessageBox(tip, "白棋胜利,是否继续下一局?", "胜负已分", MB_OKCANCEL);//弹出窗口,获取信息赋值给windo
if (windo == IDOK) {
init();//棋盘初始化
playDouble();
}
else {
closegraph();//关闭棋盘
creat_first();
}
}
else {
HWND tip = GetHWnd();
int windo = MessageBox(tip, "黑棋胜利,是否继续下一局?", "胜负已分", MB_OKCANCEL);//弹出窗口,获取信息赋值给windo
if (windo == IDOK) {
init();//棋盘初始化
playDouble();
}
else {
closegraph();//关闭棋盘
creat_first();
}
}
}
}
void Drawchess(int mande, int AIas) {//绘制棋子
BeginBatchDraw();//双缓冲绘图,防止闪屏
cleardevice();
IMAGE qp_img;//定义一个图片名
loadimage(&qp_img, "res/qp.jpg", 898, 894);//加载图片,并与qp_img绑定
putimage(0, 0, &qp_img);//插入图片
double xs = 58.6, pui = 38;//棋子相对方位,用来调整
for (int l = 1; l <= 15; l++) {
for (int i = 1; i <= 15; i++) {
if (Chess[i][l] != 0) {//该坐标有棋子
if (Chess[i][l] == -1) {//是黑子
setfillcolor(BLACK);
fillcircle(pui + (i - 1) * xs, pui + (l - 1) * xs, 21);
}
else {//白子
setfillcolor(WHITE);
fillcircle(pui + (i - 1) * xs, pui + (l - 1) * xs, 21);
}
}
}
}
setbkmode(TRANSPARENT);//设置字体背景模式
settextstyle(20, 0, "楷体");//设置字体
settextcolor(RGB(705, 79, 79));//设置字体颜色
outtextxy(10, 10, "提示:按下鼠标左键落子,按下鼠标右键悔棋,按下鼠标中键返回主菜单");
settextcolor(RGB(0, 275, 70));//设置字体颜色
if (mande == 1) {//是人机局则提示人机局
outtextxy(630, 865, "当前为人机对战,");
settextcolor(RGB(0, 675, 70));//设置字体颜色
if (AIas == 1) {//人机执白棋
outtextxy(780, 865, "人机执白棋");
}
else {//人机执黑棋
outtextxy(780, 865, "人机执黑棋");
}
}
else {
outtextxy(750, 865, "当前为人人对战");
}
settextcolor(RGB(0, 575, 70));//设置字体颜色
if (AS == 1) {//显示当前执子方
outtextxy(10, 865, "执棋方:白方");
}
else {
outtextxy(10, 865, "执棋方:黑方");
}
EndBatchDraw();
}
void playAI() {//人机模式
char name[10];
InputBox(name, 8, "请输入你想要的昵称", "用户注册");
int AIas;//标记人机执棋色
HWND tip = GetHWnd();
int windo = MessageBox(tip, "您是否先手呢", "选择先后手", MB_OKCANCEL);//弹出窗口,获取信息赋值给windo,先手为黑棋
if (windo == IDOK) {//玩家执黑棋,则人机执白棋
AIas = 1;
}
else {
AIas = -1;
}
creatchess(1, AIas);//创建棋盘
mciSendString("play res/start.wav", 0, 0, 0);//播报开始语音
init();//棋盘初始化
while (1) {//游戏内循环
int so = check();// 检查棋盘
if (so == -1) {//黑子胜
if (so == -AIas) {//玩家胜利
coutall++;
strcpy(num[coutall].name, name);
if (AIas == 1) {//人机执白棋
strcpy(num[coutall].qizi, "黑棋");//玩家用黑棋战胜
}
else {
strcpy(num[coutall].qizi, "白棋");//玩家用白棋战胜
}
num[coutall].step = step;
downphbfile(&num[1], coutall);//保存玩家信息
}
shenfu(-1, 1, AIas);//提示黑子胜利
break;
}
if (so == 1) {//白子胜
if (so == -AIas) {//玩家胜利
coutall++;
strcpy(num[coutall].name, name);
if (AIas == 1) {//人机执白棋
strcpy(num[coutall].qizi, "黑棋");//玩家用黑棋战胜
}
else {
strcpy(num[coutall].qizi, "白棋");//玩家用白棋战胜
}
num[coutall].step = step;
downphbfile(&num[1], coutall);
}
shenfu(1, 1, AIas);//提示白子胜利
break;
}
if (AIas != AS) {//玩家下棋或悔棋
mango(1, AIas);
}
else {//人机下棋
int AX, AY;
//AIgo(AIas, &AX, &AY);//得到人机要下子的坐标
AIdfsgo(AIas, &AX, &AY);
Chess[AX][AY] = AIas;//下子
step++;
AS = -AS;
Drawchess(1, AIas);//重新绘制
mciSendString("play res/select.wav", 0, 0, 0);
chessxy[step].x = AX, chessxy[step].y = AY;
}
}
}
void playDouble() {//双人模式
creatchess(0, 0);//创建棋盘
mciSendString("play res/start.wav", 0, 0, 0);//播报开始语音
init();//棋盘初始化
while (1) {//游戏内循环
int so = check();//检查棋盘
if (so == -1) {//黑子胜
shenfu(-1, 0, 0);//提示黑子胜利
break;
}
if (so == 1) {//白子胜
shenfu(1, 0, 0);//提示白子胜利
break;
}
if (so == 6) {//平局
shenfu(0, 0, 0);//提示平局
break;
}
mango(0, 0);
}
}
void go_ranklist() {
coutall = openphbfile(num + 1);//打开玩家信息文件,方便排行榜操作
initgraph(650, 938);
IMAGE f_b_img;//定义一个图片名
loadimage(&f_b_img, "res/phb.jpg", 650, 938);//加载图片,并与f_b_img绑定
putimage(0, 0, &f_b_img);
setbkmode(TRANSPARENT);//设置字体背景模式
settextstyle(25, 0, "正体");//设置字体
setlinestyle(PS_SOLID, 3);//设置选项边框为实线,宽度为1像素
setfillcolor(RGB(287, 178, 6));
setlinecolor(RED);//设置线条颜色
fillrectangle(48, 196, 108, 226);// 边框
settextcolor(YELLOW);//设置字体颜色
outtextxy(53, 200, "战胜");
setfillcolor(BLUE);
setlinecolor(RED);//设置线条颜色
fillrectangle(542, 196, 582, 226);// 边框
settextcolor(YELLOW);//设置字体颜色
outtextxy(549, 200, "AI");
settextcolor(RGB(105, 79, 59));//设置字体颜色
outtextxy(58, 256, "排名");
settextcolor(RGB(105, 79, 59));//设置字体颜色
outtextxy(196, 256, "玩家昵称");
settextcolor(RGB(105, 79, 59));//设置字体颜色
outtextxy(381, 256, "棋子");
settextcolor(RGB(105, 79, 59));//设置字体颜色
outtextxy(505, 256, "所用步数");
setcolor(RGB(255, 0, 0));//设置线条颜色
line(45, 285, 615, 285);
for (int i = 1; i <= 10; i++) {//绘制10条线,已及排名
if (i % 2 == 0) {
setcolor(RGB(83, 60, 233));
settextcolor(RGB(34, 216, 94));
}
else {
setcolor(RGB(34, 216, 94));
settextcolor(RGB(83, 60, 233));
}
line(48, 340 + (i - 1) * 60, 610, 340 + (i - 1) * 60);
if (i <= coutall) {
char bb[5];
sprintf(bb, "%d", num[i].step);//将整形step转换成字符串
outtextxy(217, 311 + (i - 1) * 60, num[i].name);
outtextxy(382, 311 + (i - 1) * 60, num[i].qizi);
outtextxy(520, 311 + (i - 1) * 60, bb);
}
else {
outtextxy(217, 311 + (i - 1) * 60, "xxxx");
outtextxy(382, 311 + (i - 1) * 60, "xxxx");
outtextxy(520, 311 + (i - 1) * 60, "xxxx");
}
outtextxy(52, 311 + (i - 1) * 60, "第 名:");
char bb[5];
sprintf(bb, "%d", i);//将整形i转换成字符串
if (i <= 3) {
settextcolor(RED);//设置字体颜色
}
else {
settextcolor(BLACK);//设置字体颜色
}
outtextxy(80, 311 + (i - 1) * 60, bb);
}
settextcolor(RED);//设置字体颜色绿色
outtextxy(58, 891, "按鼠标右键返回主菜单");
MOUSEMSG jk = GetMouseMsg();//定义鼠标信息状态jk
while (1) {
jk = GetMouseMsg();//获取鼠标信息
if (jk.uMsg == WM_RBUTTONDOWN) {//鼠标按下左键
closegraph();
creat_first();
break;
}
}
}
void creat_first() {//进入主界面
coutall = openphbfile(num + 1);//打开玩家信息文件,方便排行榜操作
initgraph(igwide, igwigh);//打开界面
IMAGE f_b_img;//定义一个图片名
loadimage(&f_b_img, "res/menue.jpg", 666, 664);//加载图片,并与f_b_img绑定
putimage(0, 0, &f_b_img);//插入图片
setlinestyle(PS_SOLID, 2);//设置选项边框为实线,宽度为1像素
setfillcolor(RGB(187, 128, 96));
setlinecolor(RED);//设置线条颜色
fillrectangle(buttw, buttg, igwide - buttw, butth + buttg);
buttg += 100;
fillrectangle(buttw, buttg, igwide - buttw, butth + buttg);
buttg += 110;
fillrectangle(buttw, buttg, igwide - buttw, butth + buttg);
buttg += 120;
fillrectangle(buttw, buttg, igwide - buttw, butth + buttg);//设置三个主菜单选项边框
buttg -= 330;
setbkmode(TRANSPARENT);//设置字体背景模式
settextstyle(50, 0, "正体");//设置字体
settextcolor(RGB(105, 79, 59));//设置字体颜色
outtextxy(248, 144, "排行榜");
outtextxy(218, 240, "双人模式");
outtextxy(218, 350, "单人模式");
outtextxy(218, 475, "结束游戏");
MOUSEMSG first;//定义鼠标信息状态first
while (1) {
first = GetMouseMsg();//输入鼠标信息
if (first.uMsg == WM_LBUTTONDOWN) {//鼠标按下左键
if (first.x > buttw && first.x <igwide - buttw && first.y > buttg && first.y < buttg + butth) {
mciSendString("play res/select.wav", 0, 0, 0);
go_ranklist();//查看排行榜
break;
}
buttg += 100;
if (first.x > buttw && first.x <igwide - buttw && first.y > buttg && first.y < buttg + butth) {
mciSendString("play res/select.wav", 0, 0, 0);
buttg -= 100;
playDouble();//双人模式
break;
}
buttg += 110;
if (first.x > buttw && first.x <igwide - buttw && first.y > buttg && first.y < buttg + butth) {
mciSendString("play res/select.wav", 0, 0, 0);
buttg -= 210;
playAI();//单人模式
break;
}
buttg += 120;
if (first.x > buttw && first.x <igwide - buttw && first.y > buttg && first.y < buttg + butth) {
mciSendString("play res/select.wav", 0, 0, 0);
buttg -= 330;
closegraph();//结束游戏
break;
}
buttg -= 330;
}
}
system("pause");
}
int main() {
mciSendString("open res/bg.mp3 alias f_b_m", 0, 0, 0);//加载音乐文件,并将其命名f_b_m
mciSendString("play f_b_m repeat", 0, 0, 0);//重复播放音乐
creat_first();
closegraph();
return 0;
}
五子棋项目C++整合资源下载:
链接:https://pan.baidu.com/s/1-0GZjZKqbuOr7c1c2nLmUQ?pwd=6766
提取码:6766
有很多不足,欢迎大佬指正