Advertisement
Guest User

Untitled

a guest
Nov 2nd, 2016
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.17 KB | None | 0 0
  1. #pragma once
  2. #include <iostream>
  3. #include <fstream>
  4. #include <string>
  5. using namespace std;
  6. using std::ofstream;
  7. using std::ifstream;
  8. using std::ios;
  9. //predefine crossroad class
  10. class CrossRoad;
  11. //neighbor class - has a reference to a crossroad, as well as a cost to reach it
  12. class Neighbor {
  13. public:
  14.     CrossRoad *key1;
  15.     int cost;
  16.     Neighbor(CrossRoad *_key1 = nullptr, int _cost = 0) :key1(_key1), cost(_cost) {}
  17. };
  18. //same as the neighbor class, but contains both crossroads
  19. class CameFromTrio :public Neighbor {
  20. public:
  21.     CrossRoad *key2;
  22.     CameFromTrio(CrossRoad *_key1 = nullptr, CrossRoad *_key2 = nullptr, int _cost = 0) :Neighbor(_key1, _cost), key2(_key2) {}
  23. };
  24. //generic class for a list with a typename class
  25. template <typename T>
  26. class List
  27. {
  28. protected:
  29.     //array of items
  30.     T *items;
  31.     //size of array
  32.     int size;
  33. public:
  34.     //constructor
  35.     List() :items(nullptr) {}
  36.     //add item function
  37.     void AddItem(T *_item)
  38.     {
  39.         //creates temporary array, 1 element more than the current item array
  40.         T *temp = new T[size + 1];
  41.         //adds current items to temp array
  42.         for (int i = 0; i < size; i++)
  43.         {
  44.             temp[i] = items[i];
  45.         }
  46.         //last item is the new item
  47.         temp[size] = *_item;
  48.         //increase size
  49.         size++;
  50.         //set items array
  51.         items = temp;
  52.     }
  53.     //remove item from item array
  54.     void RemoveItem(T *_item)
  55.     {
  56.         //check if item is in items array
  57.         if (Contains(_item))
  58.         {
  59.             //index of item
  60.             int index = 0;
  61.             //get index of item
  62.             for (int i = 0; i < size; i++)
  63.             {
  64.                 if (GetItem(i) == _item)
  65.                 {
  66.                     index = i;
  67.                     break;
  68.                 }
  69.             }
  70.             //temp array
  71.             T *_temp = new T[size - 1];
  72.             //copy items from items array to temp array, excluding the item
  73.             for (int i = 0; i < index; i++)
  74.             {
  75.                 _temp[i] = items[i];
  76.             }
  77.             for (int i = index; i < size - 1; i++)
  78.             {
  79.                 _temp[i] = items[i + 1];
  80.             }
  81.             //set items array
  82.             items = _temp;
  83.             //decrease items size
  84.             size--;
  85.         }
  86.     }
  87.     //get item from items array by index
  88.     T *GetItem(int i)
  89.     {
  90.         return &items[i];
  91.     }
  92.     //return size of items array
  93.     int Count()
  94.     {
  95.         return size;
  96.     }
  97.     //check if item is contained in items array
  98.     bool Contains(T *item)
  99.     {
  100.         for (int i = 0; i < Count(); i++)
  101.         {
  102.             T *_t = GetItem(i);
  103.             if (_t == item)
  104.             {
  105.                 return true;
  106.             }
  107.         }
  108.         return false;
  109.     }
  110.     //reverse the order of the list
  111.     void Reverse()
  112.     {
  113.         //make temporary array of the same size
  114.         T *_temp = new T[size];
  115.         for (int i = size - 1; i >= 0; i--)
  116.         {//add the elements backwards
  117.             _temp[size - i - 1] = items[i];
  118.         }
  119.         //set items array
  120.         items = _temp;
  121.  
  122.     }
  123. };
  124. //crossroad class
  125. class CrossRoad
  126. {
  127. protected:
  128.     //name of crossroad
  129.     string name;
  130.     //neighbors of crossroad, and distance to reach them
  131.     List<Neighbor> neighbors;
  132. public:
  133.     //constructor
  134.     CrossRoad(string _name = "") :name(_name) {}
  135.     string Name()
  136.     {
  137.         return name;
  138.     }
  139.     //check if neighbor is contained.
  140.     //can't use default list function for Contained, since we're using a list of CrossRoadNeighbor, not CrossRoad.
  141.     //i wanted to store the distance in something, so i had to do it like this
  142.     bool ContainsNeighbor(CrossRoad *_neighbor)
  143.     {
  144.         for (int i = 0; i < neighbors.Count(); i++)
  145.         {
  146.             if (neighbors.GetItem(i)->key1 == _neighbor)
  147.             {
  148.                 return true;
  149.             }
  150.         }
  151.         return false;
  152.     }
  153.     //add new neighbor + distance
  154.     void AddNeighbor(CrossRoad *_neighbor, int _distance, bool DoubleSided)
  155.     {
  156.         if (!ContainsNeighbor(_neighbor)) {
  157.             Neighbor temp;//(_neighbor, _distance);
  158.             temp.key1 = _neighbor;
  159.             temp.cost = _distance;
  160.             neighbors.AddItem(&temp);
  161.             //function calls itself, won't end in infinite loop since we check if the crossroad is contained in neighbors
  162.             if (DoubleSided) {
  163.                 _neighbor->AddNeighbor(this, _distance,false);
  164.             }
  165.         }
  166.     }
  167.     //return neighbors
  168.     List<Neighbor> *Neighbors()
  169.     {
  170.         return &neighbors;
  171.     }
  172. };
  173. //used for the CameFrom list
  174. //key1 is the key
  175. //key2 is the parent of key1
  176. //key3 is the cost so far
  177.  
  178.  
  179. //list of trio
  180. //has multiple functions to get values based on keys
  181. class TrioList :public List<CameFromTrio>
  182. {
  183. public:
  184.     CrossRoad *GetKey(CrossRoad *item)
  185.     {
  186.         for (int i = 0; i < size; i++)
  187.         {
  188.             if (items[i].key1->Name() == item->Name())
  189.             {
  190.                 return items[i].key2;
  191.             }
  192.         }
  193.         return nullptr;
  194.     }
  195.     CrossRoad *GetKeyValue(CrossRoad *item)
  196.     {
  197.         for (int i = 0; i < size; i++)
  198.         {
  199.             if (items[i].key2->Name() == item->Name())
  200.             {
  201.                 return items[i].key1;
  202.             }
  203.         }
  204.         return nullptr;
  205.     }
  206.     int GetCostSoFar(CrossRoad *item)
  207.     {
  208.         for (int i = 0; i < size; i++)
  209.         {
  210.             if (items[i].key1 == item)
  211.             {
  212.                 return items[i].cost;
  213.             }
  214.         }
  215.         return 0;
  216.     }
  217.     bool Contains(CrossRoad *item)
  218.     {
  219.         for (int i = 0; i < size; i++)
  220.         {
  221.             if (items[i].key1 == item)
  222.                 return true;
  223.         }
  224.         return false;
  225.     }
  226. };
  227. //get path
  228. List<CrossRoad> * Path(CrossRoad *_start, CrossRoad *_end) {
  229.     List<CrossRoad> storeIn;
  230.     //start at the starting node
  231.     CrossRoad *cur = _start;
  232.     //list of trios
  233.     TrioList CameFrom;
  234.     //add the starting node, it comes from itself, 0 cost
  235.     CameFrom.AddItem(new CameFromTrio(_start, _start, 0));
  236.     //frontier, contains all the nodes we're about to check
  237.     List<CrossRoad> frontier;
  238.     //add starting node
  239.     frontier.AddItem(cur);
  240.     //do cycle until frontier is empty
  241.     while (frontier.Count() > 0)
  242.     {
  243.         //remove cur item
  244.         //if we had coordinates, we could use a priority que to remove the item closest to the goal, would make the process a lot faster
  245.         cur = frontier.GetItem(0);
  246.         frontier.RemoveItem(cur);
  247.         //if we've reached the end, reconstruct the path
  248.         if (cur->Name() == _end->Name())
  249.         {
  250.             //add end
  251.             storeIn.AddItem(cur);
  252.             //get number of connections;
  253.             //we're not necessarily going to check everyone, but we need a limit
  254.             int cost = CameFrom.Count();
  255.             for (int i = 0; i < cost; i++)
  256.             {
  257.                 //next is the element that cur came from
  258.                 CrossRoad *next = CameFrom.GetKey(cur);
  259.                 //add next to the path
  260.                 storeIn.AddItem(next);
  261.                 //if we've reached the start, reverse the path
  262.                 //now start is at the begining of the path, end is at the end
  263.                 if (next->Name() == _start->Name())
  264.                 {
  265.                     storeIn.Reverse();
  266.                     return &storeIn;
  267.                 }
  268.                 cur = next;
  269.             }
  270.         }
  271.         //get neighbors
  272.         List<Neighbor> *neighbors = cur->Neighbors();
  273.         for (int i = 0; i < neighbors->Count(); i++)
  274.         {
  275.             Neighbor *_next = neighbors->GetItem(i);
  276.             CrossRoad *next = _next->key1;
  277.             int newCost = CameFrom.GetCostSoFar(cur) + _next->cost;
  278.             if (!CameFrom.Contains(next) || CameFrom.GetCostSoFar(cur) < newCost)
  279.             {
  280.                 //add next to frontier
  281.                 frontier.AddItem(next);
  282.                 //get distance to next crossroad
  283.                 //add next to camefrom
  284.                 CameFrom.AddItem(new CameFromTrio(next, cur, newCost));
  285.             }
  286.         }
  287.     }
  288.     return &storeIn;
  289. }
  290.  
  291. bool PathExists(CrossRoad *_start, CrossRoad *_end)
  292. {
  293.     List<CrossRoad> _path = *Path(_start, _end);
  294.     return _path.Count() > 1;
  295. }
  296. /*
  297. void testTextFileOutput() {
  298.     ofstream text_file("test.txt");
  299.  
  300.     text_file << "This is my text file\n";
  301.     text_file << 10 << ' ' << 5.6;
  302.  
  303.     text_file.close();
  304. }
  305.  
  306. void testBinaryFileOutput() {
  307.     ofstream binary_file("test.bin", ios::binary);
  308.  
  309.     for (int i = 0; i <= 20; ++i) {
  310.         binary_file.put((char)i);
  311.     }
  312.  
  313.     int numbers[] = { 1.2, 3.4, 5.6, 7.8 };
  314.     binary_file.write((const char*)numbers, sizeof(numbers));
  315.  
  316.     binary_file.close();
  317. }
  318.  
  319. void testTextFileInput() {
  320.     ifstream text_file("test.txt");
  321.  
  322.     char line[100];
  323.     text_file.getline(line, 100);
  324.  
  325.     int first_number;
  326.     int second_number;
  327.     text_file >> first_number >> second_number;
  328.  
  329.     cout << "line = " << line << '\n';
  330.     cout << "first_number = " << first_number << '\n';
  331.     cout << "second_number = " << second_number << '\n';
  332.  
  333.     text_file.close();
  334. }
  335.  
  336. void testBinaryFileInput() {
  337.     ifstream binary_file("test.bin", ios::binary);
  338.  
  339.     for (int i = 0; i <= 20; ++i) {
  340.         cout << binary_file.get() << '\n';
  341.     }
  342.  
  343.     int numbers[4];
  344.     binary_file.read((char*)numbers, 4 * sizeof(int));
  345.  
  346.     for (int i = 0; i < 4; ++i) {
  347.         cout << numbers[i] << '\n';
  348.     }
  349.  
  350.     binary_file.seekg(-2 * sizeof(int), ios::cur);
  351.     cout << binary_file.tellg() << '\n';
  352.  
  353.     int number;
  354.     binary_file.read((char*)&number, sizeof(int));
  355.     cout << "number = " << number << '\n';
  356.  
  357.     binary_file.close();
  358. }
  359. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement