Advertisement
Guest User

astar.z

a guest
Aug 20th, 2018
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.09 KB | None | 0 0
  1. const int ARR_EMPTY = -1;
  2. const int ARR_INFINITY = -2;
  3.  
  4. // used in the algorithm.
  5. const int ARR_W = 16;
  6. const int ARR_H = 11;
  7.  
  8. const int DEBUG_COMBO_START = 900;
  9. const int DEBUG_COMBO_FINISH = 901;
  10. const int DEBUG_COMBO_RESULT = 914;
  11. // 4 combos each, coming from up/down/left/right.
  12. const int DEBUG_COMBO_OPEN = 902;
  13. const int DEBUG_COMBO_CLOSED = 906;
  14. const int DEBUG_COMBO_CURRENT = 910;
  15.  
  16. // Ex1 for step-by-step, ex2 for fast.
  17. void WaitForUser()
  18. {
  19.         while (!Link->PressEx1 && !Link->InputEx2) Waitframe();
  20. }
  21.  
  22. ffc script Astar
  23. {
  24.     void run()
  25.     {
  26.         ClearTrace();
  27.  
  28.         WaitForUser();
  29.  
  30.         int START = 72;
  31.         int GOAL = 148;
  32.  
  33.         Screen->ComboD[START] = DEBUG_COMBO_START;
  34.         Screen->ComboD[GOAL] = DEBUG_COMBO_FINISH;
  35.  
  36.         int CURRENT = START;
  37.  
  38.         int ClosedSet[176]; // Unsorted array
  39.         ClearArrToVal(ClosedSet, ARR_EMPTY);
  40.  
  41.         for(int i = 0; i < SizeOfArray(ClosedSet); i += 1)
  42.         {
  43.             if(Screen->ComboS[i] != 0 && i != GOAL)
  44.             {
  45.                 Put(ClosedSet, i);
  46.             }
  47.         }
  48.  
  49.         int OpenSet[176]; // Unsorted array
  50.         ClearArrToVal(OpenSet, ARR_EMPTY);
  51.         Put(OpenSet, START);
  52.  
  53.         int CameFrom[176]; // Sorted array
  54.         ClearArrToVal(CameFrom, ARR_EMPTY);
  55.  
  56.         int GScore[176]; // Sorted array
  57.         ClearArrToVal(GScore, ARR_INFINITY);
  58.         GScore[START] = 0;
  59.  
  60.         int FScore[176]; // Sorted array
  61.         ClearArrToVal(FScore, 9999);
  62.         FScore[START] = heuristic(START, GOAL);
  63.  
  64.         int NEIGHBOR = 0;
  65.         bool VALID_NEIGHBOR = false;
  66.  
  67.         int Tentative_GScore = 0;
  68.  
  69.         int Iterations = 0; // Custom stuff
  70.  
  71.         int Space[] = " "; // Debug stuff
  72.  
  73.         int smallest = 0;
  74.  
  75.         while(ArrEmpty(OpenSet, ARR_EMPTY) == false)
  76.         {
  77.             Iterations += 1;
  78.  
  79.             int choosing[] = "Choosing next node:"; TraceS(choosing); TraceNL();
  80.  
  81.             smallest = 0;
  82.             for(int i = 0; i < SizeOfArray(OpenSet); i += 1)
  83.             {
  84.                 if(OpenSet[i] > 0)
  85.                 {
  86.                     int s1[] = "  X "; TraceS(s1); Trace(OpenSet[i] % 16);
  87.                     int s4[] = "  Y "; TraceS(s4); Trace(OpenSet[i] >> 4);
  88.                     int s2[] = "  Score "; TraceS(s2); Trace(FScore[OpenSet[i]]);
  89.  
  90.                     if(FScore[OpenSet[i]] < FScore[OpenSet[smallest]] && FScore[OpenSet[i]] >= 0)
  91.                     {
  92.                         smallest = i;
  93.                         int s3[] = "  New smallest!"; TraceS(s3); TraceNL();
  94.                     }
  95.                 }
  96.             }
  97.  
  98.             if(smallest < 0)
  99.             {
  100.                 continue;
  101.             }
  102.  
  103.             CURRENT = OpenSet[smallest];
  104.             if(CURRENT != START && CURRENT != GOAL)
  105.             {
  106.                 Screen->ComboD[CURRENT] += DEBUG_COMBO_CURRENT - DEBUG_COMBO_OPEN;
  107.             }
  108.  
  109.             WaitForUser();
  110.  
  111.             int currentval[] = "Current node: "; TraceS(currentval); Trace(CURRENT); TraceNL();
  112.  
  113.             if(CURRENT == GOAL)
  114.             {
  115.                 int SUCCESS[] = "SUCCESS! The script works!";
  116.                 TraceS(SUCCESS);
  117.                 TraceNL();
  118.  
  119.                 int cur = GOAL;
  120.                 Trace(CameFrom[GOAL]);
  121.                 Trace(GOAL);
  122.  
  123.                 while(CameFrom[cur] != START)
  124.                 {
  125.                     cur = CameFrom[cur];
  126.                     Screen->ComboD[cur] = DEBUG_COMBO_RESULT;
  127.                     Trace(cur);
  128.                     Waitframe();
  129.                     WaitForUser();
  130.                 }
  131.  
  132.                 TraceNL();
  133.                 Trace(Iterations);
  134.  
  135.                 break;
  136.             }
  137.  
  138.             if(CURRENT < 0)
  139.             {
  140.                 Waitframe();
  141.                 continue;
  142.             }
  143.  
  144.             int msg4[] = "IndiceOfVal(OpenSet, Current) = "; TraceS(msg4); Trace(IndiceOfVal(OpenSet, CURRENT)); TraceNL();
  145.             int msg5[] = "OpenSet(IndiceOfVal...) = "; TraceS(msg5); Trace(OpenSet[IndiceOfVal(OpenSet, CURRENT)]); TraceNL();
  146.             OpenSet[IndiceOfVal(OpenSet, CURRENT)] = ARR_EMPTY;
  147.             // ShiftArr(OpenSet, ARR_EMPTY, ARR_EMPTY);
  148.  
  149.             // Trace(8888);
  150.  
  151.             Put(ClosedSet, CURRENT);
  152.             if(CURRENT != START) // Promote to closed combo.
  153.             {
  154.                 Screen->ComboD[CURRENT] += DEBUG_COMBO_CLOSED - DEBUG_COMBO_CURRENT;
  155.             }
  156.  
  157.             for(int i = 0; i < 4; i += 1) // Going through each neighbor of current
  158.             {
  159.                 VALID_NEIGHBOR = false;
  160.  
  161.                 if(i == 0) // Up
  162.                 {
  163.                     NEIGHBOR = (CURRENT - ARR_W);
  164.  
  165.                     if(NEIGHBOR >= 0 && ArrContainsVal(ClosedSet, NEIGHBOR) == false)
  166.                     {
  167.                         VALID_NEIGHBOR = true;
  168.                     }
  169.                 }
  170.  
  171.                 if(i == 1) // Down
  172.                 {
  173.                     NEIGHBOR = (CURRENT + ARR_W);
  174.  
  175.                     if(NEIGHBOR < SizeOfArray(OpenSet) && ArrContainsVal(ClosedSet, NEIGHBOR) == false)
  176.                     {
  177.                         VALID_NEIGHBOR = true;
  178.                     }
  179.                 }
  180.  
  181.                 //
  182.                 // NOTE: LOOK INTO LEFT DIRECTION NODE
  183.                 // It seems like there's an error with FloorToMultiple, which allows it to return a combo on the far right of the screen as being
  184.                 // On the same row as one combo down and on the far left.
  185.  
  186.  
  187.                 if(i == 2) // Left
  188.                 {
  189.                     NEIGHBOR = (CURRENT - 1);
  190.  
  191.                     if(NEIGHBOR >= FloorToMultiple(CURRENT, ARR_W) && ArrContainsVal(ClosedSet, NEIGHBOR) == false)
  192.                     {
  193.                         VALID_NEIGHBOR = true;
  194.                     }
  195.                 }
  196.  
  197.                 if(i == 3) // Right
  198.                 {
  199.                     NEIGHBOR = (CURRENT + 1);
  200.  
  201.                     if(NEIGHBOR < FloorToMultiple(CURRENT + ARR_W, ARR_W) && ArrContainsVal(ClosedSet, NEIGHBOR) == false)
  202.                     {
  203.                         VALID_NEIGHBOR = true;
  204.                     }
  205.                 }
  206.  
  207.                 if(VALID_NEIGHBOR == true)
  208.                 {
  209.                     Tentative_GScore = GScore[CURRENT] + heuristic(CURRENT, NEIGHBOR);
  210.  
  211.                     int msg2[] = "Tentative GScore: "; TraceS(msg2); Trace(Tentative_GScore); TraceNL();
  212.  
  213.                     int msg6[] = "Neighbor node: "; TraceS(msg6); Trace(NEIGHBOR); TraceNL();
  214.  
  215.                     if(ArrContainsVal(OpenSet, NEIGHBOR) == false)
  216.                     {
  217.                         Put(OpenSet, NEIGHBOR);
  218.                         if(NEIGHBOR != GOAL)
  219.                         {
  220.                             Screen->ComboD[NEIGHBOR] = DEBUG_COMBO_OPEN + i;
  221.                         }
  222.                     }
  223.                     else if(Tentative_GScore >= GScore[NEIGHBOR])
  224.                     {
  225.                         continue; // Worse path
  226.                     }
  227.  
  228.                     CameFrom[NEIGHBOR] = CURRENT;
  229.                     GScore[NEIGHBOR] = Tentative_GScore;
  230.                     FScore[NEIGHBOR] = GScore[NEIGHBOR] + heuristic(NEIGHBOR, GOAL);
  231.  
  232.                     int msg3[] = "End of subloop #"; TraceS(msg3); Trace(i); TraceNL();
  233.                 }
  234.             }
  235.  
  236.             int msg[] = "End of algorithm loop ~~~~~~~~~~~~~~~~~~~~ Iteration #";
  237.             TraceS(msg); Trace(Iterations); TraceNL();
  238.  
  239.             Waitframe();
  240.         }
  241.  
  242.         while(true)
  243.         {
  244.             Waitframe();
  245.         }
  246.     }
  247. }
  248.  
  249. void ClearArrToVal(int arr, int val)
  250. {
  251.     for(int i = 0; i < SizeOfArray(arr); i += 1)
  252.     {
  253.         arr[i] = val;
  254.     }
  255. }
  256.  
  257. void Put(int arr, int val, int pos)
  258. {
  259.     arr[pos] = val;
  260. }
  261.  
  262. void Put(int arr, int val)
  263. {
  264.     for(int i = 0; i < SizeOfArray(arr); i += 1)
  265.     {
  266.         if(arr[i] == ARR_EMPTY)
  267.         {
  268.             arr[i] = val;
  269.             break;
  270.         }
  271.     }
  272. }
  273.  
  274. bool ArrEmpty(int arr, int exception)
  275. {
  276.     bool empty = true;
  277.     for(int i = 0; i < SizeOfArray(arr); i += 1)
  278.     {
  279.         if(arr[i] != exception)
  280.         {
  281.             empty = false;
  282.             break;
  283.         }
  284.     }
  285.  
  286.     return empty;
  287. }
  288.  
  289. int Get(int arr, int arrP, bool remove)
  290. {
  291.     int smallest = arrP[0];
  292.     int node = 0;
  293.     int indice = 0;
  294.  
  295.     for(int i = 1; i < SizeOfArray(arrP); i += 1)
  296.     {
  297.         if(smallest < arrP[i] && smallest > ARR_EMPTY)
  298.         {
  299.             smallest = arrP[i];
  300.             node = arr[i];
  301.             indice = i;
  302.         }
  303.     }
  304.  
  305.     if(remove == true)
  306.     {
  307.         arr[indice] = ARR_EMPTY;
  308.         arrP[indice] = ARR_EMPTY;
  309.  
  310.         //ShiftArr(arr, ARR_EMPTY, indice);
  311.         //ShiftArr(arrP, ARR_EMPTY, indice);
  312.     }
  313.  
  314.     //Trace(indice);
  315.  
  316.     return node;
  317. }
  318.  
  319. // startPos is the indice to shift into/away from
  320. void ShiftArr(int arr, int emptyVal, int startPos)
  321. {
  322.     for(int i = startPos; i < SizeOfArray(arr); i += 1)
  323.     {
  324.         if(i + 1 >= SizeOfArray(arr))
  325.         {
  326.             // arr[i] = emptyVal;
  327.             break;
  328.         }
  329.         else
  330.         {
  331.             arr[i] = arr[i + 1];
  332.         }
  333.     }
  334. }
  335.  
  336. // Floors a value to a multiple.
  337. int FloorToMultiple(int input, int multiple)
  338. {
  339.     if(multiple == 0) {return 0;}
  340.     int mul = Abs(multiple);
  341.     return Floor(input/mul)*mul;
  342. }
  343.  
  344. bool ArrContainsVal(int arr, int val)
  345. {
  346.     bool contains = false;
  347.  
  348.     for(int i = 0; i < SizeOfArray(arr); i += 1)
  349.     {
  350.         if(arr[i] == val)
  351.         {
  352.             contains = true;
  353.             break;
  354.         }
  355.     }
  356.  
  357.     return contains;
  358. }
  359.  
  360. int heuristic(int nodeA, int nodeB)
  361. {
  362.     int a_x = nodeA % ARR_W;
  363.     int a_y = Floor(nodeA / ARR_W);
  364.     int b_x = nodeB % ARR_W;
  365.     int b_y = Floor(nodeB / ARR_W);
  366.  
  367.     return Abs(a_x - b_x) + Abs(a_y - b_y);
  368. }
  369.  
  370. int IndiceOfLowestVal(int arr)
  371. {
  372.     int smallest = arr[0];
  373.     int indice = 0;
  374.  
  375.     for(int i = 0; i < SizeOfArray(arr); i += 1)
  376.     {
  377.         if(smallest < arr[i] && smallest != ARR_EMPTY && smallest != ARR_INFINITY && smallest >= 0)
  378.         {
  379.             smallest = arr[i];
  380.             indice = i;
  381.         }
  382.     }
  383.  
  384.     return indice;
  385. }
  386.  
  387. int IndiceOfVal(int arr, int val)
  388. {
  389.     int indice = -1;
  390.  
  391.     for(int i = 0; i < SizeOfArray(arr); i += 1)
  392.     {
  393.         if(arr[i] == val)
  394.         {
  395.             indice = i;
  396.             break;
  397.         }
  398.     }
  399.  
  400.     return indice;
  401. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement