├── .gitattributes ├── .gitignore ├── AlgebraLib ├── AlgebraLib.cpp ├── AlgebraLib.h ├── AlgebraLib.vcxproj └── AlgebraLib.vcxproj.filters ├── LICENSE ├── Pathfinding.sln ├── Pathfinding ├── AStarWalker.cpp ├── AStarWalker.h ├── BFSWalker.cpp ├── BFSWalker.h ├── BestFSWalker.cpp ├── BestFSWalker.h ├── DFSWalker.cpp ├── DFSWalker.h ├── DijkstraWalker.cpp ├── DijkstraWalker.h ├── Graph.cpp ├── Graph.h ├── GraphNode.cpp ├── GraphNode.h ├── Pathfinding.cpp ├── Pathfinding.vcxproj ├── Pathfinding.vcxproj.filters ├── Walker.cpp └── Walker.h └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | project.fragment.lock.json 46 | artifacts/ 47 | 48 | *_i.c 49 | *_p.c 50 | *_i.h 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.tmp_proj 65 | *.log 66 | *.vspscc 67 | *.vssscc 68 | .builds 69 | *.pidb 70 | *.svclog 71 | *.scc 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opendb 81 | *.opensdf 82 | *.sdf 83 | *.cachefile 84 | *.VC.db 85 | *.VC.VC.opendb 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 150 | # checkin your Azure Web App publish settings, but sensitive information contained 151 | # in these scripts will be unencrypted 152 | PublishScripts/ 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.jfm 193 | *.pfx 194 | *.publishsettings 195 | node_modules/ 196 | orleans.codegen.cs 197 | 198 | # Since there are multiple workflows, uncomment next line to ignore bower_components 199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 200 | #bower_components/ 201 | 202 | # RIA/Silverlight projects 203 | Generated_Code/ 204 | 205 | # Backup & report files from converting an old project file 206 | # to a newer Visual Studio version. Backup files are not needed, 207 | # because we have git ;-) 208 | _UpgradeReport_Files/ 209 | Backup*/ 210 | UpgradeLog*.XML 211 | UpgradeLog*.htm 212 | 213 | # SQL Server files 214 | *.mdf 215 | *.ldf 216 | 217 | # Business Intelligence projects 218 | *.rdl.data 219 | *.bim.layout 220 | *.bim_*.settings 221 | 222 | # Microsoft Fakes 223 | FakesAssemblies/ 224 | 225 | # GhostDoc plugin setting file 226 | *.GhostDoc.xml 227 | 228 | # Node.js Tools for Visual Studio 229 | .ntvs_analysis.dat 230 | 231 | # Visual Studio 6 build log 232 | *.plg 233 | 234 | # Visual Studio 6 workspace options file 235 | *.opt 236 | 237 | # Visual Studio LightSwitch build output 238 | **/*.HTMLClient/GeneratedArtifacts 239 | **/*.DesktopClient/GeneratedArtifacts 240 | **/*.DesktopClient/ModelManifest.xml 241 | **/*.Server/GeneratedArtifacts 242 | **/*.Server/ModelManifest.xml 243 | _Pvt_Extensions 244 | 245 | # Paket dependency manager 246 | .paket/paket.exe 247 | paket-files/ 248 | 249 | # FAKE - F# Make 250 | .fake/ 251 | 252 | # JetBrains Rider 253 | .idea/ 254 | *.sln.iml 255 | 256 | # CodeRush 257 | .cr/ 258 | 259 | # Python Tools for Visual Studio (PTVS) 260 | __pycache__/ 261 | *.pyc -------------------------------------------------------------------------------- /AlgebraLib/AlgebraLib.cpp: -------------------------------------------------------------------------------- 1 | #include "AlgebraLib.h" 2 | #include 3 | #include 4 | 5 | namespace Mat4D 6 | { 7 | CVector4D::CVector4D() : 8 | val{} 9 | { 10 | } 11 | 12 | CVector4D::CVector4D(const CVector4D & cpy) : 13 | val{ cpy.x, cpy.y, cpy.z, cpy.w } 14 | { 15 | } 16 | 17 | CVector4D::CVector4D(float x_, float y_, float z_, float w_) : 18 | x(x_), 19 | y(y_), 20 | z(z_), 21 | w(w_) 22 | { 23 | } 24 | 25 | CVector4D& CVector4D::operator+=(const CVector4D & rhs) 26 | { 27 | x += rhs.x; 28 | y += rhs.y; 29 | z += rhs.z; 30 | w += rhs.w; 31 | return *this; 32 | } 33 | 34 | CVector4D& CVector4D::operator*=(float scalar) 35 | { 36 | x *= scalar; 37 | y *= scalar; 38 | z *= scalar; 39 | w *= scalar; 40 | return *this; 41 | } 42 | 43 | CVector4D& CVector4D::operator-=(const CVector4D & rhs) 44 | { 45 | x -= rhs.x; 46 | y -= rhs.y; 47 | z -= rhs.z; 48 | w -= rhs.w; 49 | return *this; 50 | } 51 | 52 | CVector4D& CVector4D::operator/=(float scalar) 53 | { 54 | x /= scalar; 55 | y /= scalar; 56 | z /= scalar; 57 | w /= scalar; 58 | return *this; 59 | } 60 | 61 | float CVector4D::Dot(const CVector4D& b) const 62 | { 63 | return x * b.x + y * b.y + z * b.z + w * b.w; 64 | } 65 | 66 | float CVector4D::Magnitude() const 67 | { 68 | return sqrtf(this->Dot(*this)); 69 | } 70 | 71 | CVector4D CVector4D::Cross(const CVector4D & b) const 72 | { 73 | return CVector4D( 74 | y * b.z - z * b.y, 75 | z * b.x - x * b.z, 76 | x * b.y - y * b.x, 0); 77 | } 78 | 79 | CVector4D CVector4D::Normalize() const 80 | { 81 | float magnitude = Magnitude(); 82 | return magnitude != 0 ? *this / magnitude : CVector4D(); 83 | } 84 | 85 | CVector4D operator*(CVector4D lhs, const CMatrix4D & rhs) 86 | { 87 | CVector4D r; 88 | r.x = lhs.x * rhs.m00; 89 | r.x += lhs.y * rhs.m10; 90 | r.x += lhs.z * rhs.m20; 91 | r.x += lhs.w * rhs.m30; 92 | 93 | r.y = lhs.x * rhs.m01; 94 | r.y += lhs.y * rhs.m11; 95 | r.y += lhs.z * rhs.m21; 96 | r.y += lhs.w * rhs.m31; 97 | 98 | r.z = lhs.x * rhs.m02; 99 | r.z += lhs.y * rhs.m12; 100 | r.z += lhs.z * rhs.m22; 101 | r.z += lhs.w * rhs.m32; 102 | 103 | r.w = lhs.x * rhs.m03; 104 | r.w += lhs.y * rhs.m13; 105 | r.w += lhs.z * rhs.m23; 106 | r.w += lhs.w * rhs.m33; 107 | 108 | return r; 109 | } 110 | 111 | CVector4D operator+(CVector4D lhs, const CVector4D & rhs) 112 | { 113 | lhs += rhs; 114 | return lhs; 115 | } 116 | 117 | CVector4D operator-(CVector4D lhs, const CVector4D & rhs) 118 | { 119 | lhs -= rhs; 120 | return lhs; 121 | } 122 | 123 | CVector4D operator*(CVector4D vec, float scalar) 124 | { 125 | vec *= scalar; 126 | return vec; 127 | } 128 | 129 | CVector4D operator*(float scalar, const CVector4D & vec) 130 | { 131 | return vec * scalar; 132 | } 133 | 134 | CVector4D operator/(CVector4D vec, float scalar) 135 | { 136 | return vec /= scalar; 137 | } 138 | 139 | CVector4D operator*(CMatrix4D lhs, const CVector4D & rhs) 140 | { 141 | return CVector4D( 142 | lhs.r0.Dot(rhs), 143 | lhs.r1.Dot(rhs), 144 | lhs.r2.Dot(rhs), 145 | lhs.r3.Dot(rhs) 146 | ); 147 | } 148 | 149 | CMatrix4D operator*(CMatrix4D a, const CMatrix4D & b) 150 | { 151 | return 152 | { 153 | a.m[0][0] * b.m[0][0] + a.m[0][1] * b.m[1][0] + a.m[0][2] * b.m[2][0] + a.m[0][3] * b.m[3][0], a.m[0][0] * b.m[0][1] + a.m[0][1] * b.m[1][1] + a.m[0][2] * b.m[2][1] + a.m[0][3] * b.m[3][1], a.m[0][0] * b.m[0][2] + a.m[0][1] * b.m[1][2] + a.m[0][2] * b.m[2][2] + a.m[0][3] * b.m[3][2], a.m[0][0] * b.m[0][3] + a.m[0][1] * b.m[1][3] + a.m[0][2] * b.m[2][3] + a.m[0][3] * b.m[3][3], 154 | a.m[1][0] * b.m[0][0] + a.m[1][1] * b.m[1][0] + a.m[1][2] * b.m[2][0] + a.m[1][3] * b.m[3][0], a.m[1][0] * b.m[0][1] + a.m[1][1] * b.m[1][1] + a.m[1][2] * b.m[2][1] + a.m[1][3] * b.m[3][1], a.m[1][0] * b.m[0][2] + a.m[1][1] * b.m[1][2] + a.m[1][2] * b.m[2][2] + a.m[1][3] * b.m[3][2], a.m[1][0] * b.m[0][3] + a.m[1][1] * b.m[1][3] + a.m[1][2] * b.m[2][3] + a.m[1][3] * b.m[3][3], 155 | a.m[2][0] * b.m[0][0] + a.m[2][1] * b.m[1][0] + a.m[2][2] * b.m[2][0] + a.m[2][3] * b.m[3][0], a.m[2][0] * b.m[0][1] + a.m[2][1] * b.m[1][1] + a.m[2][2] * b.m[2][1] + a.m[2][3] * b.m[3][1], a.m[2][0] * b.m[0][2] + a.m[2][1] * b.m[1][2] + a.m[2][2] * b.m[2][2] + a.m[2][3] * b.m[3][2], a.m[2][0] * b.m[0][3] + a.m[2][1] * b.m[1][3] + a.m[2][2] * b.m[2][3] + a.m[2][3] * b.m[3][3], 156 | a.m[3][0] * b.m[0][0] + a.m[3][1] * b.m[1][0] + a.m[3][2] * b.m[2][0] + a.m[3][3] * b.m[3][0], a.m[3][0] * b.m[0][1] + a.m[3][1] * b.m[1][1] + a.m[3][2] * b.m[2][1] + a.m[3][3] * b.m[3][1], a.m[3][0] * b.m[0][2] + a.m[3][1] * b.m[1][2] + a.m[3][2] * b.m[2][2] + a.m[3][3] * b.m[3][2], a.m[3][0] * b.m[0][3] + a.m[3][1] * b.m[1][3] + a.m[3][2] * b.m[2][3] + a.m[3][3] * b.m[3][3] 157 | }; 158 | /*for (int i = 0; i < 4; i++) 159 | for (int j = 0; j < 4; j++) 160 | for (int k = 0; k < 4; k++) 161 | R.m[i][j] += lhs.m[i][k] * rhs.m[k][j];*/ 162 | } 163 | 164 | CMatrix4D::CMatrix4D() : 165 | v{} 166 | { 167 | } 168 | 169 | CMatrix4D::CMatrix4D(float * a) 170 | { 171 | *this = a; 172 | } 173 | 174 | CMatrix4D::CMatrix4D(const CMatrix4D & cpy) : 175 | v 176 | { 177 | cpy.m00, cpy.m01, cpy.m02, cpy.m03, 178 | cpy.m10, cpy.m11, cpy.m12, cpy.m13, 179 | cpy.m20, cpy.m21, cpy.m22, cpy.m23, 180 | cpy.m30, cpy.m31, cpy.m32, cpy.m33 181 | } 182 | { 183 | 184 | } 185 | 186 | CMatrix4D::CMatrix4D(const CVector4D & row1, const CVector4D & row2, const CVector4D & row3, const CVector4D & row4) 187 | { 188 | r0 = row1; 189 | r1 = row2; 190 | r2 = row3; 191 | r3 = row4; 192 | } 193 | 194 | CMatrix4D::CMatrix4D 195 | ( 196 | float i00, float i01, float i02, float i03, 197 | float i10, float i11, float i12, float i13, 198 | float i20, float i21, float i22, float i23, 199 | float i30, float i31, float i32, float i33 200 | ) : 201 | v 202 | { 203 | i00, i01, i02, i03, 204 | i10, i11, i12, i13, 205 | i20, i21, i22, i23, 206 | i30, i31, i32, i33 207 | } 208 | { 209 | } 210 | 211 | CMatrix4D& CMatrix4D::operator*=(const CMatrix4D & rhs) 212 | { 213 | *this = *this * rhs; 214 | return *this; 215 | } 216 | 217 | CMatrix4D& CMatrix4D::operator=(float * a) 218 | { 219 | v[0] = a[0]; v[1] = a[1]; v[2] = a[2]; v[3] = a[3]; 220 | v[4] = a[4]; v[5] = a[5]; v[6] = a[6]; v[7] = a[7]; 221 | v[8] = a[8]; v[9] = a[9]; v[10] = a[10]; v[11] = a[11]; 222 | v[12] = a[12]; v[13] = a[13]; v[14] = a[14]; v[15] = a[15]; 223 | return *this; 224 | } 225 | 226 | void CMatrix4D::Identity() 227 | { 228 | Zero(); 229 | m00 = 1.f; 230 | m11 = 1.f; 231 | m22 = 1.f; 232 | m33 = 1.f; 233 | } 234 | 235 | void CMatrix4D::Zero() 236 | { 237 | v[0] = 0; v[1] = 0; v[2] = 0; v[3] = 0; 238 | v[4] = 0; v[5] = 0; v[6] = 0; v[7] = 0; 239 | v[8] = 0; v[9] = 0; v[10] = 0; v[11] = 0; 240 | v[12] = 0; v[13] = 0; v[14] = 0; v[15] = 0; 241 | } 242 | 243 | CMatrix4D Scale(float sx, float sy, float sz) 244 | { 245 | return CMatrix4D 246 | ( 247 | sx, 0, 0, 0, 248 | 0, sy, 0, 0, 249 | 0, 0, sz, 0, 250 | 0, 0, 0, 1 251 | ); 252 | } 253 | 254 | CMatrix4D TranslateLH(float tx, float ty, float tz) 255 | { 256 | return CMatrix4D 257 | ( 258 | 1, 0, 0, 0, 259 | 0, 1, 0, 0, 260 | 0, 0, 1, 0, 261 | tx, ty, tz, 1 262 | ); 263 | } 264 | 265 | CMatrix4D RotateXLH(float theta) 266 | { 267 | return CMatrix4D( 268 | 1, 0, 0, 0, 269 | 0, cosf(theta), sin(theta), 0, 270 | 0, -sinf(theta), cosf(theta), 0, 271 | 0, 0, 0, 1 272 | ); 273 | } 274 | 275 | CMatrix4D RotateYLH(float theta) 276 | { 277 | return CMatrix4D( 278 | cosf(theta), 0, -sinf(theta), 0, 279 | 0, 1, 0, 0, 280 | sinf(theta), 0, cos(theta), 0, 281 | 0, 0, 0, 1 282 | ); 283 | } 284 | 285 | CMatrix4D RotateZLH(float theta) 286 | { 287 | return CMatrix4D( 288 | cosf(theta), sinf(theta), 0, 0, 289 | -sinf(theta), cosf(theta), 0, 0, 290 | 0, 0, 1, 0, 291 | 0, 0, 0, 1 292 | ); 293 | } 294 | 295 | CMatrix4D LookAtLH(const CVector4D & eye, const CVector4D & at, const CVector4D up) 296 | { 297 | CVector4D zaxis = (at - eye).Normalize(); 298 | CVector4D xaxis = (up.Cross(zaxis)).Normalize(); 299 | CVector4D yaxis = zaxis.Cross(xaxis); 300 | 301 | return{ xaxis.x , yaxis.x , zaxis.x , 0, 302 | xaxis.y , yaxis.y , zaxis.y , 0, 303 | xaxis.z , yaxis.z , zaxis.z , 0, 304 | -xaxis.Dot(eye), -yaxis.Dot(eye), -zaxis.Dot(eye), 1 }; 305 | } 306 | 307 | CMatrix4D PerspectiveFovLH(float fovy, float aspect, float zn, float zf) 308 | { 309 | float sen = std::sinf(fovy * 0.5f); 310 | float yScale = sen != 0.0f ? std::cosf((fovy * 0.5f)) / sen : 0.f; 311 | 312 | float xScale = yScale / aspect; 313 | 314 | return{ xScale, 0, 0, 0, 315 | 0, yScale, 0, 0, 316 | 0, 0, zf / (zf - zn), 1, 317 | 0, 0, -zn*zf / (zf - zn), 0 }; 318 | 319 | } 320 | 321 | 322 | //Right handed system 323 | 324 | CMatrix4D TranslateRH(float tx, float ty, float tz) 325 | { 326 | return CMatrix4D 327 | ( 328 | 1, 0, 0, tx, 329 | 0, 1, 0, ty, 330 | 0, 0, 1, tz, 331 | 0, 0, 0, 1 332 | ); 333 | } 334 | 335 | CMatrix4D RotateXRH(float theta) 336 | { 337 | return CMatrix4D( 338 | 1, 0, 0, 0, 339 | 0, cosf(theta), -sin(theta), 0, 340 | 0, sinf(theta), cosf(theta), 0, 341 | 0, 0, 0, 1 342 | ); 343 | } 344 | 345 | CMatrix4D RotateYRH(float theta) 346 | { 347 | return CMatrix4D( 348 | cosf(theta), 0, sinf(theta), 0, 349 | 0, 1, 0, 0, 350 | -sinf(theta), 0, cos(theta), 0, 351 | 0, 0, 0, 1 352 | ); 353 | } 354 | 355 | CMatrix4D RotateZRH(float theta) 356 | { 357 | return CMatrix4D( 358 | cosf(theta), -sinf(theta), 0, 0, 359 | sinf(theta), cosf(theta), 0, 0, 360 | 0, 0, 1, 0, 361 | 0, 0, 0, 1 362 | ); 363 | } 364 | 365 | CMatrix4D LookAtRH(const CVector4D & eye, const CVector4D & at, const CVector4D up) 366 | { 367 | CVector4D zaxis = (eye - at).Normalize(); 368 | CVector4D xaxis = (up.Cross(zaxis)).Normalize(); 369 | CVector4D yaxis = zaxis.Cross(xaxis); 370 | 371 | return{ xaxis.x , yaxis.x , zaxis.x , 0, 372 | xaxis.y , yaxis.y , zaxis.y , 0, 373 | xaxis.z , yaxis.z , zaxis.z , 0, 374 | -xaxis.Dot(eye), -yaxis.Dot(eye), -zaxis.Dot(eye), 1 }; 375 | } 376 | 377 | CMatrix4D PerspectiveFovRH(float fovy, float aspect, float zn, float zf) 378 | { 379 | float sen = std::sinf(fovy * 0.5f); 380 | float yScale = sen != 0.0f ? std::cosf((fovy * 0.5f)) / sen : 0.f; 381 | 382 | float xScale = yScale / aspect; 383 | 384 | return{ 385 | xScale, 0, 0, 0, 386 | 0, yScale, 0, 0, 387 | 0, 0, zf / (zn - zf), -1, 388 | 0, 0, zn*zf / (zn - zf), 0 }; 389 | } 390 | 391 | } -------------------------------------------------------------------------------- /AlgebraLib/AlgebraLib.h: -------------------------------------------------------------------------------- 1 | #ifndef _SIMPLE_ALGEBRA_H_ 2 | #define _SIMPLE_ALGEBRA_H_ 3 | 4 | #ifdef USING_LEFT_HANDEND_SYSTEM 5 | #define Mat4RotateX Mat4D::RotateXLH 6 | #define Mat4RotateY Mat4D::RotateYLH 7 | #define Mat4RotateZ Mat4D::RotateZLH 8 | #define Mat4Translate Mat4D::TranslateLH 9 | #define Mat4LookAt Mat4D::LookAtLH 10 | #define Mat4PerspectiveFov Mat4D::PerspectiveFovLH 11 | #else 12 | #define Mat4RotateX Mat4D::RotateXRH 13 | #define Mat4RotateY Mat4D::RotateYRH 14 | #define Mat4RotateZ Mat4D::RotateZRH 15 | #define Mat4Translate Mat4D::TranslateLH 16 | #define Mat4LookAt Mat4D::LookAtRH 17 | #define Mat4PerspectiveFov Mat4D::PerspectiveFovRH 18 | #endif // USING_LEFT_HANDEND_SYSTEM 19 | 20 | namespace Mat4D 21 | { 22 | 23 | 24 | class CMatrix4D; 25 | 26 | class CVector4D 27 | { 28 | public: 29 | union 30 | { 31 | struct 32 | { 33 | float x, y, z, w; 34 | }; 35 | struct 36 | { 37 | float r, g, b, a; 38 | }; 39 | float val[4]; 40 | }; 41 | CVector4D(); 42 | CVector4D(const CVector4D& cpy); 43 | CVector4D(float x_, float y_, float z_, float w_); 44 | CVector4D& operator+=(const CVector4D& rhs); 45 | CVector4D& operator*=(float scalar); 46 | CVector4D& operator-=(const CVector4D& rhs); 47 | CVector4D& operator/=(float scalar); 48 | float Dot(const CVector4D& b) const; 49 | float Magnitude() const; 50 | CVector4D Cross(const CVector4D& b) const; 51 | CVector4D Normalize() const; 52 | }; 53 | 54 | CVector4D operator+(CVector4D lhs, const CVector4D& rhs); 55 | CVector4D operator-(CVector4D lhs, const CVector4D& rhs); 56 | CVector4D operator*(CVector4D vec, float scalar); 57 | CVector4D operator*(float scalar, const CVector4D& vec); 58 | CVector4D operator/(CVector4D vec, float scalar); 59 | 60 | 61 | class CMatrix4D 62 | { 63 | public: 64 | union 65 | { 66 | struct 67 | { 68 | float m00, m01, m02, m03, 69 | m10, m11, m12, m13, 70 | m20, m21, m22, m23, 71 | m30, m31, m32, m33; 72 | }; 73 | struct 74 | { 75 | CVector4D r0, r1, r2, r3; 76 | }; 77 | float m[4][4]; 78 | float v[16] = { 0 }; 79 | }; 80 | CMatrix4D(); 81 | CMatrix4D(float* a); 82 | CMatrix4D(const CMatrix4D& cpy); 83 | CMatrix4D ( 84 | const CVector4D& row1, 85 | const CVector4D& row2, 86 | const CVector4D& row3, 87 | const CVector4D& row4 88 | ); 89 | CMatrix4D ( 90 | float i00, float i01, float i02, float i03, 91 | float i10, float i11, float i12, float i13, 92 | float i20, float i21, float i22, float i23, 93 | float i30, float i31, float i32, float i33 94 | ); 95 | CMatrix4D& operator*=(const CMatrix4D& rhs); 96 | CMatrix4D& operator=(float* a); 97 | void Identity(); 98 | void Zero(); 99 | }; 100 | 101 | CVector4D operator*(CMatrix4D lhs, const CVector4D & rhs); 102 | CVector4D operator*(CVector4D lhs, const CMatrix4D & rhs); 103 | CMatrix4D operator*(CMatrix4D lhs, const CMatrix4D& rhs); 104 | 105 | //TODO: Meter a la como metodos de la clase 106 | CMatrix4D Scale(float sx, float sy, float sz); 107 | 108 | CMatrix4D TranslateLH(float tx, float ty, float tz); 109 | CMatrix4D RotateXLH(float theta); 110 | CMatrix4D RotateYLH(float theta); 111 | CMatrix4D RotateZLH(float theta); 112 | CMatrix4D LookAtLH(const CVector4D& eye, const CVector4D& at, const CVector4D up); 113 | CMatrix4D PerspectiveFovLH(float fovy, float aspect, float zn, float zf); 114 | 115 | CMatrix4D TranslateRH(float tx, float ty, float tz); 116 | CMatrix4D RotateXRH(float theta); 117 | CMatrix4D RotateYRH(float theta); 118 | CMatrix4D RotateZRH(float theta); 119 | CMatrix4D LookAtRH(const CVector4D& eye, const CVector4D& at, const CVector4D up); 120 | CMatrix4D PerspectiveFovRH(float fovy, float aspect, float zn, float zf); 121 | 122 | } 123 | 124 | #endif //_SIMPLE_ALGEBRA_H_ -------------------------------------------------------------------------------- /AlgebraLib/AlgebraLib.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | {FD0E31B4-3A9C-4ED4-8847-A4E9308E6FA0} 24 | AlgebraLib 25 | 10.0 26 | 27 | 28 | 29 | StaticLibrary 30 | true 31 | v142 32 | Unicode 33 | 34 | 35 | StaticLibrary 36 | false 37 | v142 38 | true 39 | Unicode 40 | 41 | 42 | StaticLibrary 43 | true 44 | v142 45 | Unicode 46 | 47 | 48 | StaticLibrary 49 | false 50 | v142 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | false 74 | $(SolutionDir)Bin\$(PlatformTarget)\ 75 | $(SolutionDir)Intermediate\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ 76 | 77 | 78 | true 79 | $(ProjectName)-d 80 | $(SolutionDir)Bin\$(PlatformTarget)\ 81 | $(SolutionDir)Intermediate\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ 82 | 83 | 84 | true 85 | $(ProjectName)-d 86 | $(SolutionDir)Bin\$(PlatformTarget)\ 87 | $(SolutionDir)Intermediate\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ 88 | 89 | 90 | false 91 | $(SolutionDir)Bin\$(PlatformTarget)\ 92 | $(SolutionDir)Intermediate\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ 93 | 94 | 95 | 96 | Level3 97 | true 98 | true 99 | true 100 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 101 | true 102 | 103 | 104 | Console 105 | true 106 | true 107 | true 108 | 109 | 110 | 111 | 112 | Level3 113 | true 114 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 115 | true 116 | 117 | 118 | Console 119 | true 120 | 121 | 122 | 123 | 124 | Level3 125 | true 126 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 127 | true 128 | 129 | 130 | Console 131 | true 132 | 133 | 134 | 135 | 136 | Level3 137 | true 138 | true 139 | true 140 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 141 | true 142 | 143 | 144 | Console 145 | true 146 | true 147 | true 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /AlgebraLib/AlgebraLib.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | 23 | 24 | Resource Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Gerardo Hernandez 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Pathfinding.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29806.167 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Pathfinding", "Pathfinding\Pathfinding.vcxproj", "{A4DC0C1A-8108-4738-BBC7-E01405688CEA}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {FD0E31B4-3A9C-4ED4-8847-A4E9308E6FA0} = {FD0E31B4-3A9C-4ED4-8847-A4E9308E6FA0} 9 | EndProjectSection 10 | EndProject 11 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AlgebraLib", "AlgebraLib\AlgebraLib.vcxproj", "{FD0E31B4-3A9C-4ED4-8847-A4E9308E6FA0}" 12 | EndProject 13 | Global 14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 15 | Debug|x64 = Debug|x64 16 | Debug|x86 = Debug|x86 17 | Release|x64 = Release|x64 18 | Release|x86 = Release|x86 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {A4DC0C1A-8108-4738-BBC7-E01405688CEA}.Debug|x64.ActiveCfg = Debug|x64 22 | {A4DC0C1A-8108-4738-BBC7-E01405688CEA}.Debug|x64.Build.0 = Debug|x64 23 | {A4DC0C1A-8108-4738-BBC7-E01405688CEA}.Debug|x86.ActiveCfg = Debug|Win32 24 | {A4DC0C1A-8108-4738-BBC7-E01405688CEA}.Debug|x86.Build.0 = Debug|Win32 25 | {A4DC0C1A-8108-4738-BBC7-E01405688CEA}.Release|x64.ActiveCfg = Release|x64 26 | {A4DC0C1A-8108-4738-BBC7-E01405688CEA}.Release|x64.Build.0 = Release|x64 27 | {A4DC0C1A-8108-4738-BBC7-E01405688CEA}.Release|x86.ActiveCfg = Release|Win32 28 | {A4DC0C1A-8108-4738-BBC7-E01405688CEA}.Release|x86.Build.0 = Release|Win32 29 | {FD0E31B4-3A9C-4ED4-8847-A4E9308E6FA0}.Debug|x64.ActiveCfg = Debug|x64 30 | {FD0E31B4-3A9C-4ED4-8847-A4E9308E6FA0}.Debug|x64.Build.0 = Debug|x64 31 | {FD0E31B4-3A9C-4ED4-8847-A4E9308E6FA0}.Debug|x86.ActiveCfg = Debug|Win32 32 | {FD0E31B4-3A9C-4ED4-8847-A4E9308E6FA0}.Debug|x86.Build.0 = Debug|Win32 33 | {FD0E31B4-3A9C-4ED4-8847-A4E9308E6FA0}.Release|x64.ActiveCfg = Release|x64 34 | {FD0E31B4-3A9C-4ED4-8847-A4E9308E6FA0}.Release|x64.Build.0 = Release|x64 35 | {FD0E31B4-3A9C-4ED4-8847-A4E9308E6FA0}.Release|x86.ActiveCfg = Release|Win32 36 | {FD0E31B4-3A9C-4ED4-8847-A4E9308E6FA0}.Release|x86.Build.0 = Release|Win32 37 | EndGlobalSection 38 | GlobalSection(SolutionProperties) = preSolution 39 | HideSolutionNode = FALSE 40 | EndGlobalSection 41 | GlobalSection(ExtensibilityGlobals) = postSolution 42 | SolutionGuid = {9E568C05-BA78-4EE2-9B24-CECFF4A424EE} 43 | EndGlobalSection 44 | EndGlobal 45 | -------------------------------------------------------------------------------- /Pathfinding/AStarWalker.cpp: -------------------------------------------------------------------------------- 1 | #include "AStarWalker.h" 2 | #include "Graph.h" 3 | 4 | CAStarWalker::CAStarWalker() 5 | { 6 | } 7 | 8 | CAStarWalker::~CAStarWalker() 9 | { 10 | 11 | } 12 | 13 | bool CAStarWalker::Step() 14 | { 15 | if ( m_pEnd && m_pCurrent && 16 | m_iCurrentSteps++ < m_iMaxSteps && !m_nodes.empty() ) 17 | { 18 | m_pCurrent = *m_nodes.begin(); 19 | 20 | m_pCurrent->SetVisited( true ); 21 | 22 | m_nodes.erase( m_nodes.begin() ); 23 | 24 | if ( m_pCurrent == m_pEnd ) 25 | { 26 | CreatePath( m_pCurrent ); 27 | return true; 28 | } 29 | 30 | LoadConnections( m_pCurrent ); 31 | 32 | } 33 | else 34 | { 35 | //CreatePath(m_pCurrent); 36 | return true; 37 | } 38 | 39 | return false; 40 | } 41 | 42 | 43 | void CAStarWalker::LoadConnections( CGraphNode *pNode ) 44 | { 45 | auto connections = std::move( GetConnections( pNode ) ); 46 | 47 | for ( auto& node : connections ) 48 | { 49 | float fTentDist = pNode->GetTentativeDistance() + node->GetWeight(); 50 | float fNodeTent = node->GetTentativeDistance(); 51 | if ( !node->Visited() && !node->IsBlocked() && 52 | fTentDist < fNodeTent ) 53 | { 54 | auto it = m_nodes.find( node ); 55 | 56 | if ( it != m_nodes.end() ) 57 | { 58 | m_nodes.erase( it ); 59 | } 60 | 61 | node->SetTentativeDistance( fTentDist ); 62 | 63 | m_nodes.insert( node ); 64 | 65 | node->SetParent( pNode ); 66 | } 67 | } 68 | } 69 | 70 | void CAStarWalker::ClearNodes() 71 | { 72 | m_nodes.clear(); 73 | } 74 | 75 | /*************Calculador de F**************/ 76 | 77 | bool CLessF::operator()( CGraphNode *pA, CGraphNode *pB ) const 78 | { 79 | CGraph* pGraph = pA->GetGraph(); 80 | float hA = pGraph->GetNodeHeuristic( pA ); 81 | float hB = pGraph->GetNodeHeuristic( pB ); 82 | return (hA + pA->GetTentativeDistance()) < (hB + pB->GetTentativeDistance()); 83 | } 84 | -------------------------------------------------------------------------------- /Pathfinding/AStarWalker.h: -------------------------------------------------------------------------------- 1 | #ifndef CASTARWALKER_H 2 | #define CASTARWALKER_H 3 | 4 | #include "Walker.h" 5 | #include 6 | 7 | class CLessF 8 | { 9 | public: 10 | bool operator()( CGraphNode* pA, CGraphNode* pB ) const; 11 | }; 12 | 13 | class CAStarWalker : public CWalker 14 | { 15 | public: 16 | CAStarWalker(); 17 | virtual ~CAStarWalker(); 18 | bool Step() override; 19 | private: 20 | void LoadConnections( CGraphNode* pNode ) override; 21 | void ClearNodes() override; 22 | private: 23 | std::multiset m_nodes; 24 | }; 25 | 26 | #endif // CASTARWALKER_H 27 | 28 | -------------------------------------------------------------------------------- /Pathfinding/BFSWalker.cpp: -------------------------------------------------------------------------------- 1 | #include "BFSWalker.h" 2 | #include "Graph.h" 3 | 4 | CBFSWalker::CBFSWalker() 5 | { 6 | } 7 | 8 | CBFSWalker::~CBFSWalker() 9 | { 10 | } 11 | 12 | bool CBFSWalker::Step( ) 13 | { 14 | if ( m_pEnd && m_pCurrent && 15 | m_iCurrentSteps++ < m_iMaxSteps && !m_nodes.empty() ) 16 | { 17 | m_pCurrent = m_nodes.front(); 18 | 19 | m_pCurrent->SetVisited( true ); 20 | 21 | m_nodes.pop(); 22 | 23 | if ( m_pCurrent == m_pEnd ) 24 | { 25 | CreatePath( m_pCurrent ); 26 | return true; 27 | } 28 | 29 | LoadConnections( m_pCurrent ); 30 | } 31 | else 32 | { 33 | //CreatePath(m_pCurrent); 34 | return true; 35 | } 36 | 37 | return false; 38 | } 39 | 40 | void CBFSWalker::LoadConnections( CGraphNode *pNode ) 41 | { 42 | auto connections = std::move( GetConnections( pNode ) ); 43 | 44 | for ( auto& node : connections ) 45 | { 46 | if ( !node->Visited() && !node->GetParent() && !node->IsBlocked() ) 47 | { 48 | m_nodes.push( node ); 49 | node->SetParent( pNode ); 50 | } 51 | } 52 | } 53 | 54 | void CBFSWalker::ClearNodes() 55 | { 56 | while ( !m_nodes.empty() ) 57 | m_nodes.pop(); 58 | } 59 | 60 | 61 | -------------------------------------------------------------------------------- /Pathfinding/BFSWalker.h: -------------------------------------------------------------------------------- 1 | #ifndef _CBFSWALKER_H_ 2 | #define _CBFSWALKER_H_ 3 | 4 | #include "Walker.h" 5 | #include 6 | 7 | 8 | class CBFSWalker : public CWalker 9 | { 10 | public: 11 | CBFSWalker(); 12 | virtual ~CBFSWalker(); 13 | bool Step() override; 14 | private: 15 | void LoadConnections( CGraphNode* pNode ) override; 16 | void ClearNodes() override; 17 | private: 18 | std::queue m_nodes; 19 | }; 20 | 21 | #endif //_CBFSWALKER_H_ 22 | 23 | -------------------------------------------------------------------------------- /Pathfinding/BestFSWalker.cpp: -------------------------------------------------------------------------------- 1 | #include "bestfswalker.h" 2 | #include "Graph.h" 3 | 4 | CBestFSWalker::CBestFSWalker() 5 | { 6 | 7 | } 8 | 9 | CBestFSWalker::~CBestFSWalker() 10 | { 11 | 12 | } 13 | bool CBestFSWalker::Step( ) 14 | { 15 | if ( m_pEnd && m_pCurrent && 16 | m_iCurrentSteps++ < m_iMaxSteps && !m_nodes.empty() ) 17 | { 18 | m_pCurrent = m_nodes.top(); 19 | 20 | m_pCurrent->SetVisited( true ); 21 | 22 | m_nodes.pop(); 23 | 24 | if ( m_pCurrent == m_pEnd ) 25 | { 26 | CreatePath( m_pCurrent ); 27 | return true; 28 | } 29 | 30 | LoadConnections( m_pCurrent ); 31 | 32 | } 33 | else 34 | { 35 | //CreatePath(m_pCurrent); 36 | return true; 37 | } 38 | 39 | return false; 40 | } 41 | 42 | void CBestFSWalker::LoadConnections( CGraphNode* pNode ) 43 | { 44 | auto connections = std::move( GetConnections( pNode ) ); 45 | 46 | for ( auto& node : connections ) 47 | { 48 | if ( !node->Visited() && !node->GetParent() && !node->IsBlocked() ) 49 | { 50 | m_nodes.push( node ); 51 | node->SetParent( pNode ); 52 | } 53 | } 54 | } 55 | 56 | void CBestFSWalker::ClearNodes() 57 | { 58 | while ( m_nodes.size() ) 59 | { 60 | m_nodes.pop(); 61 | } 62 | } 63 | 64 | /*********CLessHeuristic******/ 65 | bool CLessHeuristic::operator()( CGraphNode *lhs, CGraphNode *rhs ) const 66 | { 67 | CGraph* graph = lhs->GetGraph(); 68 | return graph->GetNodeHeuristic( lhs ) > graph->GetNodeHeuristic( rhs ); 69 | } 70 | -------------------------------------------------------------------------------- /Pathfinding/BestFSWalker.h: -------------------------------------------------------------------------------- 1 | #ifndef BESTFSWALKER_H 2 | #define BESTFSWALKER_H 3 | 4 | #include "Walker.h" 5 | #include 6 | #include 7 | 8 | class CLessHeuristic 9 | { 10 | public: 11 | bool operator()( CGraphNode* lhs, CGraphNode* rhs ) const; 12 | }; 13 | 14 | class CBestFSWalker : public CWalker 15 | { 16 | public: 17 | CBestFSWalker(); 18 | virtual ~CBestFSWalker(); 19 | bool Step( ) override; 20 | private: 21 | void LoadConnections( CGraphNode* pNode ) override; 22 | void ClearNodes() override; 23 | private: 24 | //CLessHeuristic 25 | std::priority_queue, 27 | CLessHeuristic> m_nodes; 28 | }; 29 | 30 | 31 | #endif // BESTFSWALKER_H 32 | -------------------------------------------------------------------------------- /Pathfinding/DFSWalker.cpp: -------------------------------------------------------------------------------- 1 | #include "DFSWalker.h" 2 | #include "Graph.h" 3 | 4 | CDFSWalker::CDFSWalker() 5 | { 6 | } 7 | 8 | CDFSWalker::~CDFSWalker() 9 | { 10 | 11 | } 12 | 13 | 14 | bool CDFSWalker::Step() 15 | { 16 | if ( m_pEnd && m_pCurrent && 17 | m_iCurrentSteps++ < m_iMaxSteps && !m_nodes.empty() ) 18 | { 19 | m_pCurrent = m_nodes.top(); 20 | 21 | m_pCurrent->SetVisited( true ); 22 | 23 | m_nodes.pop(); 24 | 25 | if ( m_pCurrent == m_pEnd ) 26 | { 27 | CreatePath( m_pCurrent ); 28 | return true; 29 | } 30 | 31 | LoadConnections( m_pCurrent ); 32 | } 33 | else 34 | { 35 | //CreatePath(m_pCurrent); 36 | return true; 37 | } 38 | 39 | return false; 40 | } 41 | 42 | void CDFSWalker::ClearNodes() 43 | { 44 | while ( !m_nodes.empty() ) 45 | m_nodes.pop(); 46 | } 47 | 48 | void CDFSWalker::LoadConnections( CGraphNode *pNode ) 49 | { 50 | auto connections = std::move( GetConnections( pNode ) ); 51 | 52 | for ( auto& node : connections ) 53 | { 54 | if ( !node->Visited() && !node->GetParent() && !node->IsBlocked() ) 55 | { 56 | m_nodes.push( node ); 57 | node->SetParent( pNode ); 58 | } 59 | } 60 | } 61 | 62 | -------------------------------------------------------------------------------- /Pathfinding/DFSWalker.h: -------------------------------------------------------------------------------- 1 | #ifndef _CDFSWALKER_H_ 2 | #define _CDFSWALKER_H_ 3 | 4 | #include "Walker.h" 5 | #include 6 | 7 | class CDFSWalker : public CWalker 8 | { 9 | public: 10 | CDFSWalker(); 11 | virtual ~CDFSWalker(); 12 | bool Step() override; 13 | private: 14 | void LoadConnections( CGraphNode* pNode ) override; 15 | void ClearNodes() override; 16 | private: 17 | std::stack m_nodes; 18 | }; 19 | 20 | #endif //_CDFSWALKER_H_ 21 | -------------------------------------------------------------------------------- /Pathfinding/DijkstraWalker.cpp: -------------------------------------------------------------------------------- 1 | #include "DijkstraWalker.h" 2 | #include "Graph.h" 3 | 4 | CDijkstraWalker::CDijkstraWalker() 5 | { 6 | 7 | } 8 | 9 | CDijkstraWalker::~CDijkstraWalker() 10 | { 11 | 12 | } 13 | 14 | bool CDijkstraWalker::Step() 15 | { 16 | if ( m_pEnd && m_pCurrent && 17 | m_iCurrentSteps++ < m_iMaxSteps && !m_nodes.empty() ) 18 | { 19 | m_pCurrent = *m_nodes.begin(); 20 | m_nodes.erase( m_nodes.begin() ); 21 | 22 | if ( m_pCurrent != m_pEnd ) 23 | { 24 | m_pCurrent->SetVisited( true ); 25 | LoadConnections( m_pCurrent ); 26 | } 27 | else 28 | CreatePath( m_pCurrent ); 29 | } 30 | else 31 | { 32 | return true; 33 | } 34 | 35 | return false; 36 | } 37 | 38 | void CDijkstraWalker::LoadConnections( CGraphNode *pNode ) 39 | { 40 | auto connections = std::move( GetConnections( pNode ) ); 41 | 42 | for ( auto& node : connections ) 43 | { 44 | float fTentDist = pNode->GetTentativeDistance() + node->GetWeight(); 45 | float fNodeTent = node->GetTentativeDistance(); 46 | if ( !node->Visited() && !node->IsBlocked() && 47 | fTentDist < fNodeTent ) 48 | { 49 | auto it = m_nodes.find( node ); 50 | 51 | if ( it != m_nodes.end() ) 52 | { 53 | m_nodes.erase( it ); 54 | } 55 | 56 | node->SetTentativeDistance( fTentDist ); 57 | 58 | m_nodes.insert( node ); 59 | 60 | node->SetParent( pNode ); 61 | } 62 | } 63 | } 64 | 65 | void CDijkstraWalker::ClearNodes() 66 | { 67 | m_nodes.clear(); 68 | } 69 | 70 | 71 | /*******Clase Para Comprar pesos******/ 72 | 73 | bool CLessWeight::operator()( CGraphNode *lhs, CGraphNode *rhs ) const 74 | { 75 | return lhs->GetTentativeDistance() < rhs->GetTentativeDistance(); 76 | } 77 | -------------------------------------------------------------------------------- /Pathfinding/DijkstraWalker.h: -------------------------------------------------------------------------------- 1 | #ifndef CDIJKSTRAWALKER_H 2 | #define CDIJKSTRAWALKER_H 3 | 4 | #include "Walker.h" 5 | #include 6 | 7 | class CLessWeight 8 | { 9 | public: 10 | bool operator()( CGraphNode* lhs, CGraphNode* rhs ) const; 11 | }; 12 | 13 | class CDijkstraWalker : public CWalker 14 | { 15 | public: 16 | CDijkstraWalker(); 17 | virtual ~CDijkstraWalker(); 18 | bool Step() override; 19 | private: 20 | void LoadConnections( CGraphNode* pNode ) override; 21 | void ClearNodes() override; 22 | private: 23 | std::multiset m_nodes; 24 | }; 25 | 26 | #endif // CDIJKSTRAWALKER_H 27 | -------------------------------------------------------------------------------- /Pathfinding/Graph.cpp: -------------------------------------------------------------------------------- 1 | #include "Graph.h" 2 | #include 3 | 4 | CGraph::CGraph() : 5 | m_iRows{ 0 }, 6 | m_iCols{ 0 }, 7 | m_pBegin{ nullptr }, 8 | m_pEnd{ nullptr }, 9 | m_pConnections{ nullptr } 10 | { 11 | } 12 | 13 | CGraph::CGraph( const CGraph & graph ) 14 | { 15 | *this = graph; 16 | } 17 | 18 | CGraph& CGraph::operator=( const CGraph & graph ) 19 | { 20 | m_iRows = graph.m_iRows; 21 | m_iCols = graph.m_iRows; 22 | 23 | m_nodes.reserve( graph.m_nodes.size() ); 24 | 25 | for ( auto& pNode : graph.m_nodes ) 26 | { 27 | auto pNewNode = std::make_unique( *pNode ); 28 | pNewNode->SetGraph( this ); 29 | m_nodes.push_back( std::move(pNewNode) ); 30 | } 31 | 32 | m_heuristicFunc = graph.m_heuristicFunc; 33 | 34 | if ( graph.m_pBegin ) 35 | SetBegin( graph.m_pBegin->GetID() ); 36 | else 37 | m_pBegin = nullptr; 38 | 39 | if ( graph.m_pEnd ) 40 | SetBegin( graph.m_pEnd->GetID() ); 41 | else 42 | m_pEnd = nullptr; 43 | 44 | m_pConnections = &const_cast(graph).m_connections; 45 | 46 | return *this; 47 | } 48 | 49 | CGraph::~CGraph() 50 | { 51 | } 52 | 53 | CGraphNode* CGraph::GetNode( id_type id ) 54 | { 55 | return ((int)id >= 0 && (int)id < (m_iRows * m_iCols)) ? m_nodes[id].get() : nullptr; 56 | } 57 | 58 | CGraphNode* CGraph::GetBeginNode() 59 | { 60 | return m_pBegin; 61 | } 62 | 63 | CGraphNode* CGraph::GetEndNode() 64 | { 65 | return m_pEnd; 66 | } 67 | 68 | CGraph::ConnectionsMap CGraph::GetConnections() 69 | { 70 | return m_pConnections ? *m_pConnections : m_connections; 71 | } 72 | 73 | std::vector CGraph::GetNodeConnections( CGraphNode * pNode ) 74 | { 75 | auto nodeConnections = m_pConnections ? m_pConnections->find(pNode->GetID()) : m_connections.find( pNode->GetID() ); 76 | 77 | std::vector connections; 78 | 79 | auto connEnd = m_pConnections ? m_pConnections->end() : m_connections.end(); 80 | 81 | if ( nodeConnections != connEnd ) 82 | { 83 | for ( auto& connection_id : nodeConnections->second ) 84 | { 85 | connections.emplace_back( GetNode( connection_id ) ); 86 | } 87 | } 88 | 89 | return std::move( connections ); 90 | } 91 | 92 | std::vector CGraph::GetNodes() 93 | { 94 | std::vector out; 95 | 96 | out.reserve( m_nodes.size() ); 97 | 98 | for ( auto& pNode : m_nodes ) 99 | out.emplace_back( pNode.get() ); 100 | 101 | return std::move( out ); 102 | } 103 | 104 | void CGraph::Create( int iCols, int iRows, float fNodeWidth, float fNodeHeight, Connections::Type connType ) 105 | { 106 | Clean(); 107 | 108 | m_iRows = iRows; 109 | m_iCols = iCols; 110 | 111 | m_nodes.reserve( iCols * iRows ); 112 | 113 | for ( int i = 0; i < (iCols * iRows); ++i ) 114 | { 115 | auto pNode = std::make_unique( i, this ); 116 | pNode->SetPosition( { i % iCols * fNodeWidth, 117 | i / iCols * fNodeHeight, 0.f, 1.f } ); 118 | m_nodes.push_back( std::move( pNode ) ); 119 | } 120 | 121 | for ( int i = 0; i < (iCols * iRows); ++i ) 122 | { 123 | const int x = i % iCols; 124 | const int y = i / iCols; 125 | 126 | const int iLeft = std::max( x - 1, 0 ); 127 | const int iRight = std::min( x + 1, iCols - 1 ); 128 | const int iTop = std::max( y - 1, 0 ); 129 | const int iDown = std::min( y + 1, iRows - 1 ); 130 | 131 | AddConnection( iLeft + y * iCols, i, true ); 132 | AddConnection( iRight + y * iCols, i, true ); 133 | AddConnection( iTop * iCols + x, i, true ); 134 | AddConnection( iDown * iCols + x, i, true ); 135 | 136 | if ( connType == Connections::EIGHT_DIRECTIONS ) 137 | { 138 | AddConnection( iLeft + iTop * iCols, i, true ); 139 | AddConnection( iRight + iDown * iCols, i, true ); 140 | AddConnection( iTop * iCols + iRight, i, true ); 141 | AddConnection( iDown * iCols + iLeft, i, true ); 142 | } 143 | } 144 | } 145 | 146 | void CGraph::SetHeuristicFunction( HeuristeicFuncType func ) 147 | { 148 | m_heuristicFunc = func; 149 | } 150 | 151 | void CGraph::SetBegin( id_type id ) 152 | { 153 | m_pBegin = GetNode( id ); 154 | } 155 | 156 | void CGraph::SetEnd( id_type id ) 157 | { 158 | m_pEnd = GetNode( id ); 159 | } 160 | 161 | void CGraph::Clean() 162 | { 163 | m_iRows = 0; 164 | m_iCols = 0; 165 | m_nodes.clear(); 166 | m_connections.clear(); 167 | m_pConnections = nullptr; 168 | m_pBegin = nullptr; 169 | m_pEnd = nullptr; 170 | } 171 | 172 | float CGraph::GetNodeHeuristic( CGraphNode* node ) 173 | { 174 | return m_heuristicFunc( node, this ); 175 | } 176 | 177 | void CGraph::AddConnection( id_type id_from, id_type id_to, bool bBidirectional ) 178 | { 179 | auto pFrom = GetNode( id_from ); 180 | auto pTo = GetNode( id_to ); 181 | 182 | if ( pFrom && pTo && pFrom != pTo ) 183 | { 184 | m_connections[id_from].insert( id_to ); 185 | if ( bBidirectional ) 186 | m_connections[id_to].insert( id_from ); 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /Pathfinding/Graph.h: -------------------------------------------------------------------------------- 1 | #ifndef _CGRAPH_H_ 2 | #define _CGRAPH_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "GraphNode.h" 10 | 11 | namespace Connections 12 | { 13 | enum Type 14 | { 15 | EIGHT_DIRECTIONS, 16 | FOUR_DIRECTIONS 17 | }; 18 | } 19 | 20 | class CGraph 21 | { 22 | friend class GraphCopy; 23 | public: 24 | using id_type = unsigned int; 25 | using ConnectionsMap = std::unordered_map>; 26 | using NodesMap = std::vector>; 27 | using HeuristeicFuncType = std::function; 28 | public: 29 | CGraph(); 30 | CGraph( const CGraph& graph ); 31 | CGraph& operator=( const CGraph& graph ); 32 | ~CGraph(); 33 | CGraphNode* GetNode( id_type id ); 34 | CGraphNode* GetBeginNode(); 35 | CGraphNode* GetEndNode(); 36 | ConnectionsMap GetConnections(); 37 | std::vector GetNodeConnections( CGraphNode* node ); 38 | std::vector GetNodes(); 39 | void Create( int iCols, int iRows, float fNodeWidth, float fNodeHeight, Connections::Type connType ); 40 | void SetHeuristicFunction( HeuristeicFuncType func ); 41 | void SetBegin( id_type id ); 42 | void SetEnd( id_type id ); 43 | void Clean(); 44 | float GetNodeHeuristic( CGraphNode* node ); 45 | private: 46 | void AddConnection( id_type id_from, id_type id_to, bool bBidirectional ); 47 | private: 48 | HeuristeicFuncType m_heuristicFunc; 49 | int m_iRows; 50 | int m_iCols; 51 | float m_fNodeWidth; 52 | float m_fNodeHeight; 53 | NodesMap m_nodes; 54 | ConnectionsMap m_connections; 55 | ConnectionsMap* m_pConnections; 56 | CGraphNode* m_pBegin; 57 | CGraphNode* m_pEnd; 58 | }; 59 | 60 | #endif //_CGRAPH_H_ 61 | -------------------------------------------------------------------------------- /Pathfinding/GraphNode.cpp: -------------------------------------------------------------------------------- 1 | #include "GraphNode.h" 2 | #include 3 | 4 | CGraphNode::CGraphNode( id_type id, CGraph* pGraph ) 5 | : 6 | m_pParent{ nullptr }, 7 | m_bVisited{ false }, 8 | m_dwID{ id }, 9 | m_pGraph{ pGraph }, 10 | m_fWeight{ 0 }, 11 | m_bBlocked{ false }, 12 | m_fTentativeDistance{ std::numeric_limits::max() } 13 | { 14 | } 15 | 16 | void CGraphNode::SetParent( CGraphNode * parent ) 17 | { 18 | m_pParent = parent; 19 | } 20 | 21 | CGraphNode* CGraphNode::GetParent() 22 | { 23 | return m_pParent; 24 | } 25 | 26 | void CGraphNode::SetPosition( const Mat4D::CVector4D & pos ) 27 | { 28 | m_position = pos; 29 | } 30 | 31 | Mat4D::CVector4D CGraphNode::GetPosition() 32 | { 33 | return m_position; 34 | } 35 | 36 | void CGraphNode::SetVisited( bool visit ) 37 | { 38 | m_bVisited = visit; 39 | } 40 | 41 | bool CGraphNode::Visited() 42 | { 43 | return m_bVisited; 44 | } 45 | 46 | CGraphNode::id_type CGraphNode::GetID() 47 | { 48 | return m_dwID; 49 | } 50 | 51 | void CGraphNode::SetName( std::string name ) 52 | { 53 | m_name = name; 54 | } 55 | 56 | std::string CGraphNode::GetName() 57 | { 58 | return m_name; 59 | } 60 | 61 | CGraph *CGraphNode::GetGraph() 62 | { 63 | return m_pGraph; 64 | } 65 | 66 | float CGraphNode::GetWeight() 67 | { 68 | return m_fWeight; 69 | } 70 | 71 | float CGraphNode::GetTentativeDistance() 72 | { 73 | return m_fTentativeDistance; 74 | } 75 | 76 | bool CGraphNode::IsBlocked() 77 | { 78 | return m_bBlocked; 79 | } 80 | 81 | void CGraphNode::SetGraph( CGraph *graph ) 82 | { 83 | m_pGraph = graph; 84 | } 85 | 86 | void CGraphNode::SetWeight( float fWeight ) 87 | { 88 | m_fWeight = fWeight; 89 | } 90 | 91 | void CGraphNode::SetBlocked( bool bBlocked ) 92 | { 93 | m_bBlocked = bBlocked; 94 | } 95 | 96 | void CGraphNode::SetTentativeDistance( float fTentativeDistance ) 97 | { 98 | m_fTentativeDistance = fTentativeDistance; 99 | } 100 | 101 | 102 | CGraphNode::~CGraphNode() 103 | { 104 | } 105 | -------------------------------------------------------------------------------- /Pathfinding/GraphNode.h: -------------------------------------------------------------------------------- 1 | #ifndef _CGRAPHNODE_H_ 2 | #define _CGRAPHNODE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class CGraph; 9 | 10 | class CGraphNode 11 | { 12 | public: 13 | using id_type = unsigned int; 14 | CGraphNode( id_type id, CGraph* pGraph ); 15 | CGraphNode( const CGraphNode& node ) = default; 16 | CGraphNode& operator=( const CGraphNode& node ) = default; 17 | bool Visited(); 18 | void SetParent( CGraphNode* parent ); 19 | void SetVisited( bool visit ); 20 | void SetPosition( const Mat4D::CVector4D& pos ); 21 | void SetName( std::string name ); 22 | void SetGraph( CGraph* graph ); 23 | void SetWeight( float fWeight ); 24 | void SetBlocked( bool bBlocked ); 25 | void SetTentativeDistance( float fTentativeDistance ); 26 | Mat4D::CVector4D GetPosition(); 27 | CGraphNode* GetParent(); 28 | id_type GetID(); 29 | std::string GetName(); 30 | CGraph* GetGraph(); 31 | float GetWeight(); 32 | float GetTentativeDistance(); 33 | bool IsBlocked(); 34 | ~CGraphNode(); 35 | private: 36 | id_type m_dwID; 37 | float m_fTentativeDistance; 38 | float m_fWeight; 39 | bool m_bVisited; 40 | bool m_bBlocked; 41 | CGraph* m_pGraph; 42 | std::string m_name; 43 | CGraphNode* m_pParent; 44 | Mat4D::CVector4D m_position; 45 | }; 46 | 47 | #endif //_CGRAPHNODE_H_ 48 | 49 | -------------------------------------------------------------------------------- /Pathfinding/Pathfinding.cpp: -------------------------------------------------------------------------------- 1 | #include "Graph.h" 2 | #include "BestFSWalker.h" 3 | #include "AStarWalker.h" 4 | #include "DijkstraWalker.h" 5 | #include "BFSWalker.h" 6 | #include "DFSWalker.h" 7 | #include 8 | #include 9 | 10 | 11 | auto main( int argc, char** argv ) -> int 12 | { 13 | auto myGraph = std::make_shared(); 14 | 15 | auto manhattanDistance = []( CGraphNode* pNode, CGraph* pGraph ) 16 | { 17 | auto pEnd = pGraph->GetEndNode(); 18 | float dx = std::fabsf( pNode->GetPosition().x - pEnd->GetPosition().x ); 19 | float dy = std::fabsf( pNode->GetPosition().y - pEnd->GetPosition().y ); 20 | return dx + dy; 21 | }; 22 | 23 | auto euclideanDistance = []( CGraphNode* pNode, CGraph* pGraph ) 24 | { 25 | auto pEnd = pGraph->GetEndNode(); 26 | return (pEnd->GetPosition() - pNode->GetPosition()).Magnitude(); 27 | }; 28 | 29 | const int gridCols = 50; 30 | const int gridRows = 50; 31 | 32 | myGraph->Create( gridCols, gridRows, 50, 50, Connections::EIGHT_DIRECTIONS ); 33 | myGraph->SetHeuristicFunction( euclideanDistance ); 34 | 35 | std::unique_ptr pWalker = std::make_unique(); 36 | 37 | using namespace std::chrono; 38 | 39 | std::cout << "Start\n"; 40 | 41 | auto start = steady_clock::now(); 42 | 43 | auto pGraphCopy = std::make_shared( *myGraph ); 44 | 45 | pWalker->SetBegin( 0 ); 46 | pWalker->SetEnd( gridCols * gridRows - 1 ); 47 | pWalker->FindPath( pGraphCopy ); 48 | 49 | auto end = steady_clock::now(); 50 | 51 | std::cout << "Time to calculate path: " << duration_cast>(end - start).count() << std::endl; 52 | 53 | auto path = pWalker->GetPath(); 54 | 55 | if ( path.empty() ) 56 | { 57 | std::cout << "Couldn't find any path" << std::endl; 58 | } 59 | else 60 | { 61 | std::cout << "Path found: " << std::endl << std::endl; 62 | 63 | int nNodes = path.size() - 1; 64 | 65 | for ( auto pNode : path ) 66 | { 67 | std::cout << pNode->GetID(); 68 | 69 | if ( nNodes-- ) 70 | std::cout << "->"; 71 | } 72 | 73 | } 74 | 75 | pGraphCopy = nullptr; 76 | pWalker = nullptr; 77 | myGraph = nullptr; 78 | 79 | std::cin.ignore( std::numeric_limits::max() , '\n' ); 80 | 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /Pathfinding/Pathfinding.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {A4DC0C1A-8108-4738-BBC7-E01405688CEA} 24 | Pathfinding 25 | 10.0 26 | 27 | 28 | 29 | Application 30 | true 31 | v142 32 | MultiByte 33 | 34 | 35 | Application 36 | false 37 | v142 38 | true 39 | MultiByte 40 | 41 | 42 | Application 43 | true 44 | v142 45 | MultiByte 46 | 47 | 48 | Application 49 | false 50 | v142 51 | true 52 | MultiByte 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | $(SolutionDir)Bin\$(PlatformTarget)\ 74 | $(SolutionDir)Intermediate\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ 75 | 76 | 77 | $(SolutionDir)Bin\$(PlatformTarget)\ 78 | $(SolutionDir)Intermediate\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ 79 | 80 | 81 | $(SolutionDir)Bin\$(PlatformTarget)\ 82 | $(SolutionDir)Intermediate\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ 83 | 84 | 85 | $(SolutionDir)Bin\$(PlatformTarget)\ 86 | $(SolutionDir)Intermediate\$(ProjectName)\$(PlatformTarget)\$(Configuration)\ 87 | 88 | 89 | 90 | Level3 91 | Disabled 92 | true 93 | $(SolutionDir)AlgebraLib;%(AdditionalIncludeDirectories) 94 | 95 | 96 | $(SolutionDir)Bin\$(PlatformTarget);%(AdditionalLibraryDirectories) 97 | AlgebraLib-d.lib;%(AdditionalDependencies) 98 | 99 | 100 | 101 | 102 | Level3 103 | Disabled 104 | true 105 | $(SolutionDir)AlgebraLib;%(AdditionalIncludeDirectories) 106 | 107 | 108 | AlgebraLib-d.lib;%(AdditionalDependencies) 109 | $(SolutionDir)Bin\$(PlatformTarget);%(AdditionalLibraryDirectories) 110 | 111 | 112 | 113 | 114 | Level3 115 | MaxSpeed 116 | true 117 | true 118 | true 119 | $(SolutionDir)AlgebraLib;%(AdditionalIncludeDirectories) 120 | 121 | 122 | true 123 | true 124 | $(SolutionDir)Bin\$(PlatformTarget);%(AdditionalLibraryDirectories) 125 | AlgebraLib.lib;%(AdditionalDependencies) 126 | 127 | 128 | 129 | 130 | Level3 131 | MaxSpeed 132 | true 133 | true 134 | true 135 | $(SolutionDir)AlgebraLib;%(AdditionalIncludeDirectories) 136 | 137 | 138 | true 139 | true 140 | AlgebraLib.lib;%(AdditionalDependencies) 141 | $(SolutionDir)Bin\$(PlatformTarget);%(AdditionalLibraryDirectories) 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /Pathfinding/Pathfinding.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Resource Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | 44 | 45 | Source Files 46 | 47 | 48 | Source Files 49 | 50 | 51 | Source Files 52 | 53 | 54 | Source Files 55 | 56 | 57 | Source Files 58 | 59 | 60 | Source Files 61 | 62 | 63 | Source Files 64 | 65 | 66 | Source Files 67 | 68 | 69 | Source Files 70 | 71 | 72 | -------------------------------------------------------------------------------- /Pathfinding/Walker.cpp: -------------------------------------------------------------------------------- 1 | #include "Walker.h" 2 | #include "Graph.h" 3 | #include "GraphNode.h" 4 | 5 | CWalker::CWalker() : 6 | m_iMaxSteps{ 10000 }, 7 | m_pCurrent{ nullptr }, 8 | m_iCurrentSteps{ 0 }, 9 | m_pEnd{ nullptr }, 10 | m_iBegin{ static_cast(-1) }, 11 | m_iEnd{ static_cast(-1) } 12 | { 13 | } 14 | 15 | CWalker::~CWalker() 16 | { 17 | } 18 | 19 | void CWalker::FindPath( const std::shared_ptr& pGraph ) 20 | { 21 | Setup( pGraph ); 22 | while ( !Step() ); 23 | Cleanup(); 24 | } 25 | 26 | CGraphNode* CWalker::GetCurrentNode() 27 | { 28 | return m_pCurrent; 29 | } 30 | 31 | std::deque CWalker::GetPath() 32 | { 33 | return m_path; 34 | } 35 | 36 | void CWalker::Setup( const std::shared_ptr& pGraph ) 37 | { 38 | m_pGraph = pGraph; 39 | 40 | m_pGraph->SetBegin( m_iBegin ); 41 | m_pGraph->SetEnd( m_iEnd ); 42 | 43 | m_iCurrentSteps = 0; 44 | 45 | m_pCurrent = m_pGraph->GetBeginNode(); 46 | m_pEnd = m_pGraph->GetEndNode(); 47 | 48 | if ( m_pCurrent ) 49 | { 50 | m_pCurrent->SetVisited( true ); 51 | m_pCurrent->SetTentativeDistance( m_pCurrent->GetWeight() ); 52 | LoadConnections( m_pCurrent ); 53 | } 54 | 55 | ClearPath(); 56 | } 57 | 58 | void CWalker::Cleanup() 59 | { 60 | ClearNodes(); 61 | m_pGraph = nullptr; 62 | m_pCurrent = nullptr; 63 | m_pEnd = nullptr; 64 | } 65 | 66 | void CWalker::SetMaxSteps( int iMaxSteps ) 67 | { 68 | m_iMaxSteps = iMaxSteps; 69 | } 70 | 71 | void CWalker::SetBegin( id_type iBegin ) 72 | { 73 | m_iBegin = iBegin; 74 | } 75 | 76 | void CWalker::SetEnd( id_type iEnd ) 77 | { 78 | m_iEnd = iEnd; 79 | } 80 | 81 | void CWalker::ClearPath() 82 | { 83 | m_path.clear(); 84 | } 85 | 86 | CWalker::id_type CWalker::GetBegin() 87 | { 88 | return m_iBegin; 89 | } 90 | 91 | CWalker::id_type CWalker::GetEnd() 92 | { 93 | return m_iEnd; 94 | } 95 | 96 | void CWalker::CreatePath( CGraphNode *pEnd ) 97 | { 98 | m_path.clear(); 99 | 100 | while ( pEnd ) 101 | { 102 | m_path.push_front( m_pGraph->GetNode( pEnd->GetID() ) ); 103 | pEnd = pEnd->GetParent(); 104 | } 105 | 106 | } 107 | 108 | 109 | std::vector CWalker::GetConnections( CGraphNode * pNode ) 110 | { 111 | return m_pGraph->GetNodeConnections( pNode ); 112 | } -------------------------------------------------------------------------------- /Pathfinding/Walker.h: -------------------------------------------------------------------------------- 1 | #ifndef _CWALKER_H_ 2 | #define _CWALKER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class CGraph; 9 | class CGraphNode; 10 | 11 | class CWalker 12 | { 13 | public: 14 | using id_type = unsigned int; 15 | CWalker(); 16 | virtual ~CWalker(); 17 | //Find the path in 1 call 18 | virtual void FindPath( const std::shared_ptr& pGraph ); 19 | //Find the path by steps 20 | /**********************/ 21 | virtual void Setup( const std::shared_ptr& pGraph ); 22 | virtual bool Step() = 0; 23 | virtual void Cleanup(); 24 | /**********************/ 25 | //Max number of iterations before cancelling the search 26 | void SetMaxSteps( int iMaxSteps ); 27 | void SetBegin( id_type iBegin ); 28 | void SetEnd( id_type iEnd ); 29 | void ClearPath(); 30 | id_type GetBegin(); 31 | id_type GetEnd(); 32 | //Used externally when finding the path by steps 33 | CGraphNode* GetCurrentNode(); 34 | std::deque GetPath(); 35 | protected: 36 | virtual void LoadConnections( CGraphNode* pNode ) = 0; 37 | virtual void ClearNodes() = 0; 38 | void CreatePath( CGraphNode* pEnd ); 39 | std::vector GetConnections( CGraphNode* pNode ); 40 | protected: 41 | std::shared_ptr m_pGraph; 42 | CGraphNode* m_pCurrent; 43 | CGraphNode* m_pEnd; 44 | int m_iMaxSteps; 45 | int m_iCurrentSteps; 46 | id_type m_iBegin; 47 | id_type m_iEnd; 48 | private: 49 | std::deque m_path; 50 | 51 | }; 52 | 53 | #endif //_CWALKER_H_ 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pathfinding 2 | Common pathfinding algorithms 3 | 4 | A*, Dijkstra, Best First Search, Depth First Search & Breadth First Search algorithms implementation using C++11 5 | --------------------------------------------------------------------------------