您的位置:首页 > 理论基础 > 数据结构算法

数据结构课程设计--连连看

2015-12-31 09:11 369 查看
/*
* Copyright (c)2015,烟台大学计算机与控制工程学院
* All rights reserved.
* 文件名称:linktolink.cbp
* 作    者:朱希康
* 完成日期:2015年12月31日
* 版 本 号:v1.0
* 问题描述:实现简单连连看小游戏
* 程序输出:需要连接的字母、等级选择等等
*/


#define KEY_UP 0xE048
#define KEY_DOWN 0xE050
#define KEY_LEFT 0xE04B
#define KEY_RIGHT 0xE04D
#define KEY_ESC 0x001B
#define KEY_1 '1'
#define KEY_2 '2'
#include <iostream>
#include <algorithm>
#include <vector>
#include <time.h>
#include <cstdlib>
#include <math.h>
#include <iomanip>
#include <windows.h>
#include <conio.h>
#include <String>
#include <fstream>
using namespace std;
int m,n,_sum,curX,curY,LeftTimes,difficult,diff=0;
string user;
vector<vector<char> > ve;
void bigger(int &x1, int &x2);
void bigger(int &x1,int &y1,int &x2,int &y2);
bool check_x(int y1,int y2,int x1);
bool check_y(int x1,int x2,int y1);
int left_ray(int x,int y);
int up_ray(int x,int y);
int right_ray(int x,int y);
int down_ray(int x,int y);
bool scan_ver(int beg,int end,int y1,int y2);
bool scan_hor(int beg,int end,int x1,int x2);
bool check_hor(int x1,int y1,int x2,int y2);
bool check_ver(int x1,int y1,int x2,int y2);
bool check(int x1, int y1, int x2, int y2);
int _random(int range); //参数为范围
char random_letter(vector<char> &a);
void even_number_letters(char letter, vector<char> &a);
void output(const vector<vector<char> > &a);
void assign(const vector<char> &a, vector<vector<char> > &b);
void add_frame(vector<vector<char> > &a);
void reshuffle(vector<vector<char> > &a);
int GetKey();
void initialize(int dif); //选择难度
void game_end(int start);
void LLKGame();
void reshuffle(vector<vector<char> > &a);
int GotoXY(int x, int y);
//保证t1>t2,交换return true
void bigger(int &x1, int &x2)
{
if (x1 >= x2)
return;
else
{
int t;
t = x1;
x1 = x2;
x2 = t;
return;
}
}

void bigger(int &x1, int &y1, int &x2, int &y2)
{
if (x1 >= x2)
return;
else
{
int t, q;
t = x1;
q = y1;
x1 = x2;
y1 = y2;
y2 = q;
x2 = t;
return;
}
}
//横向检测和纵向检测
bool check_x(int y1, int y2, int x1)
{
int _y1(y1), _y2(y2);
bigger(_y1, _y2);
bool flag = true;
for (int i = _y2 + 1; i < _y1; i++)
{
if (ve[i][x1] != ' ')
{
flag = false;
break;
}
}
return flag;
}
bool check_y(int x1, int x2, int y1)
{
int _x1(x1), _x2(x2);
bigger(_x1, _x2);
bool flag = true;
for (int i = _x2 + 1; i < _x1; i++)
{
if (ve[y1][i] != ' ')
{
flag = false;
break;
}
}
return flag;
}
//向左发出的射线,返回障碍物与元素的间距
int left_ray(int x, int y)
{
if (check_y(x, 0, y))
return x + 1;
for (int i = 1; i <= x - 1; i++)
{
if (check_y(x, i, y))
return x - i;
}
cout << "DANGER!" << endl;
return -1;
}
<pre name="code" class="html">//向上发出的射线,返回障碍物与元素的间距
int up_ray(int x, int y){if (check_x(y, 0, x))return y + 1;for (int i = 1; i <= y - 1; i++){if (check_x(y, i, x))return y - i;}cout << "DANGER!" << endl;return -1;}

<pre name="code" class="html">//向右发出的射线,返回障碍物与元素的间距
int right_ray(int x, int y){if (check_y(x, ve[0].size() - 1, y))return ve[0].size() - x;for (int i = ve[0].size() - 2; i >= x + 1; i--){if (check_y(x, i, y))return i - x;}cout << "DANGER!" << endl;return -1;}

<pre name="code" class="html">//向下发出的射线,返回障碍物与元素的间距
int down_ray(int x, int y){if (check_x(y, ve.size() - 1, x))return ve.size() - y;for (int i = ve.size() - 2; i >= y + 1; i--){if (check_x(y, i, x))return i - y;}cout << "DANGER!" << endl;return -1;}bool scan_ver(int beg, int end, int y1, int
y2){if (beg < end){for (int i = beg; i <= end; i++){if (check_x(y1, y2, i))return true;}}else{for (int i = beg; i >= end; i--){if (check_x(y1, y2, i))return true;}}return false;}bool scan_hor(int beg, int end, int x1, int x2){if (beg < end){for (int i = beg;
i <= end; i++){if (check_y(x1, x2, i))return true;}}else{for (int i = beg; i >= end; i--){if (check_y(x1, x2, i))return true;}}return false;}bool check_hor(int x1, int y1, int x2, int y2){//horizontalbigger(y1, x1, y2, x2);//0 1 2 3// 2 0// 1// 2//1 3////0
1 2 3//2 0// 1// 2// 1 3// up_outint t1 = y1 - up_ray(x1, y1), t2 = y2 - up_ray(x2, y2);bigger(t1, t2);if (t1 < y2 - 1){if (scan_hor(y2 - 1, t1 + 1, x1, x2))return true;}// down_outt1 = y1 + down_ray(x1, y1), t2 = y2 + down_ray(x2, y2);bigger(t1, t2);if (t2>y1
+ 1){if (scan_hor(y1 + 1, t2 - 1, x1, x2))return true;}// hor_int1 = up_ray(x1, y1), t2 = down_ray(x2, y2);if ((t1 + t2) > (y1 - y2 + 1)){if ((t1 <= y1 - y2) && (t2 <= y1 - y2)){if (scan_hor(y2 + t2 - 1, y1 - t1 + 1, x1, x2))return true;}else if ((t1>y1 -
y2 || t2>y1 - y2) && !(t1>y1 - y2 && t2>y1 - y2)){if (t1 > t2&&y1 > y2){if (scan_hor(y2 + t2 - 1, y2 + 1, x1, x2))return true;}else if (t1 < t2&&y1 > y2){if (scan_hor(y1 - 1, y1 - t1 + 1, x1, x2))return true;}}else{if (scan_hor(y1, y2, x1, x2))return true;}}return
false;}bool check_ver(int x1, int y1, int x2, int y2){//verticalbigger(x1, y1, x2, y2);//0 1 2 3// 1 0// 1// 2//2 3////0 1 2 3//2 0// 1// 2// 1 3// left_outint t1 = x1 - left_ray(x1, y1), t2 = x2 - left_ray(x2, y2);bigger(t1, t2);if (t1 < x2 - 1) //障碍物中较大者比元素x位置较小者大,则无法形成左外连{if
(scan_ver(x2 - 1, t1 + 1, y1, y2))return true;}// right_outt1 = x1 + right_ray(x1, y1), t2 = x2 + right_ray(x2, y2);bigger(t1, t2);if (t2 > x1 + 1){if (scan_ver(x1 + 1, t2 - 1, y1, y2))return true;}// ver_int1 = left_ray(x1, y1), t2 = right_ray(x2, y2);if
((t1 + t2) > (x1 - x2 + 1)){if ((t1 <= x1 - x2) && (t2 <= x1 - x2)){if (scan_ver(x2 + t2 - 1, x1 - t1 + 1, y1, y2))return true;}else if ((t1>x1 - x2 || t2>x1 - x2) && !(t1>x1 - x2 && t2>x1 - x2)){if (t1 > t2&&x1 > x2){if (scan_ver(x2 + t2 - 1, x2 + 1, y1,
y2))return true;}else if (t1 < t2&&x1 > x2){if (scan_ver(x1 - 1, x1 - t1 + 1, y1, y2))return true;}else{if (scan_ver(x1, x2, y1, y2))return true;}}}return false;}bool check(int x1, int y1, int x2, int y2){if (ve[y1][x1] != ve[y2][x2] || (x1 == x2&&y1 == y2)
|| ve[y1][x1] == ' ' || ve[y2][x2] == ' ')return false;if ((x1 == x2 + 1 && y1 == y2) || (x1 == x2 - 1 && y1 == y2) || (x1 == x2&&y2 == y1 - 1) || (x1 == x2&&y2 == y1 + 1))return true;return (check_hor(x1, y1, x2, y2) || check_ver(x1, y1, x2, y2));}int _random(int
range)//参数为范围{return rand() % range;}//返回一个随机字母,且与ve内原有字母不重复char random_letter(vector<char> &a){char ch = _random(26) + 65;vector<char>::iterator it;for (it = a.begin(); it != a.end(); it++) //迭代器到末尾之前{if (*it == ch) //防止产生相同的字母{ch = _random(26) + 65;}}return
ch;}//在ve末端加入随机偶数个的lettervoid even_number_letters(char letter, vector<char> &a){int max = (int)ceil(sqrt(_sum)) + diff, ran = 0; //设定随机字母的最大重复次数,可以用来设定难度,重复次数越多难度越小ran = _random(max);ran < 3 ? ran = 1 : ran -= 2;int _rest = _sum - a.size();if (_rest < ran
* 2) //ve剩余空间太小,不能完成随机个数要求的重复次数{for (int i = 0; i != _rest; i++){a.push_back(letter);}}else{for (int i = 0; i < ran * 2; i++){a.push_back(letter);}}}////用不到的一维vector输出//void output(vector<char> &a)//{// vector<char>::iterator it;// for (it = a.begin(); it
!= a.end(); it++) //用迭代器的方式输出容器对象的值// {// cout << *it;// }// cout << endl;//}void output(const vector<vector<char> > &a){vector<vector<char> >::const_iterator it_1;vector<char>::const_iterator it_2;for (it_1 = a.begin(); it_1 != a.end(); ++it_1){for (it_2
= it_1->begin(); it_2 != it_1->end(); it_2++){cout << setw(3) << *it_2;}cout << endl;}cout << endl << "你有:" << LeftTimes << "次重置机会" << endl;}void assign(const vector<char> &a, vector<vector<char> > &b){vector<char>::const_iterator it = a.begin(); //C++11中用auto
m=a.begin();即可vector<vector<char> >::iterator it_1;for (it_1 = b.begin(); it_1 != b.end(); it_1++){for (int i = 0; i < n&&it != a.end(); i++){it_1->push_back(*it);it++;}}}void add_frame(vector<vector<char> > &a){vector<vector<char> >::iterator it;for (it =
a.begin(); it < a.end(); it++){it->insert(it->begin(), ' ');it->insert(it->end(), ' ');}vector<char> b(a[0].size(), ' ');a.insert(a.begin(), b);a.insert(a.end(), b);}void reshuffle(vector<vector<char> > &a);int GotoXY(int x, int y){COORD cd;cd.X = x; cd.Y
= y;return SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cd);}int GetKey(){int nkey = _getch(), nk = 0;if (nkey >= 128 || nkey == 0)nk = _getch();return nk > 0 ? nkey * 256 + nk : nkey;}void initialize(int dif) //选择难度{if (dif == 1) { m = 4; n =
4; LeftTimes = 3; diff = 2; }if (dif == 2) { m = 4; n = 5; LeftTimes = 1; diff = 1; }if (dif == 3) { m = 5; n = 6; LeftTimes = 2; diff = 0; }if (dif == 4) { m = 8; n = 8; LeftTimes = 2; diff = 0; }if (dif == 5) { m = 12; n = 12; LeftTimes = 2; diff = -1; }}void
game_end(int start);void LLKGame();int main(){//剩下来任务//遇到空格 自动保留有字母的那个//颜色突出//替换字符//重整代码//自定义功能//继续寻找BUGcout << " Welcome to LLKGame! " << endl<< " 请输入用户名 " << endl<< " 按1选定元素,按2重新打乱排序 " << endl;cin >> user;cout << "***********************************************************"
<< endl<< " 请选择难度! " << endl<< " So easy —— 1 " << endl<< " Easy —— 2 " << endl<< " Normal —— 3 " << endl<< " Hard —— 4 " << endl<< " So Hard —— 5 " << endl;cin >> difficult;initialize(difficult);curX = 5;curY = 1;_sum = (m*n % 2 == 0) ? m*n : m*n - 1;//偶数,_sum=sum;奇数_sum=sum-1;vector<char>
p;srand((unsigned)time(NULL));for (; (int)p.size() < _sum;){even_number_letters(random_letter(p), p);}random_shuffle(p.begin(), p.end());if (m*n % 2 != 0) { p.push_back(' '); }ve.resize(m);assign(p, ve);add_frame(ve);system("cls");output(ve);GotoXY(curX, curY);int
start = clock();LLKGame();game_end(start);system("pause");return 0;}void LLKGame(){int x1, x2, y1, y2;for (int i = 0; i < _sum / 2;){bool boo1 = false, boo2 = false;do{int nKey = GetKey();switch (nKey){case KEY_UP:{ if (curY > 1) GotoXY(curX, --curY);}break;case
KEY_DOWN:{ if (curY < m) GotoXY(curX, ++curY);}break;case KEY_LEFT:{ if (curX > 7) GotoXY(curX -= 3, curY);}break;case KEY_RIGHT:{ if (curX < 3 * n + 2) GotoXY(curX += 3, curY);}break;case KEY_1:{ if (boo1 == false) { x1 = (int)(curX - 2) / 3; y1 = curY; boo1
= true; } else { x2 = (int)(curX - 2) / 3; y2 = curY; boo2 = true; }}break;case KEY_2:{ reshuffle(ve); system("cls"); output(ve); continue;}}} while (!(boo1&&boo2));if (check(x1, y1, x2, y2)){ve[y1][x1] = ' ';ve[y2][x2] = ' ';i++;}system("cls");output(ve);}}void
game_end(int start){int finish = clock();double duration = (double)(finish - start) / CLOCKS_PER_SEC;string Name;string allname[6];double Time;double alltime[6];int rank = 0;if (difficult == 1) //简单 存储文件{ifstream out;out.open("LLK_Level_1.txt", ios::in);while
(out >> Name >> Time){ //文件中信息导入到数组里allname[rank] = Name;alltime[rank] = Time;if (rank<5)rank++;elsebreak;}out.close();allname[5] = user; //本轮玩家信息alltime[5] = duration;string t2;double t1;for (int j = 0; j<5; j++){ //冒泡排序法for (rank = 0; rank<5 - j; rank++){if
(alltime[rank]>alltime[rank + 1]){t1 = alltime[rank];alltime[rank] = alltime[rank + 1];alltime[rank + 1] = t1;t2 = allname[rank];allname[rank] = allname[rank + 1];allname[rank + 1] = t2;}}}ofstream file;file.open("LLK_Level_1.txt", ios::out);for (rank = 0;
rank<5; rank++) //将前五名玩家信息存储到文件中{cout << allname[rank] << " " << rank + 1 << " " << alltime[rank] << endl;file << allname[rank] << " " << alltime[rank] << endl;}file.close();}if (difficult == 2) //简单 存储文件{ifstream out;out.open("LLK_Level_2.txt", ios::in);while
(out >> Name >> Time){ //文件中信息导入到数组里allname[rank] = Name;alltime[rank] = Time;if (rank<5)rank++;elsebreak;}out.close();allname[5] = user; //本轮玩家信息alltime[5] = duration;string t2;double t1;for (int j = 0; j<5; j++){ //冒泡排序法for (rank = 0; rank<5 - j; rank++){if
(alltime[rank]>alltime[rank + 1]){t1 = alltime[rank];alltime[rank] = alltime[rank + 1];alltime[rank + 1] = t1;t2 = allname[rank];allname[rank] = allname[rank + 1];allname[rank + 1] = t2;}}}ofstream file;file.open("LLK_Level_2.txt", ios::out);for (rank = 0;
rank<5; rank++) //将前五名玩家信息存储到文件中{cout << allname[rank] << " " << rank + 1 << " " << alltime[rank] << endl;file << allname[rank] << " " << alltime[rank] << endl;}file.close();}if (difficult == 3) //简单 存储文件{ifstream out;out.open("LLK_Level_3.txt", ios::in);while
(out >> Name >> Time){ //文件中信息导入到数组里allname[rank] = Name;alltime[rank] = Time;if (rank<5)rank++;elsebreak;}out.close();allname[5] = user; //本轮玩家信息alltime[5] = duration;string t2;double t1;for (int j = 0; j<5; j++){ //冒泡排序法for (rank = 0; rank<5 - j; rank++){if
(alltime[rank]>alltime[rank + 1]){t1 = alltime[rank];alltime[rank] = alltime[rank + 1];alltime[rank + 1] = t1;t2 = allname[rank];allname[rank] = allname[rank + 1];allname[rank + 1] = t2;}}}ofstream file;file.open("LLK_Level_3.txt", ios::out);for (rank = 0;
rank<5; rank++) //将前五名玩家信息存储到文件中{cout << allname[rank] << " " << rank + 1 << " " << alltime[rank] << endl;file << allname[rank] << " " << alltime[rank] << endl;}file.close();}if (difficult == 4) //简单 存储文件{ifstream out;out.open("LLK_Level_4.txt", ios::in);while
(out >> Name >> Time){ //文件中信息导入到数组里allname[rank] = Name;alltime[rank] = Time;if (rank<5)rank++;elsebreak;}out.close();allname[5] = user; //本轮玩家信息alltime[5] = duration;string t2;double t1;for (int j = 0; j<5; j++){ //冒泡排序法for (rank = 0; rank<5 - j; rank++){if
(alltime[rank]>alltime[rank + 1]){t1 = alltime[rank];alltime[rank] = alltime[rank + 1];alltime[rank + 1] = t1;t2 = allname[rank];allname[rank] = allname[rank + 1];allname[rank + 1] = t2;}}}ofstream file;file.open("LLK_Level_4.txt", ios::out);for (rank = 0;
rank<5; rank++) //将前五名玩家信息存储到文件中{cout << allname[rank] << " " << rank + 1 << " " << alltime[rank] << endl;file << allname[rank] << " " << alltime[rank] << endl;}file.close();}if (difficult == 5) //简单 存储文件{ifstream out;out.open("LLK_Level_5.txt", ios::in);while
(out >> Name >> Time){ //文件中信息导入到数组里allname[rank] = Name;alltime[rank] = Time;if (rank<5)rank++;elsebreak;}out.close();allname[5] = user; //本轮玩家信息alltime[5] = duration;string t2;double t1;for (int j = 0; j<5; j++){ //冒泡排序法for (rank = 0; rank<5 - j; rank++){if
(alltime[rank]>alltime[rank + 1]){t1 = alltime[rank];alltime[rank] = alltime[rank + 1];alltime[rank + 1] = t1;t2 = allname[rank];allname[rank] = allname[rank + 1];allname[rank + 1] = t2;}}}ofstream file;file.open("LLK_Level_5.txt", ios::out);for (rank = 0;
rank<5; rank++) //将前五名玩家信息存储到文件中{cout << allname[rank] << " " << rank + 1 << " " << alltime[rank] << endl;file << allname[rank] << " " << alltime[rank] << endl;}file.close();}}void reshuffle(vector<vector<char> > &a){if (LeftTimes == 0)return;vector<char>
b;vector<vector<char> >::iterator it_1;vector<char>::iterator it_2;for (it_1 = a.begin(); it_1 != a.end(); ++it_1){for (it_2 = it_1->begin(); it_2 != it_1->end(); it_2++){if (*it_2 != ' ')b.push_back(*it_2);}}random_shuffle(b.begin(), b.end());for (it_1 =
a.begin(); it_1 != a.end(); ++it_1){for (it_2 = it_1->begin(); it_2 != it_1->end(); it_2++){if (*it_2 != ' '){*it_2 = b.back();b.pop_back();}}}LeftTimes--;}

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构