You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

823 lines
25 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include<iostream>
#include<graphics.h>
#include"MyGraph.h"
#include<cmath>
#include<stack>
#include<fstream>
#include<string>
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<io.h>
#include"Function.h"
#include"Stack.h"
#include"MessageBox.h"
#include"Account.h"
#define WIDTH (915 + (LEFTBORDER * 2))
#define HEIGHT (722 + TOPBORDER + LEFTBORDER)
#define UP 72
#define DOWN 80
#define BACKGROUND "seu map.png"
#define BKCOLOR RGB(240, 240, 240)
#define SELECTCOLOR RGB(255, 0, 0)
#define TEXTCOLOR RGB(7, 102, 198)
#define MENUCOLOR (208, 161, 227)
#define CheckCancel if(is_cancel) {return -1;}
int choose;
Graph_List graph;
Account account;
const int menu_num = 11;
int menu_top1 = 10;
int menu_top = menu_top + 3;
#define left (LEFTBORDER)
// 设置界面高度和宽度
int menu_width = ((WIDTH - 2 * LEFTBORDER) / (menu_num));
int menu_height = 30;
EasyTextBox txt_name;
EasyTextBox txt_password;
EasyButton btnOK;
int get_choose();
int front_menu(Graph_List & graph); // 界面
int show_all_vertex(Graph_List & graph); // 显示所有节点
int show_all_path(Graph_List & graph); // 显示所有路径
// 显示路径
int printroad(int dx, int dy, int sx, int sy) {
LINESTYLE linestyle; // 定义线的样式
getlinestyle(&linestyle);
setlinestyle(PS_SOLID, 3, NULL, 0);
line(sx, sy, dx, dy);
setlinestyle(&linestyle);
double x1 = (sx + dx) / 2;
double y1 = (sy + dy) / 2;
double x2 = ((3.0 / 8.0) * sx + (5.0 / 8.0) * dx);
double y2 = ((3.0 / 8.0) * sy + (5.0 / 8.0) * dy);
double k1 = (y2 - y1) / (x2 - x1);
double k2 = (-1) / k1;
double delta = 1600;
double a = sqrt((delta / 16) / (1 + k2 * k2));
double b = a * fabs(k2);
if (((x1 > x2) && (y1 < y2)) || ((x1 < x2) && (y1 > y2))) {
}
else b = -1 * b;
if (x1 == x2) {
a = 5;
b = 0;
}
if (y1 == y2) {
a = 0;
b = 3;
}
// 坐标
POINT pts[] = { {x1, y1}, {x2 + a, y2 + b}, {(x1 + x2) / 2, (y1 + y2) / 2} };
POINT pts1[] = { {x1, y1}, {x2 * 2 - (x2 + a), y2 * 2 - (y2 + b)}, {(x1 + x2) / 2, (y1 + y2) / 2} };
setfillcolor(BLUE);
solidpolygon(pts1, 3); // 画填充的多边形(无边框)
solidpolygon(pts, 3);
return 0;
}
// 获取鼠标位置
int get_mouse_xy(int& mousex, int& mousey) {
MOUSEMSG temp;
temp.mkLButton = false; // 鼠标左键是否按下
bool kick = false;
while (!kick) {
temp = GetMouseMsg();
FlushMouseMsgBuffer();
if (temp.mkLButton == false) {
mousex = temp.x;
mousey = temp.y;
}
else kick = temp.mkLButton;
}
return 0;
}
// 添加景点
int add_vertex(Graph_List& graph) {
LOGFONT font;
gettextstyle(&font);
settextstyle(10, 0, _T("宋体"));
BeginBatchDraw();
setlinecolor(GREEN);
for (int lx = LEFTBORDER; lx <= WIDTH; lx += 50) {
line(lx, TOPBORDER, lx, HEIGHT - LEFTBORDER);
}
for (int ly = TOPBORDER; ly <= HEIGHT - LEFTBORDER; ly += 50) {
line(LEFTBORDER, ly, WIDTH - LEFTBORDER, ly);
}
FlushBatchDraw();
setlinecolor(MENUCOLOR);
settextstyle(&font);
// 弹出窗口
::MessageBox(GetHWnd(), (LPCSTR)"请点击您要添加景点的位置", (LPCTSTR)"添加景点", MB_OK);
int mousex, mousey;
get_mouse_xy(mousex, mousey);
char name[30];
bool is_cancel = false;
// 获取用户输入
is_cancel = !InputBox((LPTSTR)name, 30, (LPCTSTR)"输入名称", (LPCTSTR)"添加景点", (LPCTSTR)"0", 0, 0, 0);
CheckCancel;
char description[1000];
is_cancel = !InputBox((LPTSTR)(&(description[0])), 1000, (LPCTSTR)"输入简介按Ctrl+Enter确认输入", (LPCTSTR)"添加景点", (LPCTSTR)"0", 0, 10, 0);
CheckCancel;
char mark[10];
int marki;
while (true) {
is_cancel = !InputBox(LPTSTR(&(mark[0])), 10, (LPCTSTR)"输入代号", (LPCTSTR)"添加景点", 0, 0, 0, 0);
CheckCancel;
marki = str_to_num(mark);
if (marki > 0 && graph.get_index(marki) == -1) break;
::MessageBox(GetHWnd(), (LPCTSTR)"此代号已存在,请重新输入", (LPCTSTR)"添加景点", MB_OK);
}
std::string namestr = "", descriptionstr = "";
// 把数据插入到节点
graph.insert_vertex((std::string)(namestr + name), (std::string)(descriptionstr + description), marki, mousex, mousey);
::MessageBox(GetHWnd(), (LPCTSTR)"添加成功", (LPCTSTR)"添加景点", MB_OK);
return 0;
}
int add_path(Graph_List& graph) {
bool is_cancel = false;
int v1, v2;
std::string source = "0000000000", destination = "0000000000", weightstr = "0000000000";
while (true) {
is_cancel = !InputBox(LPTSTR(&(source[0])), 10, (LPCTSTR)"输入起点代号", (LPCTSTR)"添加边", (LPCTSTR)"0", 0, 0, 0);
CheckCancel;
v1 = str_to_num(source);
if (graph.get_index(v1) != -1) break;
::MessageBox(GetHWnd(), (LPCTSTR)"该位置不存在,请重新输入", (LPCTSTR)"添加边", MB_OK);
}
while (true) {
is_cancel = !InputBox(LPTSTR(&(destination[0])), 10, (LPCTSTR)"请输入终点代号", (LPCTSTR)"添加边", (LPCTSTR)"0", 0, 0, 0);
CheckCancel;
v2 = str_to_num(destination);
if (graph.get_index(v2) != -1) break;
::MessageBox(GetHWnd(), (LPCTSTR)"该位置不存在,请重新输入", (LPCTSTR)"添加边", MB_OK);
}
double dx = graph.get_head()[graph.get_index(v2)].get_x();
double sx = graph.get_head()[graph.get_index(v1)].get_x();
double dy = graph.get_head()[graph.get_index(v2)].get_y();
double sy = graph.get_head()[graph.get_index(v1)].get_y();
double weight = (double)sqrt(((dx - sx) * (dx - sy) + (dy - sy) * (dy - sy)) / 30000.0) * 300.0;
int retop = graph.insert_edge(graph.get_index(v1), graph.get_index(v2), weight);
if (retop == -3) { ::MessageBox(GetHWnd(), (LPCTSTR)"起点与终点相同!", (LPCTSTR)"添加边", MB_OK); return -3; }
if (retop == -4) { ::MessageBox(GetHWnd(), (LPCTSTR)"边已存在!", (LPCTSTR)"添加边", MB_OK); return -4; }
::MessageBox(GetHWnd(), (LPCTSTR)"添加成功", (LPCTSTR)"添加边", MB_OK);
return 0;
}
int delete_vertex(Graph_List& graph) {
bool is_cancel = false;
char v[10];
int v1;
while (true) {
is_cancel = !InputBox(LPTSTR(&(v[0])), 10, (LPCTSTR)"输入代号", (LPCTSTR)"删除景点", (LPCTSTR)"0", 0, 0, 0);
CheckCancel;
v1 = str_to_num(v);
if (graph.get_index(v1) != -1) break;
::MessageBox(GetHWnd(), (LPCTSTR)"此代号不存在,请重输", (LPCTSTR)"删除景点", MB_OK);
}
graph.delete_vertex(graph.get_index(v1));
return 0;
}
int delete_path(Graph_List& graph) {
bool is_cancel = false;
int v1, v2;
std::string source = "0000000000", destination = "0000000000";
while (true) {
is_cancel = !InputBox(LPTSTR(&(source[0])), 10, (LPCTSTR)"输入起点代号", (LPCTSTR)"删除边", (LPCTSTR)"0", 0, 0, 0);
CheckCancel;
v1 = str_to_num(source);
if (graph.get_index(v1) != -1) break;
::MessageBox(GetHWnd(), (LPCTSTR)"该位置不存在,请重输", (LPCTSTR)"删除边", MB_OK);
}
while (true) {
is_cancel = !InputBox(LPTSTR(&(destination[0])), 10, (LPCTSTR)"输入终点代号", (LPCTSTR)"删除边", (LPCTSTR)"0", 0, 0, 0);
CheckCancel;
v2 = str_to_num(destination);
if (graph.get_index(v2) != -1) break;
::MessageBox(GetHWnd(), (LPCTSTR)"该位置不存在,请重输", (LPCTSTR)"删除边", MB_OK);
}
int retop = graph.delete_edge(graph.get_index(v1), graph.get_index(v2));
if (retop == -1) { ::MessageBox(GetHWnd(), (LPCTSTR)"边不存在!", (LPCTSTR)"删除边", MB_OK); return -1; }
::MessageBox(GetHWnd(), (LPCTSTR)"删除成功", (LPCTSTR)"删除边", MB_OK);
return 0;
}
// 画出最短路径
int draw_shortest_path(Graph_List& graph, int v1, int v2) {
Vertex* Head = graph.get_head();
int* path = new int[graph.number_of_vertices()];
graph.dshortest_path(v1, path);
Stack<int> s;
if (path[v2] == -1) {
::MessageBox(GetHWnd(), (LPCTSTR)"*** 无路径 ***", (LPCTSTR)"查询路径", MB_OK);
return -1;
}
int i = v2;
while (i != path[v1]) {
s.push(i);
i = path[i];
}
delete[]path;
int temp = v1, temppre = v1, length = 0;
std::string pathstr, tempstr;
// 开始批量绘制
BeginBatchDraw();
while (!s.empty()) {
temp = s.peek();
s.pop();
// 显示路径
printroad(Head[temppre].get_x(), Head[temppre].get_y(), Head[temp].get_x(), Head[temp].get_y());
int path_weight = graph.get_weight(temppre, temp);
length += path_weight;
tempstr = tempstr + "" + int_to_str(Head[temppre].get_mark()) + "" + int_to_str(Head[temp].get_mark()) + "" + int_to_str(path_weight) + "\n";
temppre = temp;
}
FlushBatchDraw();
setbkcolor(BKCOLOR);
settextcolor(TEXTCOLOR);
std::string str = "最短路径长度为:";
str = str + int_to_str(length) + "\n步行所需时间:" + int_to_str(length / 90) + "分钟\n";
str += tempstr;
::MessageBox(GetHWnd(), LPTSTR(&str[0]), (LPCTSTR)"查询路径", MB_OK);
return 0;
}
// 查找路径
int find_path(Graph_List& graph) {
bool is_cancel = false;
int v1, v2;
std::string source = "0000000000", destination = "0000000000";
while (true) {
is_cancel = !InputBox(LPTSTR(&(source[0])), 10, (LPCTSTR)"输入起点代号", (LPCTSTR)"查询路径", (LPCTSTR)"0", 0, 0, 0);
CheckCancel;
v1 = str_to_num(source);
if (graph.get_index(v1) != -1) break;
::MessageBox(GetHWnd(), (LPCTSTR)"该位置不存在,请重输", (LPCTSTR)"查询路径", MB_OK);
}
while (true) {
is_cancel = !InputBox(LPTSTR(&(destination[0])), 10, (LPCTSTR)"输入终点代号", (LPCTSTR)"查询路径", (LPCTSTR)"0", 0, 0, 0);
CheckCancel;
v2 = str_to_num(destination);
if (graph.get_index(v2) != -1) break;
::MessageBox(GetHWnd(), (LPCTSTR)"该位置不存在,请重输", (LPCTSTR)"查询路径", MB_OK);
}
draw_shortest_path(graph, graph.get_index(v1), graph.get_index(v2));
return 0;
}
// 画出最长路径
int draw_longest_path(Graph_List& graph, int v1, int v2) {
Vertex* Head = graph.get_head();
int* path = new int[graph.number_of_vertices()];
graph.dlongest_path(v1, path);
Stack<int> s;
if (path[v2] == -1) {
::MessageBox(GetHWnd(), (LPCTSTR)"*** 无路径 ***", (LPCTSTR)"查询路径", MB_OK);
return -1;
}
int i = v2;
while (i != path[v1]) {
s.push(i);
i = path[i];
}
delete[] path;
int temp = v1, temppre = v1, length = 0;
std::string pathstr, tempstr;
BeginBatchDraw();// 开始批量绘制
while (!s.empty()) {
temp = s.peek();
s.pop();
printroad(Head[temppre].get_x(), Head[temppre].get_y(), Head[temp].get_x(), Head[temp].get_y());//显示路径
int pathweight = graph.get_weight(temppre, temp);
length += pathweight;
tempstr = tempstr + "" + int_to_str(Head[temppre].get_mark()) + "" + int_to_str(Head[temp].get_mark()) + " : " + int_to_str(pathweight) + "" + "\n";
temppre = temp;
}
FlushBatchDraw();// 执行未完成的绘制任务
setbkcolor(BKCOLOR);// 显示颜色
settextcolor(TEXTCOLOR);//显示颜色
std::string str = "最短路径长度为:";
str = str + int_to_str(length) + "\n" + "步行所需时间:" + int_to_str(length / 90) + "分钟\n";
str += tempstr;
::MessageBox(GetHWnd(), LPTSTR(&str[0]), (LPCTSTR)"查询路径", MB_OK);
return 0;
}
// 漫游模式
int wandering(Graph_List& grpah) {
bool is_cancel = false;
int v1, v2;
std::string source = "0000000000", destination = "0000000000";
while (true) {
is_cancel = !InputBox(LPTSTR(&(source[0])), 10, (LPCTSTR)"输入起点代号", (LPCTSTR)"漫游模式", (LPCTSTR)"0", 0, 0, 0);
CheckCancel;
v1 = str_to_num(source);
if (graph.get_index(v1) == -1) ::MessageBox(GetHWnd(), (LPCTSTR)"该位置不存在,请重输", (LPCTSTR)"漫游模式", MB_OK);
else break;
}
while (true) {
is_cancel = !InputBox(LPTSTR(&(destination[0])), 10, (LPCTSTR)"输入终点代号", (LPCTSTR)"漫游模式", (LPCTSTR)"0", 0, 0, 0);
CheckCancel;
v2 = str_to_num(destination);
if (graph.get_index(v1) == -1) ::MessageBox(GetHWnd(), (LPCTSTR)"该位置不存在,请重输", (LPCTSTR)"漫游模式", MB_OK);
else break;
}
draw_longest_path(graph, graph.get_index(v1), graph.get_index(v2));
return 0;
}
void show_vertex(Graph_List& graph, int i) {
Vertex* Head = graph.get_head();
if (i < 0 || i > graph.number_of_vertices() - 1) {
::MessageBox(GetHWnd(), (LPCTSTR)"查询位置不存在", (LPCTSTR)"景点查询", MB_OK); //GetHWnd()获得窗口句柄
return;
}
std::string str = "代号:" + int_to_str(Head[i].get_mark()) + "\n" + "简介: " + Head[i].get_Description();
str = "名称:" + Head[i].get_VerName() + "\n" + str;
::MessageBox(GetHWnd(), LPTSTR(&str[0]), (LPCTSTR)"景点查询", MB_OK); //GetHWnd()获得窗口句柄
}
// 修改菜单
int ModifyMenu() {
int choose1 = 1;
char temp = 0, key;
while (temp != '\r') {
if (_kbhit()) {
key = _getch(); // 读取字符
fflush(stdin); // 清除读写缓冲区
switch (key) {
case UP: choose1--; break;
case DOWN: choose1++; break;
}
}
if (choose1 == 6) choose1 = 5;
if (choose1 == 0) choose1 = 1;
IMAGE img;
loadimage(&img, (LPCTSTR)"R-C.jpg", WIDTH, HEIGHT);
cleardevice();
putimage(0, 0, &img);
// transparentimage3(NULL, 0, 0, &img);
outtextxy((WIDTH / 2) - 80, 120, (LPCTSTR)"修改景点");
outtextxy((WIDTH / 2) - 180, 230, (LPCTSTR)"按↑和↓选择选项");
outtextxy((WIDTH / 2) - 180, 250, (LPCTSTR)"按ENTER键确定选择");
outtextxy(300, 300, (LPCTSTR)"请选择选项:");
outtextxy(420, 350, (LPCTSTR)"修改名称");
outtextxy(420, 380, (LPCTSTR)"修改简介");
outtextxy(420, 410, (LPCTSTR)"修改代号");
outtextxy(420, 440, (LPCTSTR)"修改坐标");
outtextxy(420, 470, (LPCTSTR)"返回");
outtextxy(390, 350 + (choose1 - 1) * 30, (LPCTSTR)"");
FlushBatchDraw();// 执行未完成的绘制任务
temp = _getch();
}
return choose1;
}
// 修改景点
int modify_vertex(Graph_List& graph) {
bool is_cancel = false;
int v1;
char v1str[10] = { 'a' };
while (true) {
is_cancel = !InputBox(LPTSTR(&(v1str[0])), 10, (LPCTSTR)"输入代号", (LPCTSTR)"修改景点", (LPCTSTR)"0", 0, 0, 0);
CheckCancel;
v1 = str_to_num(v1str);
if (graph.get_index(v1) != -1) break;
::MessageBox(GetHWnd(), (LPCTSTR)"该位置不存在,请重输", (LPCTSTR)"修改景点", MB_OK);
}
int v = graph.get_index(v1);
Vertex* Head = graph.get_head();
std::string name = Head[v].get_VerName();
std::string description = Head[v].get_Description();
int marki = Head[v].get_mark();
int x = Head[v].get_x();
int y = Head[v].get_y();
bool is_return = false;
while (!is_return) {
int in = ModifyMenu();
switch (in) {
case 1: {
is_cancel = !InputBox(LPTSTR(&(name[0])), 30, (LPCTSTR)"输入名称", (LPCTSTR)"修改景点", (LPCTSTR)"0", 0, 0, 0);
CheckCancel;
break;
}
case 2: {
is_cancel = !InputBox(LPTSTR(&(description[0])), 1000, (LPCTSTR)"输入简介:(按Ctrl+Enter确认输入)", (LPCTSTR)"修改景点", (LPCTSTR)"0", 0, 10, 0);
CheckCancel;
break;
}
case 3: {
char mark[10];
while (true) {
is_cancel = !InputBox(LPTSTR(&(mark[0])), 10, (LPCTSTR)"输入代号", (LPCTSTR)"修改景点", 0, 0, 0, 0);
CheckCancel;
marki = str_to_num(mark);
if (marki > 0 && (marki == Head[v].get_mark() || graph.get_index(marki) == -1)) {
break;
}
::MessageBox(GetHWnd(), (LPCTSTR)"输入有误或代号已存在,请重输", (LPCTSTR)"修改景点", MB_OK);
}
break;
}
case 4: {
char xstr[10], ystr[10];
while (true) {
is_cancel = !InputBox(LPTSTR(&(xstr[0])), 10, (LPCTSTR)"输入X坐标", (LPCTSTR)"修改景点", (LPCTSTR)"0", 0, 0, 0);
CheckCancel;
x = str_to_num(xstr);
if (x > 0 && x < WIDTH) break;
::MessageBox(GetHWnd(), (LPCTSTR)"您所输入的坐标不在图像范围内", (LPCTSTR)"修改景点", MB_OK);
}
while (true) {
is_cancel = !InputBox(LPTSTR(&(ystr[0])), 10, (LPCTSTR)"输入Y坐标", (LPCTSTR)"修改景点", (LPCTSTR)"0", 0, 0, 0);
CheckCancel;
y = str_to_num(ystr);
if (y > 0 && y < HEIGHT) break;
::MessageBox(GetHWnd(), (LPCTSTR)"您所输入的坐标不在图像范围内", (LPCTSTR)"修改景点", MB_OK);
}
break;
}
case 5: {
graph.modify_vertex(v, name, description, marki, x, y);
show_vertex(graph, v);
is_return = true;
break;
}
default: break;
}
}
return 0;
}
// 显示节点
int show_all_vertex(Graph_List& graph) {
Vertex* Head = graph.get_head();
setbkcolor(RGB(240, 240, 240));
settextcolor(RED);
setfillcolor(RGB(255, 0, 0));
LOGFONT font1;
gettextstyle(&font1);
settextstyle(font1.lfHeight - 2, 0, _T("宋体"));
for (int i = 0; i < graph.number_of_vertices(); i++) {
int x = Head[i].get_x(), y = Head[i].get_y();
std::string str = "";
str += int_to_str(Head[i].get_mark()); // 在地图上显示名称
if (Head[i].get_VerName() != "*") str = str + " " + Head[i].get_VerName();
solidcircle(x, y, 4); // 显示节点
outtextxy(x, y, (LPCTSTR)&str[0]); // 输出str字符串
}
settextstyle(&font1);
FlushBatchDraw();
return 0;
}
int show_all_path(Graph_List& graph) {
LINESTYLE linestyle;
getlinestyle(&linestyle);
setlinestyle(PS_SOLID, 3, NULL, 0);
setlinecolor(BLUE);
for (int i = 0; i < graph.number_of_vertices(); i++) {
Edge* p = graph.get_head()[i].get_adjacent();
while (p) {
// 画出当前节点与相邻节点的边
line(graph.get_head()[i].get_x(), graph.get_head()[i].get_y(),
graph.get_head()[p->get_VerAdj()].get_x(),
graph.get_head()[p->get_VerAdj()].get_y());
p = p->get_link(); // 指向下一个节点的邻边
}
} // 画出所有边
setlinestyle(&linestyle);
FlushBatchDraw();
return 0;
}
// 查找
int find_menu() {
int choose1 = 1;
char temp = 0, key;
while (temp != '\r') {
if (_kbhit()) {
key = _getch();
fflush(stdin);
switch (key) {
case UP: {
choose1--;
break;
}
case DOWN: {
choose1++;
break;
}
}
}
if (choose1 == 4) choose1 = 3;
if (choose1 == 0) choose1 = 1;
cleardevice();
IMAGE img;
loadimage(&img, (LPCTSTR)"R-C.jpg", WIDTH, HEIGHT);
putimage(0, 0, &img);
outtextxy((WIDTH / 2) - 80, 120, (LPCTSTR)"查询景点");//在指定位置输出字符串
outtextxy((WIDTH / 2) - 180, 230, (LPCTSTR)"按↑和↓选择选项");
outtextxy((WIDTH / 2) - 180, 250, (LPCTSTR)"按ENTER键确定选择");
outtextxy(300, 300, (LPCTSTR)"请选择选项:");
outtextxy(420, 350, (LPCTSTR)"按代号查询");
outtextxy(420, 380, (LPCTSTR)"按名称查询");
outtextxy(420, 410, (LPCTSTR)"返回");
outtextxy(390, 350 + (choose1 - 1) * 30, (LPCTSTR)"");
FlushBatchDraw();
temp = _getch();
}
return choose1;
}
// 查找景点
int find_vertex(Graph_List& graph) {
bool is_cancel = false;
bool is_return = false;
while (!is_return) {
int in = find_menu();
switch (in) {
case 1: {
char v1str[10] = { 'a' };
int v1;
is_cancel = !InputBox(LPTSTR(&(v1str[0])), 10, (LPCTSTR)"输入代号", (LPCTSTR)"查询景点", (LPCTSTR)"0", 0, 0, 0);
CheckCancel;
v1 = str_to_num(v1str);
show_vertex(graph, graph.get_index(v1));
break;
}
case 2: {
char v1str[10] = { 'a' };
std::string v1;
is_cancel = !InputBox(LPTSTR(&(v1str[0])), 10, (LPCTSTR)"输入名称", (LPCTSTR)"查询景点", (LPCTSTR)"0", 0, 0, 0);
CheckCancel;
v1 = "";
v1 += v1str;
show_vertex(graph, graph.get_index(v1));
break;
}
case 3: {
is_return = true;
break;
}
default: {} break;
}
}
return 0;
}
// 打开文件
int open(Graph_List& graph, bool is_first_open) {
std::fstream filestr;
char mapname[256] = { 'a' }; // map_name保存文件名
if (is_first_open) {
filestr.open("map.txt");
strcpy_s(mapname, "seu map.png");
}
else {
bool is_cancel = false;
char filename[256] = { 'a' };
while (true) {
is_cancel = !InputBox((LPTSTR) & (filename[0]), 10, (LPCTSTR)"输入文本文件名(不需输'.txt')", (LPCTSTR)"打开", (LPCTSTR)"0", 0, 0, 0);
CheckCancel;
strcat_s(filename, ".txt");
filestr.open(filename);
if (filestr.is_open()) break;
::MessageBox(GetHWnd(), (LPCTSTR)"无此文件,请重输", (LPCTSTR)"打开", MB_OK); //提示框
}
while (true) {
is_cancel = !InputBox((LPTSTR) & (mapname[0]), 10, (LPCTSTR)"输入图片文件名(不需输'.png')", (LPCTSTR)"打开", (LPCTSTR)"0", 0, 0, 0);
CheckCancel;
strcat_s(mapname, ".png");
if ((_access(mapname, 0)) != -1) { //_access,判断文件是否存在,如果文件具有指定的访问权限则函数返回0如果文件不存在或者不能访问指定的权限则返回-1.
break;
}
::MessageBox(GetHWnd(), (LPCTSTR)"无此文件,请重输", (LPCTSTR)"打开", MB_OK);
}
}
// 从文件中提取节点和边信息绘制图
graph.graph_con(filestr, mapname);
filestr.close();
putimage(LEFTBORDER, TOPBORDER, graph.get_map());
return 0;
}
// 保存文件
int save(Graph_List& graph) {
bool is_cancel = false;
Vertex* head = graph.get_head();
char filename[256] = { 'a' };
is_cancel = !InputBox((LPTSTR) & (filename[0]), 10, (LPCTSTR)"输入文本文件名(不需输'.txt')", (LPCTSTR)"保存", (LPCTSTR)"0", 0, 0, 0);
CheckCancel;
strcat_s(filename, ".txt");
graph.save_file(filename);
::MessageBox(GetHWnd(), (LPCTSTR)"保存成功", (LPCTSTR)"保存", MB_OK);
return 0;
}
int get_choose() {
FlushMouseMsgBuffer(); // 清空鼠标消息缓冲区
MOUSEMSG temp;
temp.mkLButton = false;
bool kick = false;
while (!kick) {
temp = GetMouseMsg(); // 获取一个鼠标信息,若没有则等待
FlushMouseMsgBuffer();
if (temp.mkLButton == false) {
}
else {
if (temp.y < menu_top + menu_height && temp.y > menu_top) kick = true;
}
}
choose = (temp.x - left) / menu_width;
return 0;
}
// 菜单
int front_menu(Graph_List& graph) {
fflush(stdin);
settextcolor(TEXTCOLOR);
setfillcolor(BKCOLOR);
solidrectangle(5, TOPBORDER, WIDTH, HEIGHT); //以背景色刷新
setfillcolor(MENUCOLOR);
solidrectangle(5, 0, WIDTH - 5, menu_top1); //画最上方的绿色条
putimage(LEFTBORDER, TOPBORDER, graph.get_map());
setfillcolor(BKCOLOR);
solidrectangle(LEFTBORDER, menu_top + textheight('a'), WIDTH - LEFTBORDER, menu_top + textheight('a') + 5); //去掉选中的菜单下方的小绿块
setfillcolor(TEXTCOLOR);
setfillcolor(MENUCOLOR);
solidrectangle(choose * menu_width + left, menu_top + textheight('a'),
(choose + 1) * menu_width + left, menu_top + textheight('a') + 5); //画选中的菜单下方的小绿块
roundrect(5, menu_top + textheight('a') + 5, WIDTH - 5, HEIGHT - 5, 5, 3); //画图片周围的绿色边框
solidrectangle(5, menu_top + textheight('a') + 5, WIDTH - 5, menu_top + textheight('a') + 10); //画图片上方与小绿块相连的绿色条
setfillcolor(TEXTCOLOR);
LOGFONT font1;
gettextstyle(&font1);
settextstyle(font1.lfHeight, 0, _T("宋体"));
std::string menu[menu_num] = { " 打开", " 显示", " 查询路径",
" 查询景点", " 修改景点", " 添加景点", " 删除景点",
" 添加边", " 删除边"," 保存", " 退出"};//菜单栏
for (int index = 0; index <= menu_num - 1; index++) {
if (index == choose)settextcolor(SELECTCOLOR);
const char* p = menu[index].c_str();
outtextxy(left + index * menu_width, menu_top, (LPCTSTR)p);
if (index == choose)settextcolor(TEXTCOLOR);
}
settextstyle(&font1);
setlinecolor(MENUCOLOR);
for (int index1 = 0; index1 <= menu_num + 1; index1++) {
line(left + index1 * menu_width, menu_top, left + index1 * menu_width, menu_top + textheight('a'));
}
LOGFONT font;
gettextstyle(&font);
settextstyle(10, 0, _T("宋体"));
settextcolor(TEXTCOLOR);
for (int lx = LEFTBORDER; lx <= WIDTH; lx += 50) {
outtextxy(lx, TOPBORDER - 10, (LPCTSTR)&int_to_str(lx - LEFTBORDER)[0]);
}
for (int ly = TOPBORDER; ly <= HEIGHT - LEFTBORDER; ly += 50) {
outtextxy(10, ly - 5, (LPCTSTR)&int_to_str(ly - TOPBORDER)[0]);
}
settextstyle(&font);
settextcolor(TEXTCOLOR);
FlushBatchDraw();
setbkcolor(BKCOLOR);
settextcolor(TEXTCOLOR);
return choose;
}
void on_btnOK_click() {
if (wcscmp(L"123", txt_password.get_text())) {
MessageBox(GetHWnd(), (LPCTSTR)"密码错误", (LPCTSTR)"错误", MB_OK);
}
else {
wchar_t s[100] = L"Hello, ";
wcscat_s(s, 100, txt_name.get_text());
MessageBox(GetHWnd(), (LPCTSTR)s, (LPCTSTR)"登陆成功", MB_OK);
}
}
//void log_in() {
// initgraph(640, 480);
// setbkcolor(0xeeeeee);
// cleardevice();
// settextcolor(BLACK);
// outtextxy(50, 55, (LPCTSTR)"用户名:");
// txt_name.create(120, 50, 400, 75, 10);
// outtextxy(50, 105, (LPCTSTR)"密 码:");
// txt_password.create(120, 100, 400, 125, 10);
// btnOK.create(320, 150, 400, 175, L"OK", on_btnOK_click);
//
// ExMessage msg;
// while (true) {
// msg = getmessage(EX_MOUSE); // 获取消息输入
// if (msg.message == WM_LBUTTONDOWN) {
// // 判断控件
// if (txt_name.check(msg.x, msg.y)) txt_name.on_message();
// if (txt_password.check(msg.x, msg.y)) txt_password.on_message();
// if (btnOK.check(msg.x, msg.y)) btnOK.on_message();
// }
// }
// // 关闭窗口
// closegraph();
// return;
//}
int main() {
// log_in();
initgraph(WIDTH, HEIGHT);
setbkcolor(BKCOLOR);
cleardevice();
log_in_2(account);
bool is_first_open = true;
while (true) {
front_menu(graph);
if (is_first_open) choose = 0;
else get_choose();
front_menu(graph);
switch (choose) {
case 0: {
open(graph, is_first_open);
is_first_open = false;
break;
}
case 1: {
show_all_path(graph);
show_all_vertex(graph);
int vertex_num = graph.number_of_vertices();
int edge_num = graph.number_of_edges();
std::string num_of_vertices;
num_of_vertices = "图中共有景点 " + int_to_str(vertex_num) + "\n" + "共有边" + int_to_str(edge_num) + "\n";
::MessageBox(GetHWnd(), LPCSTR(&num_of_vertices[0]), (LPCSTR)"显示", MB_OK);
break;
}
case 2: {
show_all_vertex(graph);
find_path(graph);
show_all_vertex(graph);
break;
}
//case 3: {
// // std::cout << 1 << std::endl;
// show_all_vertex(graph);
// wandering(graph);
// show_all_vertex(graph);
// break;
//}
case 3: {
show_all_vertex(graph);
find_vertex(graph);
break;
}
case 4: {
show_all_vertex(graph);
modify_vertex(graph);
break;
}
case 5: {
show_all_vertex(graph);
add_vertex(graph);
break;
}
case 6: {
show_all_vertex(graph);
delete_vertex(graph);
break;
}
case 7: {
show_all_path(graph);
show_all_vertex(graph);
add_path(graph);
break;
}
case 8: {
show_all_path(graph);
show_all_vertex(graph);
delete_path(graph);
break;
}
case 9: {
save(graph);
break;
}
case 10: {
WinExec((LPCSTR)_T("taskkill /f /im conhost.ext /t"), 1);
exit(0);
break;
}
default: break;
}
}
return 0;
}