From 058e21902138e8d091f9490e4fc48c614161ef42 Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 8 Nov 2021 09:12:32 +0100 Subject: [PATCH] add search.cpp --- alrys/Makefile | 8 +- alrys/search.cpp | 223 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 229 insertions(+), 2 deletions(-) create mode 100644 alrys/search.cpp diff --git a/alrys/Makefile b/alrys/Makefile index c661355..24f56fe 100644 --- a/alrys/Makefile +++ b/alrys/Makefile @@ -1,6 +1,7 @@ CFLAGS = -O3 +CXXFLAGS = -O3 -std=c++11 -all: explore finalize +all: explore finalize search explore: explore.c alryslib.c gcc $(CFLAGS) -o $@ $< -lm @@ -8,5 +9,8 @@ explore: explore.c alryslib.c finalize: finalize.c alryslib.c gcc $(CFLAGS) -o $@ $< -lm +search: search.cpp alryslib.c + g++ $(CXXFLAGS) -o $@ $< -lm + clean: - rm -rf explore finalize + rm -rf explore finalize search diff --git a/alrys/search.cpp b/alrys/search.cpp new file mode 100644 index 0000000..b1fe7ce --- /dev/null +++ b/alrys/search.cpp @@ -0,0 +1,223 @@ +#include +#include +#include + +#include +#include +#include +#include + +#include "alryslib.c" + +using namespace std; + +int index(int x, int a, int y, int b, int width) +{ + return x * 3 + a + 1 + (y * 3 + b + 1) * width; +} + +double cost(int s, int d, int width, int size, int boat) +{ + int a, b, c1, c2, k, ls; + double x, x1, x2, y, y1, y2; + double result; + + if(s < 0 || s >= size) return -1.0; + if(d < 0 || d >= size) return -1.0; + + result = 0.1; + + a = d % width; + b = d / width; + + if(a % 3 == 1) result -= 1.0e-10; + if(b % 3 == 1) result -= 1.0e-10; + + x2 = a / 3 + (a % 3 - 1) * 1.0e-14; + y2 = b / 3 + (b % 3 - 1) * 1.0e-14; + + + c2 = data[(int)x2 + (int)y2 * (width / 3)]; + if(c2 == 1 || (c2 == 3 && !boat)) return -1.0; + + a = s % width; + b = s / width; + + if(a % 3 == 1) result -= 1.0e-10; + if(b % 3 == 1) result -= 1.0e-10; + + x1 = a / 3 + (a % 3 - 1) * 1.0e-14; + y1 = b / 3 + (b % 3 - 1) * 1.0e-14; + + segments(x1, y1, x2, y2, &ls); + x = x1; + y = y1; + + for(k = 1; k < ls; ++k) + { + c1 = data[(int)MIN(x, lx[k]) + (int)MIN(y, ly[k]) * (width / 3)]; + c2 = data[(int)lx[k] + (int)ly[k] * (width / 3)]; + + if(c1 == 1 || c2 == 1 || ((c1 == 3 || c2 == 3) && !boat)) return -1.0; + + result += hypot(lx[k] - x, ly[k] - y) * (0.2 + (c1 == 5) * 0.1 + (c1 == 4) * 0.2 + (c1 == 2) * 0.3); + + x = lx[k]; + y = ly[k]; + } + + return result; +} + +void astar(int s, int d, int width, int size, int boat) +{ + int a, b, i, j, u, n, *prev; + double c, x, y, *dist; + vector path; + typedef pair element; + priority_queue, greater > q; + + prev = new int[size]; + dist = new double[size]; + + for(i = 0; i < size; ++i) + { + prev[i] = -1; + dist[i] = 1.0e9; + } + + q.emplace(0, s); + prev[s] = s; + dist[s] = 0; + + while(!q.empty()) + { + u = q.top().second; + q.pop(); + + if(u == d) break; + + a = u % width; + b = u / width; + for(i = -30; i < 31; ++i) + { + for(j = -30; j < 31; ++j) + { + if(i == 0 && j == 0) continue; + n = a + i + (b + j) * width; + c = cost(u, n, width, size, boat); + if(c < 0) continue; + c += dist[u]; + if(c < dist[n]) + { + q.emplace(c, n); + prev[n] = u; + dist[n] = c; + } + } + } + } + + if(u == d) + { + while(u != s) + { + path.push_back(u); + u = prev[u]; + } + path.push_back(s); + reverse(path.begin(), path.end()); + printf("250 0 0\n"); + for(auto u : path) + { + a = u % width; + b = u / width; + x = a / 3; + a = a % 3 - 1; + y = b / 3; + b = b % 3 - 1; + printf("%7.3f %2d %6.3f %2d\n", x, a, y, b); + } + } + + delete[] dist; + delete[] prev; +} + +int main(int argc, char *argv[]) +{ + char *end; + long number; + int s, d, width, size; + + errno = 0; + number = (argc == 2) ? strtol(argv[1], &end, 10) : -1; + if(errno != 0 || end == argv[1] || number < 0 || number > 15) + { + fprintf(stderr, "Usage: search [0-15]\n"); + return EXIT_FAILURE; + } + + width = 146 * 3; + size = 91 * 3 * width; + + switch(number) + { +/* + case 0: s = index( 49, 1, 43, 1, width); d = index( 18, -1, 39, -1, width); break; + case 1: s = index( 18, -1, 39, -1, width); d = index( 38, 1, 49, 1, width); break; + case 2: s = index( 38, 1, 49, 1, width); d = index( 9, -1, 59, -1, width); break; + case 3: s = index( 9, -1, 59, -1, width); d = index( 73, -1, 83, 1, width); break; + case 4: s = index( 73, -1, 83, 1, width); d = index(106, 1, 40, -1, width); break; + case 5: s = index(106, 1, 40, -1, width); d = index(107, 1, 69, 1, width); break; + case 6: s = index(107, 1, 69, 1, width); d = index(119, 1, 84, -1, width); break; + case 7: s = index(119, 1, 84, -1, width); d = index( 73, -1, 83, 1, width); break; + case 8: s = index( 73, -1, 83, 1, width); d = index( 2, -1, 89, 1, width); break; + case 9: s = index( 2, -1, 89, 1, width); d = index( 13, -1, 80, 1, width); break; + case 10: s = index( 13, -1, 80, 1, width); d = index( 72, 1, 83, 1, width); break; + case 11: s = index( 72, 1, 83, 1, width); d = index( 70, -1, 51, 1, width); break; + case 12: s = index( 70, -1, 51, 1, width); d = index( 70, -1, 18, -1, width); break; + case 13: s = index( 70, -1, 18, -1, width); d = index(141, 1, 71, 1, width); break; + case 14: s = index(141, 1, 71, 1, width); d = index(131, -1, 62, 1, width); break; + case 15: s = index(131, -1, 62, 1, width); d = index(115, -1, 26, 1, width); break; +*/ +/* + case 0: s = index( 49, 1, 43, 1, width); d = index( 18, -1, 39, -1, width); break; + case 1: s = index( 18, -1, 39, -1, width); d = index( 38, 1, 49, 1, width); break; + case 2: s = index( 38, 1, 49, 1, width); d = index( 9, -1, 59, -1, width); break; + case 3: s = index( 9, -1, 59, -1, width); d = index( 72, 1, 83, 1, width); break; + case 4: s = index( 72, 1, 83, 1, width); d = index( 13, -1, 80, 1, width); break; + case 5: s = index( 13, -1, 80, 1, width); d = index( 2, -1, 89, 1, width); break; + case 6: s = index( 2, -1, 89, 1, width); d = index( 73, -1, 83, 1, width); break; + case 7: s = index( 73, -1, 83, 1, width); d = index(119, 1, 84, -1, width); break; + case 8: s = index(119, 1, 84, -1, width); d = index(107, 1, 69, 1, width); break; + case 9: s = index(107, 1, 69, 1, width); d = index(106, 1, 40, -1, width); break; + case 10: s = index(106, 1, 40, -1, width); d = index( 73, -1, 83, 1, width); break; + case 11: s = index( 73, -1, 83, 1, width); d = index( 70, -1, 51, 1, width); break; + case 12: s = index( 70, -1, 51, 1, width); d = index( 70, -1, 18, -1, width); break; + case 13: s = index( 70, -1, 18, -1, width); d = index(141, 1, 71, 1, width); break; + case 14: s = index(141, 1, 71, 1, width); d = index(131, -1, 62, 1, width); break; + case 15: s = index(131, -1, 62, 1, width); d = index(115, -1, 26, 1, width); break; +*/ + case 0: s = index( 49, 1, 43, 1, width); d = index( 18, -1, 39, -1, width); break; + case 1: s = index( 18, -1, 39, -1, width); d = index( 38, 1, 49, 1, width); break; + case 2: s = index( 38, 1, 49, 1, width); d = index( 9, -1, 59, -1, width); break; + case 3: s = index( 9, -1, 59, -1, width); d = index( 72, 1, 83, 1, width); break; + case 4: s = index( 72, 1, 83, 1, width); d = index( 2, -1, 89, 1, width); break; + case 5: s = index( 2, -1, 89, 1, width); d = index(107, 1, 69, 1, width); break; + case 6: s = index(107, 1, 69, 1, width); d = index(106, 1, 40, -1, width); break; + case 7: s = index(106, 1, 40, -1, width); d = index(107, 1, 69, 1, width); break; + case 8: s = index(107, 1, 69, 1, width); d = index(119, 1, 84, -1, width); break; + case 9: s = index(119, 1, 84, -1, width); d = index( 73, -1, 83, 1, width); break; + case 10: s = index( 73, -1, 83, 1, width); d = index( 70, -1, 51, 1, width); break; + case 11: s = index( 70, -1, 51, 1, width); d = index( 70, -1, 18, -1, width); break; + case 12: s = index( 70, -1, 18, -1, width); d = index(141, 1, 71, 1, width); break; + case 13: s = index(141, 1, 71, 1, width); d = index(130, 1, 63, -1, width); break; + case 14: s = index(130, 1, 63, -1, width); d = index(104, -1, 56, 1, width); break; + case 15: s = index(104, -1, 56, 1, width); d = index(115, -1, 26, 1, width); break; + } + + astar(s, d, width, size, number >= 14); + + return EXIT_SUCCESS; +}