井字棋人机对弈的实现
以3*3的二维数组存放棋盘,输入两个数字表示要下的位置,然后人机对弈;
1.划分模块
(1). 输出模块
(2).判断模块
(3).电脑下棋模块
(4).主函数
2.简单思路介绍
输出棋盘的操作都带着清屏 打印 (cls、print);
判断就返回两个值表示是否即可,这些都不是重点;
重点是这里,人机博弈:首先有个优先度,
第一: 要赢;
第二:在实在不能赢的情况下,不能输,最多为平局;
第三:如果以上都没有,就随机下;
3.代码实现及详细思路
就按源代码中的顺序写了,思路自己对应一下吧。
1.去光标
// 去光标
void qgb ()
{
HANDLE handle = GetStdHandle (STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo (handle, &CursorInfo);
CursorInfo.bVisible = false;
SetConsoleCursorInfo (handle, &CursorInfo);
}
2.判断所选位置是否可以下子
// 判断所选位置是否可下 不可下返回-1 可以下返回0
int IsNULL (int array[3][3], int x, int y)
{
if (array[x][y] == 0) return 0;
return -1;
}
3.打印棋盘
// 打印棋盘
void Print (int array[3][3])
{
system("cls");
int i, j;
printf ("\n\n\t井 字 棋\n");
for (i = 0; i < 3; i ++)
{
printf ("\n\t+-+-+-+\n\t|");
for (j = 0; j < 3; j ++)
{
if (array[i][j] == 0) printf(" ");
if (array[i][j] == 1) printf("X");
if (array[i][j] == -1) printf("O");
printf("|");
}
}
printf ("\n\t+-+-+-+\n\n");
}
4.电脑下棋部分
其一考虑赢,即有一线有两个自己的棋子,则优先放在第三个的位置。
其二考虑不输,即不然对方赢,一条线上有两个对方棋子,则下在第三个位置堵住。
其三随机下。
重点:一定要按该思路的顺序 先考虑赢,再考虑不输,最后考虑随机,即使你分 横竖撇捺的位置来实现的,最后也得等赢的情况全部考虑完在考虑其他情况,我刚开始就傻逼了。
代码:
// 电脑下子
int GO (int array[3][3])
{
int i, t;
int k;
for (i = 0; i < 3; i ++)
{
t = array[i][0] + array[i][1] + array[i][2];
if (t == -2)
{
for (k = 0; k < 3; k ++)
{
if (array[i][k] == 0)
{
array[i][k] = -1;
return 0;
}
}
}
}
for (i = 0; i < 3; i ++)
{
t = array[0][i] + array[1][i] + array[2][i];
if (t == -2)
{
for (k = 0; k < 3; k ++)
{
if (array[k][i] == 0)
{
array[k][i] = -1;
return 0;
}
}
}
}
int j = 0; t = 0;
for (i = 0; i < 3; i ++)
{
j += array[i][i];
t += array[i][2-i];
}
if (t == -2)
{
for (k = 0; k < 3; k ++)
{
if (array[k][2-k] == 0)
{
array[k][2-k] = -1;
return 0;
}
}
}
if (j == -2)
{
for (k = 0; k < 3; k ++)
{
if (array[k][k] == 0)
{
array[k][k] = -1;
return 0;
}
}
}
for (i = 0; i < 3; i ++)
{
t = array[i][0] + array[i][1] + array[i][2];
if (t == 2)
{
for (k = 0; k < 3; k ++)
{
if (array[i][k] == 0)
{
array[i][k] = -1;
return 0;
}
}
}
}
for (i = 0; i < 3; i ++)
{
t = array[0][i] + array[1][i] + array[2][i];
if (t == 2)
{
for (k = 0; k < 3; k ++)
{
if (array[k][i] == 0)
{
array[k][i] = -1;
return 0;
}
}
}
}
j = 0; t = 0;
for (i = 0; i < 3; i ++)
{
j += array[i][i];
t += array[i][2-i];
}
if (t == 2)
{
for (k = 0; k < 3; k ++)
{
if (array[k][2-k] == 0)
{
array[k][2-k] = -1;
return 0;
}
}
}
if (j == 2)
{
for (k = 0; k < 3; k ++)
{
if (array[k][k] == 0)
{
array[k][k] = -1;
return 0;
}
}
}
while (1)
{
srand (time (0));
i = rand () % 3;
j = rand () % 3;
if (IsNULL (array, i, j) == 0)
{
array[i][j] = -1;
break;
}
}
return 0;
}
5.检查胜负情况
代码:
// 平局返回0;正方胜返回1;负反胜利返回-1;否则返回6;
int Check (int array[3][3])
{
int i, t;
for (i = 0; i < 3; i ++)
{
t = array[i][0] + array[i][1] + array[i][2];
if (t == -3) return -1;
if (t == 3) return 1;
}
for (i = 0; i < 3; i ++)
{
t = array[0][i] + array[1][i] + array[2][i];
if (t == -3) return -1;
if (t == 3) return 1;
}
int j = 0; t = 0;
for (i = 0; i < 3; i ++)
{
j += array[i][i];
t += array[i][2-i];
}
if (t == -3 || j == -3) return -1;
if (t == 3 || j == 3) return 1;
for (i = 0; i < 3; i ++)
{
for (j = 0; j < 3; j ++)
{
if (array[i][j] == 0) return 6;
}
}
return 0;
}
6.我另外加的一个 集Check 和Print 一起的函数,用来输出结果;
代码:
int CP (int array[3][3])
{
int t = Check (array);
Print (array);
if (t == 0)
{
printf ("\t 平局!");
system ("pause");
return 0;
}
if (t == 1)
{
printf ("\t 恭喜你 赢了! ");
system ("pause");
return 0;
}
if (t == -1)
{
printf ("\t 很抱歉 输了! ");
system ("pause");
return 0;
}
return -1;
}
7.主函数
代码:
int main ()
{
system ("title 井字棋小游戏--BY:nanshao_zz");
qgb ();
int array[3][3];
memset (array, 0, sizeof (array));
Print (array);
int x, y, t;
while (1)
{
scanf ("%d %d", &x, &y);
x --;
y --;
if (x > 2 || y > 2 || x < 0 || y < 0)
{
printf("\t输入范围: 1-3! ");
continue;
}
if (IsNULL (array, x, y) == -1)
{
printf ("所选位置已存在! ");
continue;
}
array[x][y] = 1;
t = CP (array);
if (t == 0) return 0;
GO (array);
t = CP (array);
if (t == 0) return 0;
}
return 0;
}
全部代码:
#include "algorithm"
#include "windows.h"
#include "iostream"
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
#include "vector"
#include "math.h"
#include "time.h"
#include "string"
#include "map"
using namespace std;
// 去光标
void qgb ()
{
HANDLE handle = GetStdHandle (STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo (handle, &CursorInfo);
CursorInfo.bVisible = false;
SetConsoleCursorInfo (handle, &CursorInfo);
}
// 判断所选位置是否可下 不可下返回-1 可以下返回0
int IsNULL (int array[3][3], int x, int y)
{
if (array[x][y] == 0) return 0;
return -1;
}
// 打印棋盘
void Print (int array[3][3])
{
system("cls");
int i, j;
printf ("\n\n\t井 字 棋\n");
for (i = 0; i < 3; i ++)
{
printf ("\n\t+-+-+-+\n\t|");
for (j = 0; j < 3; j ++)
{
if (array[i][j] == 0) printf(" ");
if (array[i][j] == 1) printf("X");
if (array[i][j] == -1) printf("O");
printf("|");
}
}
printf ("\n\t+-+-+-+\n\n");
}
// 电脑下子
int GO (int array[3][3])
{
int i, t;
int k;
for (i = 0; i < 3; i ++)
{
t = array[i][0] + array[i][1] + array[i][2];
if (t == -2)
{
for (k = 0; k < 3; k ++)
{
if (array[i][k] == 0)
{
array[i][k] = -1;
return 0;
}
}
}
}
for (i = 0; i < 3; i ++)
{
t = array[0][i] + array[1][i] + array[2][i];
if (t == -2)
{
for (k = 0; k < 3; k ++)
{
if (array[k][i] == 0)
{
array[k][i] = -1;
return 0;
}
}
}
}
int j = 0; t = 0;
for (i = 0; i < 3; i ++)
{
j += array[i][i];
t += array[i][2-i];
}
if (t == -2)
{
for (k = 0; k < 3; k ++)
{
if (array[k][2-k] == 0)
{
array[k][2-k] = -1;
return 0;
}
}
}
if (j == -2)
{
for (k = 0; k < 3; k ++)
{
if (array[k][k] == 0)
{
array[k][k] = -1;
return 0;
}
}
}
for (i = 0; i < 3; i ++)
{
t = array[i][0] + array[i][1] + array[i][2];
if (t == 2)
{
for (k = 0; k < 3; k ++)
{
if (array[i][k] == 0)
{
array[i][k] = -1;
return 0;
}
}
}
}
for (i = 0; i < 3; i ++)
{
t = array[0][i] + array[1][i] + array[2][i];
if (t == 2)
{
for (k = 0; k < 3; k ++)
{
if (array[k][i] == 0)
{
array[k][i] = -1;
return 0;
}
}
}
}
j = 0; t = 0;
for (i = 0; i < 3; i ++)
{
j += array[i][i];
t += array[i][2-i];
}
if (t == 2)
{
for (k = 0; k < 3; k ++)
{
if (array[k][2-k] == 0)
{
array[k][2-k] = -1;
return 0;
}
}
}
if (j == 2)
{
for (k = 0; k < 3; k ++)
{
if (array[k][k] == 0)
{
array[k][k] = -1;
return 0;
}
}
}
while (1)
{
srand (time (0));
i = rand () % 3;
j = rand () % 3;
if (IsNULL (array, i, j) == 0)
{
array[i][j] = -1;
break;
}
}
return 0;
}
// 平局返回0;正方胜返回1;负反胜利返回-1;否则返回6;
int Check (int array[3][3])
{
int i, t;
for (i = 0; i < 3; i ++)
{
t = array[i][0] + array[i][1] + array[i][2];
if (t == -3) return -1;
if (t == 3) return 1;
}
for (i = 0; i < 3; i ++)
{
t = array[0][i] + array[1][i] + array[2][i];
if (t == -3) return -1;
if (t == 3) return 1;
}
int j = 0; t = 0;
for (i = 0; i < 3; i ++)
{
j += array[i][i];
t += array[i][2-i];
}
if (t == -3 || j == -3) return -1;
if (t == 3 || j == 3) return 1;
for (i = 0; i < 3; i ++)
{
for (j = 0; j < 3; j ++)
{
if (array[i][j] == 0) return 6;
}
}
return 0;
}
int CP (int array[3][3])
{
int t = Check (array);
Print (array);
if (t == 0)
{
printf ("\t 平局!");
system ("pause");
return 0;
}
if (t == 1)
{
printf ("\t 恭喜你 赢了! ");
system ("pause");
return 0;
}
if (t == -1)
{
printf ("\t 很抱歉 输了! ");
system ("pause");
return 0;
}
return -1;
}
int main ()
{
system ("title 井字棋小游戏--BY:nanshao_zz");
qgb ();
int array[3][3];
memset (array, 0, sizeof (array));
Print (array);
int x, y, t;
while (1)
{
scanf ("%d %d", &x, &y);
x --;
y --;
if (x > 2 || y > 2 || x < 0 || y < 0)
{
printf("\t输入范围: 1-3! ");
continue;
}
if (IsNULL (array, x, y) == -1)
{
printf ("所选位置已存在! ");
continue;
}
array[x][y] = 1;
t = CP (array);
if (t == 0) return 0;
GO (array);
t = CP (array);
if (t == 0) return 0;
}
return 0;
}
希望可以帮到正在学这个的你,欢迎批评指正!