#include<windows.h>
#include<stdlib.h>
#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<time.h>
#define len 15
int chessmessage[len][len];
int worb = 2;
int count = 0;
int m;
void star_print(); //打印游戏开始函数
void movegb(char key); //光标的移动
void renjiboyi(); //人机博弈
void shuangrenboyi(); //双人博弈
void initial(); //初始化棋盘数据
void borad_print(); //打印棋盘数据
int chessjudge(int x, int y); //判断能否下子
int chessjudgewin(int x, int y, int worb); //判断输赢
int chesscomputer(); //电脑下棋
int chessscore(int x, int y, int worb); //棋盘权值函数
void print(int m);
struct zuobiao
{
int x;
int y;
}weizhi = { 7, 9 };
void gotoxy(int x, int y) //建立坐标函数
{
COORD c;
c.X = x;
c.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
}
void star_print()
{
printf("\n\n\n\n\n");
printf(" ********************* 【五子棋】 *******************\n\n\n");
printf(" *********************【游戏说明】 ******************\n");
printf(" \n");
printf(" 【1】: 黑子由机器使用 \n");
printf(" -------------------------------------------------\n");
printf(" 【2】: 白子由人使用 \n");
printf(" \n");
printf(" ****************************************************\n");
printf("\n\n 【人机博弈按:1】 【双人博弈按:2】 【退出按:Esc】");
}
void borad_print()
{
int i, j, k;
print(m);
for (j = 0; j<len; j++)
{
for (i = 0; i<len; i++)
{
if (chessmessage[j][i] == 1)
printf("●");
else if (chessmessage[j][i] == 2)
printf("○");
else if (j == 0 && i == 0)
printf("┏");
else if (j == 0 && i == len - 1)
printf("┓");
else if (j == len - 1 && i == 0)
printf("┗");
else if (j == len - 1 && i == len - 1)
printf("┛");
else if (j == 0 && i != 0 && i != len - 1)
printf("┯");
else if (j != 0 && j != len - 1 && i == 0)
printf("┠");
else if (j != 0 && j != len - 1 && i == len - 1)
printf("┨");
else if (j == len - 1 && i != 0 && i != len - 1)
printf("┷");
else if (j != 0 && j != len - 1 && i != 0 && i != len - 1)
printf("┼");
if (j>0 && j<len - 1 && i<len - 1)
printf("—");
if (j == 0 && i != len - 1)
printf("━");
else if (j == len - 1 && i != len - 1)
printf("━");
}
printf("\n");
if (j >= 0 && j<len - 1)
{
for (k = 0; k<len; k++)
{
if (k == 0 || k == len - 1)
printf("┃ ");
else printf("│ ");
}
if (j == 2)
printf(" 【 操作 - PS 】");
if (j == 4)
printf(" 【 从玩按:n 】");
if (j == 5)
printf(" 【返回按:Backspace】");
if (j == 6)
printf(" 【退出按:Esc】");
if(j == 7)
printf(" 【 空格下子 】");
if(j == 8)
printf(" 【上,下,左,右】");
if(j == 9)
printf(" 【 移动光标 】");
}
printf("\n");
}
}
void print(int x)
{
if (x == 1)
printf("\n\n 【五子棋--人机博弈】\n\n\n");
else printf("\n\n 【五子棋--双人博弈】\n\n\n");
}
void movegb(char key)/*光标的移动*/
{
switch (key)
{
case 0x48:if (weizhi.y>1)weizhi.y--; if (weizhi.y<2)weizhi.y = len + 1; break;
/*光标向上移动*/
case 0x50:if (weizhi.y<len + 2)weizhi.y++; if (weizhi.y>len + 1)weizhi.y = 2; break;
/*光标向下移动*/
case 0x4B:if (weizhi.x>-1)weizhi.x--; if (weizhi.x<0)weizhi.x = len - 1; break;
/*光标向左移动*/
case 0x4D:if (weizhi.x<len)weizhi.x++; if (weizhi.x>len - 1)weizhi.x = 0; break;
/*光标向右移动*/
}
gotoxy(4 * weizhi.x, 2 * weizhi.y);
}
void initial()
{
int i, j;
for (j = 0; j<len; j++) //重置对局数据
{
for (i = 0; i<len; i++)
{
chessmessage[i][j] = 0;
}
}
worb = 2;
count = 0;
system("cls");
borad_print();
weizhi.x = 50;
weizhi.y = 50;
gotoxy(weizhi.x, weizhi.y);
}
int chessjudge(int x, int y)
{
if (chessmessage[x][y] != 0)
return 1;
return 0;
}
int chessjudgewin(int x, int y, int worb)
{
int row, col, count;
row = x, col = y; count = 0;
while (chessmessage[row][col] == worb && col < len)
{
count++;
col++;
}
col = y - 1;
while (chessmessage[row][col] == worb && col >= 0)
{
count++;
col--;
}
if (count >= 5)
return 1;
row = x, col = y; count = 0;
while (chessmessage[row][col] == worb && row < len)
{
count++;
row++;
}
row = x - 1;
while (chessmessage[row][col] == worb && row >= 0)
{
count++;
row--;
}
if (count >= 5)
return 1;
row = x, col = y; count = 0;
while (chessmessage[row][col] == worb && col < len && row < len)
{
count++;
col++;
row++;
}
col = y - 1, row = x - 1;
while (chessmessage[row][col] == worb && col >= 0 && row >= 0)
{
count++;
col--;
row--;
}
if (count >= 5)
return 1;
row = x, col = y; count = 0;
while (chessmessage[row][col] == worb && col < len && row >= 0)
{
count++;
col++;
row--;
}
col = y - 1, row = x + 1;
while (chessmessage[row][col] == worb && col >= 0 && row < len)
{
count++;
col--;
row++;
}
if (count >= 5)
return 1;
return 0;
}
int chesscomputer()
{
int i, j, cscore, cscorel, pscore, pscorel, row1, col1, row2, col2, x, y;
cscore = pscore = 0; row1 = row2 = col1 = col2 = 0;
if (count == 1)
{
srand((unsigned)time(NULL));
row1 = rand() % 15;
col1 = rand() % 15;
count++;
while (chessjudge(row1, col1))
{
row1 = rand() % 15;
col1 = rand() % 15;
}
chessmessage[row1][col1] = 1;
worb = 3 - worb;
x = abs(weizhi.x - col1);
y = abs(weizhi.y - 2 - row1);
if (weizhi.x - col1>0)
for (i = 0; i < x; i++)
movegb(0x4B);
else for (i = 0; i < x; i++)
movegb(0x4D);
if (weizhi.y - 2 - row1>0)
for (i = 0; i < y; i++)
movegb(0x48);
else for (i = 0; i < y; i++)
movegb(0x50);
printf("●");
}
else
{
for (i = 0; i < len; i++)
{
for (j = 0; j < len; j++)
{
if (!chessjudge(i, j))
{
cscorel = chessscore(i, j, 1);
if (cscorel > cscore)
{
cscore = cscorel;
row1 = i;
col1 = j;
}
pscorel = chessscore(i, j, 2);
if (pscorel > pscore)
{
pscore = pscorel;
row2 = i;
col2 = j;
}
}
}
}
if (count == 3)
{
chessmessage[row1][col1] = 1;
worb = 3 - worb;
count++;
x = abs(weizhi.x - col1);
y = abs(weizhi.y - 2 - row1);
if (weizhi.x - col1>0)
for (i = 0; i < x; i++)
movegb(0x4B);
else for (i = 0; i < x; i++)
movegb(0x4D);
if (weizhi.y - 2 - row1>0)
for (i = 0; i < y; i++)
movegb(0x48);
else for (i = 0; i < y; i++)
movegb(0x50);
printf("●");
}
else{
if (cscore >= pscore)
{
chessmessage[row1][col1] = 1;
worb = 3 - worb;
count++;
x = abs(weizhi.x - col1);
y = abs(weizhi.y - 2 - row1);
if (weizhi.x - col1>0)
for (i = 0; i < x; i++)
movegb(0x4B);
else for (i = 0; i < x; i++)
movegb(0x4D);
if (weizhi.y - 2 - row1>0)
for (i = 0; i < y; i++)
movegb(0x48);
else for (i = 0; i < y; i++)
movegb(0x50);
printf("●");
if (chessjudgewin(row1, col1, 1))
{
gotoxy(22, 17);
printf("【 黑子胜利 】");
return 1;
}
}
else
{
chessmessage[row2][col2] = 1;
worb = 3 - worb;
count++;
x = abs(weizhi.x - col2);
y = abs(weizhi.y - 2 - row2);
if (weizhi.x - col2>0)
for (i = 0; i < x; i++)
movegb(0x4B);
else for (i = 0; i < x; i++)
movegb(0x4D);
if (weizhi.y - 2 - row2>0)
for (i = 0; i < y; i++)
movegb(0x48);
else for (i = 0; i < y; i++)
movegb(0x50);
printf("●");
if (chessjudgewin(row2, col2, 1))
{
gotoxy(22, 17);
printf("【 黑子胜利 】");
return 1;
}
}
}
}
return 0;
}
int chessscore(int x, int y, int worb) //棋盘权值函数
{
int count3, count4, sumscore = 0;
char u, d, l, r, lu, ld, ru, rd; //u上 d下 l左 r右 lu左斜上 ld左斜下 ru右斜上 rd右斜下
int row, col, count1, count2; //1表示横向 2表示竖向 3表示斜上方向 4表示斜下方向
count1 = count2 = count3 = count4 = 1;
l = r = u = d = lu = ld = ru = rd = 0;
chessmessage[x][y] = worb; //模拟下棋
/*---------------------------------------①判断横向棋子并记录空格子---------------------------*/
row = x, col = y + 1;
while (chessmessage[row][col] == worb && col < len)
{
count1++;
col++;
}
while (col < len && chessmessage[row][col] == 0)
{
r++;
col++;
}
row = x, col = y - 1;
while (chessmessage[row][col] == worb && col >= 0)
{
count1++;
col--;
}
while (col >= 0 && chessmessage[row][col] == 0)
{
l++;
col--;
}
/*------------------------------------------------------------------------------------------*/
/*-------------------------------------②判断竖向棋子并记录空格子---------------------------*/
row = x + 1, col = y;
while (chessmessage[row][col] == worb && row < len)
{
count2++;
row++;
}
while (row < len && chessmessage[row][col] == 0)
{
d++;
row++;
}
row = x - 1, col = y;
while (chessmessage[row][col] == worb && row >= 0)
{
count2++;
row--;
}
while (row >= 0 && chessmessage[row][col] == 0)
{
u++;
row--;
}
/*------------------------------------------------------------------------------------------*/
/*------------------------------------③判断斜上向棋子并记录空格子--------------------------*/
row = x - 1, col = y + 1;
while (chessmessage[row][col] == worb && col < len && row >= 0)
{
count3++;
col++;
row--;
}
while (col < len && row >= 0 && chessmessage[row][col] == 0)
{
ru++;
col++;
row--;
}
row = x + 1, col = y - 1;
while (chessmessage[row][col] == worb && col >= 0 && row < len)
{
count3++;
col--;
row++;
}
while (col >= 0 && row < len && chessmessage[row][col] == 0)
{
ld++;
col--;
row++;
}
/*------------------------------------------------------------------------------------------*/
/*-----------------------------------④判断斜下向棋子并记录空格子---------------------------*/
row = x + 1, col = y + 1;
while (chessmessage[row][col] == worb && col < len && row < len)
{
count4++;
col++;
row++;
}
while (col < len && row < len && chessmessage[row][col] == 0)
{
rd++;
col++;
row++;
}
row = x - 1, col = y - 1;
while (chessmessage[row][col] == worb && col >= 0 && row >= 0)
{
count4++;
col--;
row--;
}
while (col >= 0 && row >= 0 && chessmessage[row][col] == 0)
{
lu++;
col--;
row--;
}
/*------------------------------------------------------------------------------------------*/
chessmessage[x][y] = 0;
if (count1 >= 5 || count2 >= 5 || count3 >= 5 || count4 >= 5) //判断五子
{
return sumscore = 5000000;
}
if ((count1 == 4 && count2 == 4 && l >= 1 && r >= 1 && u >= 1 && d >= 1) ||
(count1 == 4 && count3 == 4 && l >= 1 && r >= 1 && ru >= 1 && ld >= 1) ||
(count1 == 4 && count4 == 4 && l >= 1 && r >= 1 && rd >= 1 && lu >= 1) ||
(count2 == 4 && count3 == 4 && u >= 1 && d >= 1 && ru >= 1 && ld >= 1) ||
(count2 == 4 && count4 == 4 && u >= 1 && d >= 1 && lu >= 1 && rd >= 1) ||
(count3 == 4 && count4 == 4 && ru >= 1 && ld >= 1 && lu >= 1 && rd >= 1)) //判断双活四
{
return sumscore = 4000000;
}
if ((count1 == 4 && l >= 1 && r >= 1) || (count2 == 4 && u >= 1 && d >= 1) ||
(count3 == 4 && ru >= 1 && ld >= 1) || (count4 == 4 && lu >= 1 && rd >= 1)) //判断活四
{
return sumscore = 800000;
}
if ((count1 == 4 && ((l == 0 && r >= 1) || (l >= 1 && r == 0))) || (count2 == 4 && ((u == 0 && d >= 1) || (u >= 1 && d == 0))) ||
(count3 == 4 && ((ld == 0 && ru >= 1) || (ld >= 1 && ru == 0))) || (count4 == 4 && ((lu == 0 && rd >= 1) || (lu >= 1 && rd == 0))))
{
sumscore = sumscore + 35000; //成四
}
if( ( count1 == 3 && count2 == 3 && l >=1 && r >=1 && u >=1 && d >=1) ||
( count1 == 3 && count3 == 3 && l >=1 && r >=1 && ru >=1 && ld >=1 ) ||
( count1 == 3 && count4 == 3 && l >=1 && r >=1 && rd >=1 && lu >=1 ) ||
( count2 == 3 && count3 == 3 && u >=1 && d >=1 && ru >=1 && ld >=1 ) ||
( count2 == 3 && count4 == 3 && u >=1 && d >=1 && lu >=1 && rd >=1 ) ||
( count3 == 3 && count4 == 3 && ru >=1 && ld >=1 && lu >=1 && rd >=1) ) //判断双活三
{
return sumscore + 400000;
}
if ((count1 == 3 && l >= 1 && r >= 1) || (count2 == 3 && u >= 1 && d >= 1) ||
(count3 == 3 && ru >= 1 && ld >= 1) || (count4 == 3 && lu >= 1 && rd >= 1))
{
sumscore = sumscore + 60000;
return sumscore;
} //判断活三
if ((count1 == 2 && count2 == 2 && l >= 1 && r >= 1 && u >= 1 && d >= 1) ||
(count1 == 2 && count3 == 2 && l >= 1 && r >= 1 && ru >= 1 && ld >= 1) ||
(count1 == 2 && count4 == 2 && l >= 1 && r >= 1 && rd >= 1 && lu >= 1) ||
(count2 == 2 && count3 == 2 && u >= 1 && d >= 1 && ru >= 1 && ld >= 1) ||
(count2 == 2 && count4 == 2 && u >= 1 && d >= 1 && lu >= 1 && rd >= 1) ||
(count3 == 2 && count4 == 2 && ru >= 1 && ld >= 1 && lu >= 1 && rd >= 1))
{
sumscore = sumscore + 20000; //判断双活二
}
if ((count1 == 2 && l >= 1 && r >= 1) || (count2 == 2 && u >= 1 && d >= 1) ||
(count3 == 2 && ru >= 1 && ld >= 1) || (count4 == 2 && lu >= 1 && rd >= 1))
{
sumscore = sumscore + 10000; //单活二
}
return sumscore;
}
void renjiboyi()
{
int c = 0,w = 0;
char key;
m = 1;
while (1)
{
initial();
w = 0;
while (1)
{
key = _getch();
if(w == 0)
{
weizhi.x = 7;
weizhi.y = 9;
gotoxy(weizhi.x, weizhi.y);
w++;
}
if (key == 27) //退出游戏
{
exit(0);
}
else if (key == 8) //返回主界面
{
break;
}
else if (key == 110) //重新玩
{
break;
}
else if (key == 32)
{
if (count == len * len)
{
gotoxy(22, 13);
printf("【 平局 】");
count = 0;
break;
}
else if (worb == 2)
{
if (chessjudge(weizhi.y - 2, weizhi.x) == 0)
{
printf("○");
chessmessage[weizhi.y - 2][weizhi.x] = worb;
count++;
if (chessjudgewin(weizhi.y - 2, weizhi.x, worb))
{
gotoxy(22, 15);
printf("【 白子胜利 】");
key = _getch();
while(key != 27 && key != 110 && key != 8)
key = _getch();
if(key == 8 || key == 110)
break;
else exit(0);
}
else
{
worb = 3 - worb;
c = chesscomputer();
if(c)
{
key = _getch();
while(key != 27 && key != 110 && key != 8)
{
key = _getch();
}
if(key == 8 || key == 110)
break;
else exit(0);
}
}
}
}
}
else //光标移动
{
key = _getch();
movegb(key);
}
}
if (key == 8)
break;
}
}
void shuangrenboyi()
{
int w = 0;
char key;
m = 2;
while(1)
{
initial();
w = 0;
while(1)
{
key = _getch();
if(w == 0)
{
weizhi.x = 7;
weizhi.y = 9;
gotoxy(weizhi.x, weizhi.y);
w++;
}
if (key == 27) //退出游戏
{
exit(0);
}
else if (key == 8) //返回主界面
{
break;
}
else if (key == 110) //重新玩
{
break;
}
else if(key == 32)
{
if(worb == 2)
{
if(chessjudge(weizhi.y-2,weizhi.x) == 0)
{
chessmessage[weizhi.y-2][weizhi.x] = 2;
printf("○");
count++;
if(chessjudgewin(weizhi.y-2,weizhi.x,worb))
{
gotoxy(22, 15);
printf("【 白子胜利 】");
key = _getch();
while(key != 27 && key != 110 && key != 8)
key = _getch();
if(key == 8 || key == 110)
break;
else exit(0);
}
worb = 3 - worb;
}
}
else
{
if(chessjudge(weizhi.y-2,weizhi.x) == 0)
{
chessmessage[weizhi.y-2][weizhi.x] = 1;
printf("●");
count++;
if(chessjudgewin(weizhi.y-2,weizhi.x,worb))
{
gotoxy(22, 15);
printf("【 黑子胜利 】");
key = _getch();
while(key != 27 && key != 110 && key != 8)
key = _getch();
if(key == 8 || key == 110)
break;
else exit(0);
}
worb = 3 - worb;
}
}
}
else
{
key = _getch();
movegb(key);
}
}
if (key == 8)
break;
}
}
int main()
{
int choice = 0;
system("title 【五子棋】 --- [14003101班-冉云杰] 制作");
system("color f2");
system("mode con cols=83 lines=35");
while (1)
{
star_print();
printf("\n\n\n 【请输入你的选择】:");
while (1)
{
choice = _getch();
if (choice == 27)
{
exit(0);
}
else if (choice == 49) //人机博弈
{
renjiboyi();
break;
}
else if (choice == 50) //双人博弈
{
shuangrenboyi();
break;
}
}
system("cls");
}
return 0;
}