[问题描述]
建立一个10*20的矩形方格图,其中有10种不同的图案,每种图案个数为偶数,填满矩形方格图。
[基本要求]
(1)随机产生原始数据;
(2)输入两个位置,如果两者图案相同,并且可以用小于等于3条直线相连,即可消除该两个图案。
[基本思路和代码实现]
图的建立:首先建立如下图所示的矩阵,再将系统时间作为种子将矩阵进行随机打乱,得到最后的连连看地图。
void creat()
{
int row = 10;
int col = 20;
int num = 0;
for (int i = 0; i < row; ++i)
{
for (int j = 0; j < col; ++j)
{
gamedata[i][j] = (num / 2 + 1) % 10;//0到10的建立
++num;
}
}
//print();
//随机打乱数组里面的数据
srand((unsigned)time(NULL)); //使用当前的系统时间作为随机数种子
for (int count = 0; count < (row * col) / 2; ++count)
{
int x1 = rand() % col; //生成 0 -- (col - 1) 的数据
int y1 = rand() % row; //生成 0 -- (row - 1) 的数据
int x2 = rand() % col; //生成 0 -- (col - 1) 的数据
int y2 = rand() % row; //生成 0 -- (row - 1) 的数据
swap(gamedata[y1][x1], gamedata[y2][x2]);
}
//print();
}
相连消除:四种情况
1.一条直线:直接判断是否在同一行或同一列,在判断中间是否有障碍即可。
bool judge_x(int x1, int y1, int x2, int y2)//同行判断
{
if (x1 == x2)
{
int flag = 1;
for (int i = (y1 < y2 ? y1 : y2) + 1; i < (y1 > y2 ? y1 : y2); i++)
{
if (gamedata[x1][i] != -1)
{
flag = 0;
break;
}
}
if (flag == 1)
return true;
}
return false;
}
bool judge_y(int x1, int y1, int x2, int y2)//同列判断
{
if (y1 == y2)
{
int flag = 1;
for (int i = (x1 < x2 ? x1 : x2) + 1; i < (x1 > x2 ? x1 : x2); i++)
{
if (gamedata[i][y1] != -1)
{
flag = 0;
break;
}
}
if (flag == 1)
return true;
}
return false;
}
bool judge_1(int x1, int y1, int x2, int y2)//一条直线判断
{
if (judge_x(x1, y1, x2, y2) == 1 || judge_y(x1, y1, x2, y2) == 1)
{
return true;
}
return false;
}
2.两条直线:两条可能通的道路,各有一个拐点,根据拐点进行两次单条直线联通判断,只要有一个拐点通,则通。这个判断有点长,要是理不过来,画个图就很好理解(我就是这么干的)。
bool judge_2(int x1, int y1, int x2, int y2)//两条直线判断
{
if ((judge_x(x1, y1, x1, y2) == 1 && judge_y(x1, y2, x2, y2) == 1 && gamedata[x1][y2] == -1) || (judge_x(x2, y1, x2, y2) == 1 && judge_y(x1, y1, x2, y1) == 1 && gamedata[x2][y1] == -1))
{
return true;
}
return false;
}
3.三条直线:没想到太好的方法,就直接遍历图,看是否能找到与一个点单条直线相连,与另一点两条直线相连,小数据,也很快。
bool judge_3(int x1, int y1, int x2, int y2)
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 20; j++)
{
if ((i == x1 && j == y1) || i == x2 && j == y2)
continue;
if ((judge_1(x1, y1, i, j) == 1 && judge_2(i, j, x2, y2) == 1) || (judge_2(x1, y1, i, j) == 1 && judge_1(i, j, x2, y2) == 1))
{
return true;
}
}
}
return false;
}
4.再就是消除不了,要么是连不上,要么是数字不同,数字不同提前判断一下就行。
[源代码]
#include<iostream>
#include<iomanip>
using namespace std;
int gamedata[11][21] = { 0 };
typedef pair<int, int>position;
void print()
{
cout << setw(4) << ' ';
for (int i = 0; i < 20; i++)
cout << setw(4) << i;
cout << endl << "--------------------------------------------------------------------------------------------" << endl;
for (int i = 0; i < 10; i++)
{
cout << setw(3) << i << '|';
for (int j = 0; j < 20; ++j)
{
if (gamedata[i][j] != -1)
cout << setw(4) << gamedata[i][j];
else
cout << setw(4) << ' ';
}
cout << endl;
}
}
void creat()
{
int row = 10;
int col = 20;
int num = 0;
for (int i = 0; i < row; ++i)
{
for (int j = 0; j < col; ++j)
{
gamedata[i][j] = (num / 2 + 1) % 10;//0到1的建立
++num;
}
}
//print();
//2.随机打乱数组里面的数据
srand((unsigned)time(NULL)); //使用当前的系统时间作为随机数种子
for (int count = 0; count < (row * col) / 2; ++count)
{
int x1 = rand() % col; //生成 0 -- (col - 1) 的数据
int y1 = rand() % row; //生成 0 -- (row - 1) 的数据
int x2 = rand() % col; //生成 0 -- (col - 1) 的数据
int y2 = rand() % row; //生成 0 -- (row - 1) 的数据
swap(gamedata[y1][x1], gamedata[y2][x2]);
}
//print();
}
bool judge_x(int x1, int y1, int x2, int y2)
{
if (x1 == x2)
{
int flag = 1;
for (int i = (y1 < y2 ? y1 : y2) + 1; i < (y1 > y2 ? y1 : y2); i++)
{
if (gamedata[x1][i] != -1)
{
flag = 0;
break;
}
}
if (flag == 1)
return true;
}
return false;
}
bool judge_y(int x1, int y1, int x2, int y2)
{
if (y1 == y2)
{
int flag = 1;
for (int i = (x1 < x2 ? x1 : x2) + 1; i < (x1 > x2 ? x1 : x2); i++)
{
if (gamedata[i][y1] != -1)
{
flag = 0;
break;
}
}
if (flag == 1)
return true;
}
return false;
}
bool judge_1(int x1, int y1, int x2, int y2)//一条直线判断
{
if (judge_x(x1, y1, x2, y2) == 1 || judge_y(x1, y1, x2, y2) == 1)
{
return true;
}
return false;
}
bool judge_2(int x1, int y1, int x2, int y2)//两条直线判断
{
if ((judge_x(x1, y1, x1, y2) == 1 && judge_y(x1, y2, x2, y2) == 1 && gamedata[x1][y2] == -1) || (judge_x(x2, y1, x2, y2) == 1 && judge_y(x1, y1, x2, y1) == 1 && gamedata[x2][y1] == -1))
{
return true;
}
return false;
}
bool judge_3(int x1, int y1, int x2, int y2)
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 20; j++)
{
if ((i == x1 && j == y1) || i == x2 && j == y2)
continue;
if ((judge_1(x1, y1, i, j) == 1 && judge_2(i, j, x2, y2) == 1) || (judge_2(x1, y1, i, j) == 1 && judge_1(i, j, x2, y2) == 1))
{
return true;
}
}
}
return false;
}
int is_conected(position p1, position p2)
{
int x1 = p1.first;
int x2 = p2.first;
int y1 = p1.second;
int y2 = p2.second;
if (judge_1(x1, y1, x2, y2))
return 1;
if (judge_2(x1, y1, x2, y2))
return 2;
if (judge_3(x1, y1, x2, y2))
return 3;
return -1;
}
void run()
{
int time = 100;
while (time >= 0)
{
position p1;
position p2;
print();
while (1)
{
cout << "输入第一个选择的坐标(eg:1 2):";
cin >> p1.first;
cin >> p1.second;
if (p1.first < 0 || p1.first>10 || p1.second < 0 || p1.second>20)
{
cout << "坐标不合法!!!" << endl;
system("pause");
continue;
}
if (gamedata[p1.first][p1.second] == -1)
{
cout << "该位置已销除!!!" << endl;
system("pause");
continue;
}
break;
}
while (2)
{
cout << "输入第二个选择的坐标(eg:1 2):";
cin >> p2.first;
cin >> p2.second;
if (p2.first < 0 || p2.first>10 || p2.second < 0 || p2.second>20)
{
cout << "坐标不合法!!!" << endl;
system("pause");
continue;
}
if (gamedata[p2.first][p2.second] == -1)
{
cout << "该位置已销除!!!" << endl;
system("pause");
continue;
}
break;
}
if (gamedata[p1.first][p1.second] != gamedata[p2.first][p2.second])
{
cout << "两位置图像不同!!!" << endl;
system("pause");
system("cls");
continue;
}
if (p1.second == p2.second && p1.first == p2.first)
{
cout << "请输入两个不相同的坐标" << endl;
system("pause");
system("cls");
continue;
}
int n = is_conected(p1, p2);
if ( n != -1)
{
gamedata[p1.first][p1.second] = -1;
gamedata[p2.first][p2.second] = -1;
cout << n << "条直线连接" << endl << "消除成功!" << endl;
system("pause");
system("cls");
}
else
{
cout << "连不上!!!" << endl;
system("pause");
system("cls");
}
}
cout << "游戏成功!!!" << endl;
}
int main()
{
creat();
run();
}
[运行结果]
虽然我没有写保障必定有解的程序,但是大概率应该也是有解的,但是我也没消完过,毕竟得消除100次,谁要是消完了可以发我看看。
再就是这个代码连线只能满足图内的连线,不能从图外连线,改起来也简单,扩大一圈就可以了,在此不作过多演示了。