// File: /workspace/github_cpp_makefile_star2_O2/rilutham[P]gotojakarta/go-to-jakarta.cpp
// Function: main
int main( int argc, char *argv[] )
{
  // Creating Map of West Java
  for(int i=0; i<MAX_CITIES; i++)
    for(int j=0; j<MAX_CITIES; j++)
      WestJavaMap[i][j]=-1.0;

  // Define distance between two cities 
  // From Plat Z
  WestJavaMap[Pangandaran][Banjar]=63;
  WestJavaMap[Banjar][Ciamis]=26;
  WestJavaMap[Banjar][Kuningan]=83;
  WestJavaMap[Ciamis][Tasikmalaya]=19;
  WestJavaMap[Ciamis][Kuningan]=68;
  WestJavaMap[Tasikmalaya][Garut]=56;
  WestJavaMap[Tasikmalaya][Bandung]=93;
  WestJavaMap[Garut][Bandung]=51;
  WestJavaMap[Sumedang][Bandung]=33;

  // From Plat E
  WestJavaMap[Kuningan][Cirebon]=32;
  WestJavaMap[Kuningan][Majalengka]=58;
  WestJavaMap[Cirebon][Indramayu]=55;
  WestJavaMap[Cirebon][Majalengka]=43;
  WestJavaMap[Majalengka][Sumedang]=47;
  WestJavaMap[Majalengka][Subang]=85;
  WestJavaMap[Indramayu][Karawang]=115;

  // From Plat D
  WestJavaMap[Bandung][Subang]=60;
  WestJavaMap[Bandung][Cimahi]=35;
  WestJavaMap[Cimahi][Purwakarta]=55;
  WestJavaMap[Cimahi][Cianjur]=56;

  // From Plat T
  WestJavaMap[Subang][Purwakarta]=45;
  WestJavaMap[Purwakarta][Karawang]=30;
  WestJavaMap[Karawang][Bekasi]=45;

  // From Plat F
  WestJavaMap[Cianjur][Sukabumi]=30;
  WestJavaMap[Cianjur][Bogor]=69;
  WestJavaMap[Sukabumi][Bogor]=72;
  WestJavaMap[Bogor][Depok]=22;

  // From Plat B
  WestJavaMap[Depok][Jakarta]=26;
  WestJavaMap[Bekasi][Jakarta]=27;

  // City names
  CityNames[Garut].assign("Garut");
  CityNames[Jakarta].assign("Jakarta");
  CityNames[Tasikmalaya].assign("Tasikmalaya");
  CityNames[Ciamis].assign("Ciamis");
  CityNames[Banjar].assign("Banjar");
  CityNames[Pangandaran].assign("Pangandaran");
  CityNames[Sumedang].assign("Sumedang");
  CityNames[Bandung].assign("Bandung");
  CityNames[Cimahi].assign("Cimahi");
  CityNames[Kuningan].assign("Kuningan");
  CityNames[Majalengka].assign("Majalengka");
  CityNames[Cirebon].assign("Cirebon");
  CityNames[Indramayu].assign("Indramayu");
  CityNames[Subang].assign("Subang");
  CityNames[Karawang].assign("Karawang");
  CityNames[Purwakarta].assign("Purwakarta");
  CityNames[Cianjur].assign("Cianjur");
  CityNames[Sukabumi].assign("Sukabumi");
  CityNames[Bogor].assign("Bogor");
  CityNames[Depok].assign("Depok");
  CityNames[Bekasi].assign("Bekasi");

  ENUM_CITIES initCity = Garut;
  if(argc == 2)
  {
    bool found = false;
    for(size_t i=0; i<CityNames.size(); i++)
      if(CityNames[i].compare(argv[1])==0)
      {
        initCity = (ENUM_CITIES)i;
        found = true;
        break;
      }
    if(not found)
    {
      cout << "Kota "<<argv[1]<<" tidak ditemukan pada peta Jawa Barat, silahkan ulangi!\n";
      cout << "Gunakan kapital pada huruf pertama nama kota. Contoh: Garut, Pangandaran.\n";
      return(1);
    }
  }

  // An instance of A* search class
	AStarSearch<PathSearchNode> astarsearch;

	unsigned int SearchCount = 0;
	const unsigned int NumSearches = 1;

	while(SearchCount < NumSearches)
	{
		// Create a start state
		PathSearchNode nodeStart;
		nodeStart.city = initCity;

		// Define the goal state, always Jakarta!
		PathSearchNode nodeEnd;
		nodeEnd.city = Jakarta;

		// Set Start and goal states
		astarsearch.SetStartAndGoalStates( nodeStart, nodeEnd );

		unsigned int SearchState;
		unsigned int SearchSteps = 0;

		do
		{
			SearchState = astarsearch.SearchStep();
			SearchSteps++;

	#if DEBUG_LISTS

			cout << "Steps:" << SearchSteps << "\n";

			int len = 0;

			cout << "Open:\n";
			PathSearchNode *p = astarsearch.GetOpenListStart();
			while( p )
			{
				len++;
	#if !DEBUG_LIST_LENGTHS_ONLY
				((PathSearchNode *)p)->PrintNodeInfo();
	#endif
				p = astarsearch.GetOpenListNext();

			}
			cout << "Open list has " << len << " nodes\n";

			len = 0;

			cout << "Closed:\n";
			p = astarsearch.GetClosedListStart();
			while( p )
			{
				len++;
	#if !DEBUG_LIST_LENGTHS_ONLY
				p->PrintNodeInfo();
	#endif
				p = astarsearch.GetClosedListNext();
			}

			cout << "Closed list has " << len << " nodes\n";
	#endif

		}
		while( SearchState == AStarSearch<PathSearchNode>::SEARCH_STATE_SEARCHING );

		if( SearchState == AStarSearch<PathSearchNode>::SEARCH_STATE_SUCCEEDED )
		{
			cout << "Pencarian rute terpendek menuju Jakarta ditemukan!\n";
      PathSearchNode *node = astarsearch.GetSolutionStart();
      cout << "Berikut kota-kota yang harus dilalui:\n";
      int steps = 0;
      node->PrintNodeInfo();
      for( ;; )
      {
        node = astarsearch.GetSolutionNext();
        if( !node ) break;
        node->PrintNodeInfo();
        steps ++;
      };
      cout << "Langkah Solusi : " << steps << endl;
      // Once you're done with the solution you can free the nodes up
			astarsearch.FreeSolutionNodes();
		}
		else if( SearchState == AStarSearch<PathSearchNode>::SEARCH_STATE_FAILED )
		{
			cout << "Search terminated. Did not find goal state\n";
		}
		// Display the number of loops the search went through
		cout << "Jumlah langkah pencarian : " << SearchSteps << "\n";
		SearchCount ++;
		astarsearch.EnsureMemoryFreed();
	}

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0xa8, %rsp
movq %rsi, %rbx
movl %edi, %r14d
leaq 0x4cbb(%rip), %rax      # 0x6120
xorl %ecx, %ecx
cmpq $0x15, %rcx
je 0x148a
xorl %edx, %edx
cmpq $0x15, %rdx
je 0x1481
movl $0xbf800000, (%rax,%rdx,4) # imm = 0xBF800000
incq %rdx
jmp 0x146f
incq %rcx
addq $0x54, %rax
jmp 0x1467
movl $0x427c0000, 0x4e40(%rip) # imm = 0x427C0000
movl $0x41d00000, %eax       # imm = 0x41D00000
movl %eax, 0x4ddd(%rip)      # 0x627c
movl $0x42a60000, 0x4deb(%rip) # imm = 0x42A60000
movl $0x41980000, 0x4d71(%rip) # imm = 0x41980000
movl $0x42880000, 0x4d83(%rip) # imm = 0x42880000
movl $0x42600000, 0x4d01(%rip) # imm = 0x42600000
movl $0x42ba0000, 0x4d13(%rip) # imm = 0x42BA0000
movl $0x424c0000, 0x4c61(%rip) # imm = 0x424C0000
movl $0x42040000, 0x4e4f(%rip) # imm = 0x42040000
movabsq $0x4200000042680000, %rcx # imm = 0x4200000042680000
movq %rcx, 0x4f46(%rip)      # 0x643c
movl $0x425c0000, 0x4fec(%rip) # imm = 0x425C0000
movl $0x422c0000, 0x4fda(%rip) # imm = 0x422C0000
movl $0x423c0000, 0x4f6c(%rip) # imm = 0x423C0000
movl $0x42aa0000, 0x4f7e(%rip) # imm = 0x42AA0000
movl $0x42e60000, 0x5020(%rip) # imm = 0x42E60000
movl $0x42700000, 0x4e6e(%rip) # imm = 0x42700000
movl $0x420c0000, 0x4e50(%rip) # imm = 0x420C0000
movabsq $0x42600000425c0000, %rcx # imm = 0x42600000425C0000
movq %rcx, 0x4eaf(%rip)      # 0x63fc
movl $0x42340000, %ecx       # imm = 0x42340000
movl %ecx, 0x5048(%rip)      # 0x65a0
movl $0x41f00000, 0x50e2(%rip) # imm = 0x41F00000
movl %ecx, 0x50a0(%rip)      # 0x6608
movabsq $0x428a000041f00000, %rcx # imm = 0x428A000041F00000
movq %rcx, 0x512b(%rip)      # 0x66a4
movl $0x42900000, 0x5179(%rip) # imm = 0x42900000
movl $0x41b00000, 0x51c7(%rip) # imm = 0x41B00000
movl %eax, 0x51cd(%rip)      # 0x6760
movl $0x41d80000, 0x5217(%rip) # imm = 0x41D80000
movq 0x4b64(%rip), %rdi      # 0x6108
leaq 0x1a85(%rip), %rsi      # 0x3030
callq 0x1190
movq 0x4b51(%rip), %rdi      # 0x6108
addq $0x20, %rdi
leaq 0x1a74(%rip), %rsi      # 0x3036
callq 0x1190
movq 0x4b3a(%rip), %rdi      # 0x6108
addq $0x40, %rdi
leaq 0x1a65(%rip), %rsi      # 0x303e
callq 0x1190
movq 0x4b23(%rip), %rdi      # 0x6108
addq $0x60, %rdi
leaq 0x1a5a(%rip), %rsi      # 0x304a
callq 0x1190
movq 0x4b0c(%rip), %rdi      # 0x6108
subq $-0x80, %rdi
leaq 0x1a4a(%rip), %rsi      # 0x3051
callq 0x1190
movl $0xa0, %edi
addq 0x4af0(%rip), %rdi      # 0x6108
leaq 0x1a39(%rip), %rsi      # 0x3058
callq 0x1190
movl $0xc0, %edi
addq 0x4ad8(%rip), %rdi      # 0x6108
leaq 0x1a2d(%rip), %rsi      # 0x3064
callq 0x1190
movl $0xe0, %edi
addq 0x4ac0(%rip), %rdi      # 0x6108
leaq 0x1a1e(%rip), %rsi      # 0x306d
callq 0x1190
movl $0x100, %edi            # imm = 0x100
addq 0x4aa8(%rip), %rdi      # 0x6108
leaq 0x1a0e(%rip), %rsi      # 0x3075
callq 0x1190
movl $0x120, %edi            # imm = 0x120
addq 0x4a90(%rip), %rdi      # 0x6108
leaq 0x19fd(%rip), %rsi      # 0x307c
callq 0x1190
movl $0x140, %edi            # imm = 0x140
addq 0x4a78(%rip), %rdi      # 0x6108
leaq 0x19ee(%rip), %rsi      # 0x3085
callq 0x1190
movl $0x160, %edi            # imm = 0x160
addq 0x4a60(%rip), %rdi      # 0x6108
leaq 0x19e1(%rip), %rsi      # 0x3090
callq 0x1190
movl $0x180, %edi            # imm = 0x180
addq 0x4a48(%rip), %rdi      # 0x6108
leaq 0x19d1(%rip), %rsi      # 0x3098
callq 0x1190
movl $0x1a0, %edi            # imm = 0x1A0
addq 0x4a30(%rip), %rdi      # 0x6108
leaq 0x19c3(%rip), %rsi      # 0x30a2
callq 0x1190
movl $0x1c0, %edi            # imm = 0x1C0
addq 0x4a18(%rip), %rdi      # 0x6108
leaq 0x19b2(%rip), %rsi      # 0x30a9
callq 0x1190
movl $0x1e0, %edi            # imm = 0x1E0
addq 0x4a00(%rip), %rdi      # 0x6108
leaq 0x19a3(%rip), %rsi      # 0x30b2
callq 0x1190
movl $0x200, %edi            # imm = 0x200
addq 0x49e8(%rip), %rdi      # 0x6108
leaq 0x1996(%rip), %rsi      # 0x30bd
callq 0x1190
movl $0x220, %edi            # imm = 0x220
addq 0x49d0(%rip), %rdi      # 0x6108
leaq 0x1986(%rip), %rsi      # 0x30c5
callq 0x1190
movl $0x240, %edi            # imm = 0x240
addq 0x49b8(%rip), %rdi      # 0x6108
leaq 0x1977(%rip), %rsi      # 0x30ce
callq 0x1190
movl $0x260, %edi            # imm = 0x260
addq 0x49a0(%rip), %rdi      # 0x6108
leaq 0x1965(%rip), %rsi      # 0x30d4
callq 0x1190
movl $0x280, %edi            # imm = 0x280
addq 0x4988(%rip), %rdi      # 0x6108
leaq 0x1953(%rip), %rsi      # 0x30da
callq 0x1190
xorl %r15d, %r15d
cmpl $0x2, %r14d
jne 0x17d2
xorl %r14d, %r14d
xorl %r15d, %r15d
movq 0x496e(%rip), %rax      # 0x6110
movq 0x495f(%rip), %rdi      # 0x6108
subq %rdi, %rax
sarq $0x5, %rax
cmpq %rax, %r15
jae 0x1882
addq %r14, %rdi
movq 0x8(%rbx), %rsi
callq 0x1050
testl %eax, %eax
je 0x17d2
incq %r15
addq $0x20, %r14
jmp 0x179b
leaq -0xc0(%rbp), %rbx
movq %rbx, %rdi
callq 0x1a4c
leaq -0x20(%rbp), %rsi
movl %r15d, (%rsi)
leaq -0x1c(%rbp), %rdx
movl $0x1, (%rdx)
movq %rbx, %rdi
callq 0x1ac8
xorl %r14d, %r14d
movq %rbx, %rdi
callq 0x1b84
incl %r14d
cmpl $0x1, %eax
je 0x17fd
cmpl $0x3, %eax
je 0x18ca
cmpl $0x2, %eax
jne 0x1910
movq 0x47aa(%rip), %rdi      # 0x5fd0
leaq 0x193e(%rip), %rsi      # 0x316b
callq 0x1110
movq -0x70(%rbp), %rbx
movq %rbx, -0x60(%rbp)
movq 0x478f(%rip), %rdi      # 0x5fd0
leaq 0x1957(%rip), %rsi      # 0x319f
callq 0x1110
leaq 0x1c(%rbx), %rdi
testq %rbx, %rbx
cmoveq %rbx, %rdi
callq 0x1402
xorl %ebx, %ebx
movq -0x60(%rbp), %rax
testq %rax, %rax
je 0x18df
movq 0x8(%rax), %rdi
testq %rdi, %rdi
je 0x18df
movq %rdi, -0x60(%rbp)
addq $0x1c, %rdi
callq 0x1402
incl %ebx
jmp 0x185f
movq 0x4747(%rip), %r14      # 0x5fd0
leaq 0x1851(%rip), %rsi      # 0x30e1
movq %r14, %rdi
callq 0x1110
movq 0x8(%rbx), %rsi
movq %rax, %rdi
callq 0x1110
leaq 0x183c(%rip), %rsi      # 0x30e7
movq %rax, %rdi
callq 0x1110
leaq 0x1866(%rip), %rsi      # 0x3120
movq %r14, %rdi
callq 0x1110
pushq $0x1
popq %rax
jmp 0x1956
movq 0x46ff(%rip), %rdi      # 0x5fd0
leaq 0x1900(%rip), %rsi      # 0x31d8
callq 0x1110
jmp 0x1910
movq 0x46ea(%rip), %rdi      # 0x5fd0
leaq 0x18d9(%rip), %rsi      # 0x31c6
callq 0x1110
movq %rax, %rdi
movl %ebx, %esi
callq 0x1170
movq %rax, %rdi
callq 0x1090
leaq -0xc0(%rbp), %rdi
callq 0x1dc0
movq 0x46b9(%rip), %rdi      # 0x5fd0
leaq 0x18e6(%rip), %rsi      # 0x3204
callq 0x1110
movl %r14d, %esi
movq %rax, %rdi
callq 0x10d0
leaq 0x17e9(%rip), %rsi      # 0x311e
movq %rax, %rdi
callq 0x1110
leaq -0xc0(%rbp), %rbx
movq %rbx, %rdi
callq 0x1e08
movq %rbx, %rdi
callq 0x1e36
xorl %eax, %eax
addq $0xa8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
jmp 0x196e
jmp 0x196e
jmp 0x196e
jmp 0x196e
jmp 0x196e
movq %rax, %rbx
leaq -0xc0(%rbp), %rdi
callq 0x1e36
movq %rbx, %rdi
callq 0x1180
nop