├── .gitignore ├── CHANGELOG.md ├── Installer ├── .gitignore ├── Installer.vdproj └── sf.ico ├── LICENSE ├── README.md ├── Super Fusion.sln ├── ToDoList.txt ├── WinSparkle └── download.txt ├── main ├── .gitignore ├── AStar │ ├── ASBinaryTreeOpenListManager.h │ ├── ASBuildStateNode.h │ ├── ASEngine.h │ ├── ASHashTableBuildStateDuplicateManager.h │ ├── ASHashTableStoreStateDuplicateManager.h │ ├── ASMultipleParent.h │ ├── ASNoDuplicateManager.h │ ├── ASPriorityQueueOpenListManager.h │ ├── ASSingleParent.h │ ├── ASStoreStateNode.h │ └── ASVectorOpenListManager.h ├── Application.cpp ├── Application.h ├── ChartItem.h ├── ChartPanel.cpp ├── ChartPanel.h ├── Core │ ├── Compare.h │ ├── FastRand.cpp │ ├── FastRand.h │ ├── FastSortedQueue.h │ ├── FastString.cpp │ ├── FastString.h │ ├── HashFunction.cpp │ ├── HashFunction.h │ ├── Hashtable.cpp │ ├── Hashtable.h │ ├── LinkedList.cpp │ ├── LinkedList.h │ ├── Lock.h │ ├── LockFreeCircularQueue.h │ ├── LockFreeMemoryPool.cpp │ ├── LockFreeMemoryPool.h │ ├── MemoryPool.cpp │ ├── MemoryPool.h │ ├── MemoryPoolManager.cpp │ ├── MemoryPoolManager.h │ ├── PriorityQueue.h │ ├── ThreadPool.cpp │ ├── ThreadPool.h │ ├── Tokeniser.cpp │ ├── Tokeniser.h │ ├── Vector.cpp │ └── Vector.h ├── Details.txt ├── GA │ ├── GAChromosomeFitness.h │ ├── GAConfiguration.cpp │ ├── GAConfiguration.h │ ├── GAEngine.h │ ├── GANNChromosome.cpp │ ├── GANNChromosome.h │ ├── GAPopulation.cpp │ ├── GAPopulation.h │ ├── GAPopulationSort.h │ ├── GASequenceChromosome.cpp │ ├── GASequenceChromosome.h │ ├── GAStringFitnessCalc.cpp │ ├── GAStringFitnessCalc.h │ ├── GAValueArrayChromosome.h │ └── GAVillage.h ├── GridItem.h ├── GridOutput.cpp ├── GridOutput.h ├── MDIChild.cpp ├── MDIChild.h ├── MDIParent.cpp ├── MDIParent.h ├── MinMax.h ├── OutputPrintout.cpp ├── OutputPrintout.h ├── RaceChoiceDlg.cpp ├── RaceChoiceDlg.h ├── SC2 │ ├── FitnessCalc.h │ ├── FitnessValue.h │ ├── GameCalcs.cpp │ ├── GameCalcs.h │ ├── GasMicro.h │ ├── OutputFormat.cpp │ ├── OutputFormat.h │ ├── SC2AStar.cpp │ ├── SC2AStar.h │ ├── SC2Building.cpp │ ├── SC2Building.h │ ├── SC2BuildingStatus.cpp │ ├── SC2BuildingStatus.h │ ├── SC2Command.cpp │ ├── SC2Command.h │ ├── SC2Defines.h │ ├── SC2Event.cpp │ ├── SC2Event.h │ ├── SC2FitnessCalc.cpp │ ├── SC2FitnessCalc.h │ ├── SC2Output.cpp │ ├── SC2Output.h │ ├── SC2Race.cpp │ ├── SC2Race.h │ ├── SC2RaceData.cpp │ ├── SC2RaceData.h │ ├── SC2RaceInfo.cpp │ ├── SC2RaceInfo.h │ ├── SC2RequiredCommand.cpp │ ├── SC2RequiredCommand.h │ ├── SC2Research.cpp │ ├── SC2Research.h │ ├── SC2State.cpp │ ├── SC2State.h │ ├── SC2Target.cpp │ ├── SC2Target.h │ ├── SC2Unit.cpp │ ├── SC2Unit.h │ ├── SC2Version.cpp │ ├── SC2Version.h │ ├── SC2Waypoint.cpp │ ├── SC2Waypoint.h │ ├── TargetMinMax.cpp │ └── TargetMinMax.h ├── SC2Engine.cpp ├── SC2Engine.h ├── SCFusion.aps ├── SCFusion.rc ├── SCFusion_vc10.sln ├── SCFusion_vc10.vcxproj ├── SCFusion_vc10.vcxproj.filters ├── SCFusion_vc10.vcxproj.user ├── SCFusion_vc11.vcxproj ├── SCFusion_vc11.vcxproj.filters ├── SampleSaveFile.xml ├── SampleSaveFile2.xml ├── TimeTextCtrl.cpp ├── TimeTextCtrl.h ├── TimeValidator.cpp ├── TimeValidator.h ├── Versions │ └── StarCraft.xml ├── VisualItem.cpp ├── bitmaps │ ├── P.gif │ ├── Protoss.png │ ├── Protoss.xpm │ ├── SC2Fusion.png │ ├── SC2Fusion.xpm │ ├── SC2FusionF16.png │ ├── SC2FusionF32.png │ ├── SC2FusionF32.xpm │ ├── SC2FusionF64.png │ ├── SC2FusionSmall.png │ ├── SF16.xpm │ ├── SF32.xpm │ ├── T.gif │ ├── Terran.png │ ├── Terran.xpm │ ├── Z.gif │ ├── Z.xpm │ ├── Zerg.png │ ├── Zerg.xpm │ ├── copy.xpm │ ├── cut.xpm │ ├── gantt.xpm │ ├── help.xpm │ ├── new.xpm │ ├── open.xpm │ ├── paste.xpm │ ├── preview.xpm │ ├── print.xpm │ ├── protoss_icon.jpg │ ├── save.xpm │ ├── sc2_icon_protoss_16.png │ ├── sc2_icon_terran_16.png │ ├── sc2_icon_zerg_16.png │ ├── terran_icon.jpg │ └── zerg_icon.jpg ├── resource.h └── stdafx.h └── wxWidgets └── download.txt /.gitignore: -------------------------------------------------------------------------------- 1 | wxWidgets/* 2 | !wxWidgets/download.txt 3 | WinSparkle/* 4 | !WinSparkle/download.txt 5 | .vs 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## Super Fusion v2.2.3 9 | 10 | ### Upgrade for [Patch v5.0.14](https://news.blizzard.com/en-us/article/24162754/starcraft-ii-5-0-14-patch-notes) 11 | 12 | #### Nexus 13 | * Battery Overcharge removed. 14 | * New ability: Energy Recharge (50 Energy / 60 second cooldown). 15 | 16 | #### Stalker 17 | * Train time from Gateway reduced from 30 to 27 seconds. 18 | 19 | #### Tempest 20 | * Supply Cost reduced from 5 to 4. 21 | 22 | #### Immortal 23 | * Cost reduced from 275/100 to 250/100. 24 | 25 | #### Mothership 26 | * Cost increased from 300/300 to 400/400. 27 | * Supply cost increased from 6 to 8. 28 | 29 | #### Cyclone 30 | * Reverted to patch 5.0.11 Cyclone. 31 | 32 | #### Sensor Tower 33 | * Cost reduced from 125/100 to 100/50. 34 | 35 | #### Ghost 36 | * Supply cost increased from 2 to 3. 37 | 38 | #### Queen 39 | * Cost increased from 150/0 to 175/0. 40 | 41 | #### Hatchery 42 | * Cost reduced from 300/0 to 275/0. 43 | 44 | #### Hydralisk 45 | * New research: Nanomuscular Swell (researches new Lunge ability). Cost: 100/100, 64 seconds. Requires Hive. 46 | 47 | ### Upgrade for [Patch v5.0.13](https://news.blizzard.com/en-us/article/24078322/starcraft-ii-5-0-13-patch-notes) 48 | 49 | #### Armory 50 | * Cost reduced from 150/100 to 150/50. 51 | 52 | #### Engineering Bay 53 | * Infantry weapons/armor upgrades cost reduced from 100/175/250 to 100/150/200. 54 | 55 | #### Observer 56 | * Build time reduced from 21.4 to 17.9 seconds. 57 | 58 | ### Upgrade for [Patch v5.0.12](https://news.blizzard.com/en-us/article/24009150/starcraft-ii-5-0-12-patch-notes) 59 | 60 | #### Cyclone 61 | * Cost reduced from 150/100 to 125/50. 62 | * Tech Lab requirement removed. 63 | * Supply cost reduced from 3 to 2. 64 | * Mag-Field Accelerator upgrade removed. 65 | * New upgrade, increasing move speed to 4.73 (Cost: 100/100, 100 seconds, Researched at the Factory's Tech Lab). 66 | 67 | #### Medivac 68 | * Speed upgrade replaced with Caduceus Reactor - Increases Medivac's energy regeneration rate by 100% (Cost: 100/100/53.57 seconds, Upgraded from the Fusion Core). 69 | 70 | ### Raven 71 | * Interference Matrix now requires a research (Cost: 50/50, 57.14 seconds research time, Researched at the Starport's Tech Lab). 72 | 73 | #### Lurker 74 | * Adaptive Talons cost reduced from 150/150 to 100/100. 75 | 76 | #### Infestor 77 | * Pathogen Glands upgrade removed. 78 | * Infestor starting energy increased from 50 to 75. 79 | 80 | #### Ultralisk 81 | * Cost reduced from 300/200 to 275/200. 82 | 83 | #### Hydralisk 84 | * Speed upgrade research time reduced from 71 to 64 seconds. 85 | * Range upgrade research cost / time reduced from 100/100 / 71 seconds to 75/75 / 50 seconds. 86 | 87 | #### Baneling 88 | * Centrifugal Hooks cost reduced from 150/150 to 100/100. 89 | * Centrifugal Hooks research time reduced from 79 to 71. 90 | 91 | #### Spire 92 | * Air Armor upgrade cost reduced from 150/150, 225/225, 300/300 to 100/100, 175/175, 250/250 (Same as Air Weapons). 93 | 94 | #### Evolution Chamber 95 | * Armor upgrade cost reduced from 150/150, 225/225, 300/300 to 150/150, 200/200, 250/250. 96 | 97 | #### Forge 98 | * Shield upgrade cost reduced from 150/150, 225/225, 300/300 to 150/150, 200/200, 250/250. 99 | 100 | #### Cybernetics Core 101 | * Air Armor upgrade cost reduced from 150/150, 225/225, 300/300 to 100/100, 175/175, 250/250 (Same as Air Weapons). 102 | 103 | #### Disruptor 104 | * Supply cost increased from 3 to 4. 105 | 106 | #### Mothership 107 | * Cost reduced from 400/400 to 300/300. 108 | * Supply cost reduced from 8 to 6. 109 | * Build time reduced from 114 to 79. 110 | * No longer has energy (Spells are now cooldown based and require no energy to cast). 111 | 112 | ### Upgrade for [Patch v5.0.11](https://news.blizzard.com/en-us/article/23893118/starcraft-ii-5-0-11-patch-notes) 113 | 114 | #### Ravager 115 | * Build time increased from 8.57 to 12.14 seconds and removed the random delay of up to 0.36 seconds. 116 | 117 | #### Sentry 118 | * Build time reduced from 26.4 to 22.9 seconds. 119 | 120 | #### Forge 121 | * Level 1 upgrades research time reduced from 128.6 to 121.6. 122 | * Level 2 upgrades research time reduced from 153.6 to 144.6. 123 | * Level 3 upgrades research time reduced from 178.6 to 167.9. 124 | 125 | #### Liberator 126 | * Cost reduced from 150/150 to 150/125. 127 | 128 | #### Ghost 129 | * Enhanced Shockwaves upgrade removed. 130 | 131 | #### Banshee 132 | * Hyperflight Rotors research time reduced from 121.4 to 100 seconds. 133 | * Hyperflight Rotors cost reduced from 150/150 to 125/125. 134 | 135 | #### Raven 136 | * Gas cost reduced from 200 to 150. 137 | * Build time reduced from 42.9 to 34.3 seconds. 138 | * Corvid Reactor upgrade removed. 139 | -------------------------------------------------------------------------------- /Installer/.gitignore: -------------------------------------------------------------------------------- 1 | Release 2 | Debug -------------------------------------------------------------------------------- /Installer/sf.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrew-j-armstrong/SCFusion/d2e248e0f21194b10aa0f0bf64b93f715675534a/Installer/sf.ico -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Super Fusion 2 | Build order optimizer for StarCraft II 3 | 4 | ## How to compile 5 | 6 | Install Visual Studio Community 2022 from https://visualstudio.microsoft.com/downloads/ 7 | 8 | Download wxWidgets Windows binaries from https://www.wxwidgets.org/downloads/ 9 | 10 | - Header files 11 | - Development files 12 | - Release DLLs 13 | 14 | Download WinSparkle from https://github.com/vslavik/winsparkle/releases 15 | 16 | ## How to update version number for new release 17 | 18 | * Update CHANGELOG.md 19 | * Update version MDIParent.cpp (for UI) 20 | * Update versions in SCFusiom.rc 21 | * FILEVERSION 22 | * PRODUCTVERSION 23 | * FileVersion 24 | * ProductVersion 25 | * Update Installer 26 | * OutputFilename 27 | * ProductVersion (this will generate new ProductCode and PackageCode) 28 | * Publish updated appcast.xml and release notes 29 | -------------------------------------------------------------------------------- /Super Fusion.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31005.135 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SCFusion Main", "main\SCFusion_vc10.vcxproj", "{9F028A49-3F1C-527D-8A3B-B02716C5851E}" 7 | EndProject 8 | Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "Installer", "Installer\Installer.vdproj", "{AF6A7FEB-0D20-47B2-A078-BE3A0C2BF846}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|x86 = Debug|x86 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {9F028A49-3F1C-527D-8A3B-B02716C5851E}.Debug|x86.ActiveCfg = Debug|Win32 17 | {9F028A49-3F1C-527D-8A3B-B02716C5851E}.Debug|x86.Build.0 = Debug|Win32 18 | {9F028A49-3F1C-527D-8A3B-B02716C5851E}.Release|x86.ActiveCfg = Release|Win32 19 | {9F028A49-3F1C-527D-8A3B-B02716C5851E}.Release|x86.Build.0 = Release|Win32 20 | {AF6A7FEB-0D20-47B2-A078-BE3A0C2BF846}.Debug|x86.ActiveCfg = Debug 21 | {AF6A7FEB-0D20-47B2-A078-BE3A0C2BF846}.Release|x86.ActiveCfg = Release 22 | {AF6A7FEB-0D20-47B2-A078-BE3A0C2BF846}.Release|x86.Build.0 = Release 23 | EndGlobalSection 24 | GlobalSection(SolutionProperties) = preSolution 25 | HideSolutionNode = FALSE 26 | EndGlobalSection 27 | GlobalSection(ExtensibilityGlobals) = postSolution 28 | SolutionGuid = {A7B320F8-B71B-42E0-96F5-126A64B9D5E2} 29 | EndGlobalSection 30 | EndGlobal 31 | -------------------------------------------------------------------------------- /ToDoList.txt: -------------------------------------------------------------------------------- 1 | Handle Energy Upgrades 2 | Larvae Delay Time 3 | Create default build order file 4 | SCV Equivalent Drones 5 | 6 | 7 | Database: 8 | 9 | TargetBuild: 10 | - GameID 11 | - TargetBuildID 12 | - Build settings (gas micro) 13 | - Initial build 14 | - Stagnation Count 15 | - Request Count 16 | 17 | Waypoint: 18 | - WaypointID 19 | - TargetBuildID 20 | - WaypointIndex 21 | - MinTime 22 | - MaxTime 23 | 24 | BuildOrder: 25 | - BuildOrderID 26 | 27 | BuildOrderResult: 28 | - BuildOrderID 29 | - BuildingCount (1-32) 30 | - UnitCount (1-32) 31 | - ResearchCount (1-32) 32 | 33 | BuildOrderTime: 34 | - BuildOrderID 35 | - VersionID 36 | - Time 37 | 38 | BuildOrderCommands: 39 | - BuildOrderID 40 | - BuildOrderIndex 41 | - CommandID 42 | 43 | 44 | 45 | 46 | Initial build orders: 47 | 48 | m_initialBuildOrders["4 gate"] = 49 | "9 Pylon\n" \ 50 | "11 Chrono Nexus\n" \ 51 | "12 Gateway\n" \ 52 | "13 Chrono Nexus\n" \ 53 | "14 Assimilator\n" \ 54 | "16 3*Move Probe To Gas\n" \ 55 | "16 Pylon\n" \ 56 | "17 Cybernetics Core\n" \ 57 | "18 Zealot\n" \ 58 | "22 Warp Gate Transformation\n" \ 59 | "22 Chrono Cybernetics Core\n" \ 60 | "22 Stalker\n" \ 61 | "24 Chrono Cybernetics Core\n" \ 62 | "24 3*Gateway\n" \ 63 | "24 Chrono Cybernetics Core\n" \ 64 | "24 Stalker\n" \ 65 | "26 Pylon\n" \ 66 | "26 2*Chrono Cybernetics Core\n" \ 67 | "26 4*Convert Gateway To Warp Gate\n"; 68 | 69 | m_initialBuildOrders["3 gate robo"] = 70 | "9 Pylon\n" \ 71 | "11 Chrono Nexus\n" \ 72 | "12 Chrono Nexus\n" \ 73 | "13 Gateway\n" \ 74 | "15 Assimilator\n" \ 75 | "16 Pylon\n" \ 76 | "16 3*Move Probe To Gas\n" \ 77 | "17 Cybernetics Core\n" \ 78 | "18 Zealot\n" \ 79 | "22 Pylon\n" \ 80 | "22 Stalker\n" \ 81 | "24 Warp Gate Transformation\n" \ 82 | "24 Chrono Cybernetics Core\n" \ 83 | "25 Assimilator\n" \ 84 | "25 Chrono Cybernetics Core\n" \ 85 | "26 Gateway\n" \ 86 | "26 3*Move Probe To Gas\n" \ 87 | "26 Chrono Cybernetics Core\n" \ 88 | "27 Sentry\n" \ 89 | "30 Pylon\n" \ 90 | "30 Gateway\n" \ 91 | "31 Robotics Facility\n"; 92 | 93 | m_initialBuildOrders["3 gate expand"] = 94 | "9 Pylon\n" \ 95 | "11 Chrono Nexus\n" \ 96 | "12 Chrono Nexus\n" \ 97 | "13 Gateway\n" \ 98 | "15 Assimilator\n" \ 99 | "16 Pylon\n" \ 100 | "16 3*Move Probe To Gas\n" \ 101 | "18 Cybernetics Core\n" \ 102 | "20 Assimilator\n" \ 103 | "20 Zealot\n" \ 104 | "23 Warp Gate Transformation\n" \ 105 | "23 Chrono Cybernetics Core\n" \ 106 | "23 Pylon\n" \ 107 | "23 3*Move Probe To Gas\n" \ 108 | "24 Chrono Cybernetics Core\n" \ 109 | "24 Stalker\n" \ 110 | "26 Gateway\n" \ 111 | "27 Gateway\n" \ 112 | "27 Chrono Cybernetics Core\n" \ 113 | "28 Sentry\n" \ 114 | "31 Nexus\n"; 115 | 116 | m_initialBuildOrders["9 pylon 13 gate"] = 117 | "9 Pylon\n" \ 118 | "11 Chrono Nexus\n" \ 119 | "12 Chrono Nexus\n" \ 120 | "13 Gateway\n"; 121 | 122 | 123 | m_initialBuildOrders["1-1-1"] = 124 | "10 Supply Depot\n" \ 125 | "12 Barracks (Naked)\n" \ 126 | "13 Refinery\n" \ 127 | "15 3*Move SCV To Gas\n" \ 128 | "15 Orbital Command\n" \ 129 | "15 Marine\n" \ 130 | "16 Supply Depot\n" \ 131 | "16 Refinery\n" \ 132 | "16 Marine\n" \ 133 | "17 Calldown MULE\n" \ 134 | "18 3*Move SCV To Gas\n" \ 135 | "19 Factory (Naked)\n" \ 136 | "19 Barracks Tech Lab\n" \ 137 | "20 Marine\n" \ 138 | "23 Starport (Naked)\n"; 139 | 140 | m_initialBuildOrders["15 OC with gas"] = 141 | "10 Supply Depot\n" \ 142 | "12 Barracks (Naked)\n" \ 143 | "13 Refinery\n" \ 144 | "15 3*Move SCV To Gas\n" \ 145 | "15 Orbital Command\n"; 146 | 147 | m_initialBuildOrders["2 rax OC"] = 148 | "10 Supply Depot\n" \ 149 | "12 Barracks (Naked)\n" \ 150 | "14 Barracks (Naked)\n" \ 151 | "15 Marine\n" \ 152 | "15 Orbital Command\n"; 153 | 154 | m_initialBuildOrders["2 rax OC"] = 155 | "10 Supply Depot\n" \ 156 | "12 Barracks (Naked)\n" \ 157 | "14 Barracks (Naked)\n" \ 158 | "15 Marine\n" \ 159 | "15 Orbital Command\n"; 160 | 161 | 162 | m_initialBuildOrders["14 Pool 15 Hatch"] = 163 | "9 Overlord\n" \ 164 | "14 Spawning Pool\n" \ 165 | "15 Hatchery\n" \ 166 | "16 Queen\n" \ 167 | "18 Extractor\n" \ 168 | "17 Overlord\n" \ 169 | "17 Zergling\n"; 170 | 171 | m_initialBuildOrders["15 Hatch 15 Pool"] = 172 | "9 Overlord\n" \ 173 | "15 Hatchery\n" \ 174 | "15 Spawning Pool\n" \ 175 | "15 Extractor\n" \ 176 | "16 Overlord\n" \ 177 | "16 3*Move Drone To Gas\n" \ 178 | "17 Zergling\n" \ 179 | "18 Queen\n"; 180 | -------------------------------------------------------------------------------- /WinSparkle/download.txt: -------------------------------------------------------------------------------- 1 | Download from https://github.com/vslavik/winsparkle/releases -------------------------------------------------------------------------------- /main/.gitignore: -------------------------------------------------------------------------------- 1 | vc_mswud/ 2 | vc_mswu/ 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | *.exe 10 | *.pdb 11 | *.ilk 12 | *.res 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | 18 | # Compiled Static libraries 19 | *.lai 20 | *.la 21 | *.a 22 | 23 | # Debug files 24 | *.lastbuildstate 25 | *.embed.manifest 26 | *.embed.manifest.res 27 | *.intermediate.manifest 28 | *.vcxprojResolveAssemblyReference.cache 29 | SCFusion_manifest.rc 30 | 31 | # Build log files 32 | *.tlog 33 | SCFusion_vc10.log 34 | 35 | # Solution cache files 36 | *.opensdf 37 | *.sdf 38 | *.suo 39 | ipch/* 40 | -------------------------------------------------------------------------------- /main/AStar/ASBinaryTreeOpenListManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | class CASBinaryTreeOpenListManager 5 | { 6 | public: 7 | CASBinaryTreeOpenListManager() {} 8 | 9 | size_t size() const { return m_openList.size(); } 10 | TNode *pop_front() { return m_openList.pop_front(); } 11 | 12 | void Insert(TNode *node); 13 | void ReSort(TNode *node); 14 | 15 | protected: 16 | CVector m_openList; 17 | }; 18 | 19 | template 20 | void CASBinaryTreeOpenListManager::Insert(TNode *node) 21 | { 22 | size_t l = 0, r = m_openList.size(), i; 23 | 24 | while(r - l > 1) 25 | { 26 | i = (l + r)/2; 27 | if(m_openList[i]->GetCost() < node->GetCost()) 28 | l = i + 1; 29 | else 30 | r = i; 31 | } 32 | 33 | m_openList.insert(l, node); 34 | } 35 | 36 | template 37 | void CASBinaryTreeOpenListManager::ReSort(TNode *node) 38 | { 39 | for(size_t i=0; i < m_openList.size(); i++) 40 | { 41 | if(m_openList[i] == node) 42 | m_openList.erase(i); 43 | } 44 | 45 | Insert(node); 46 | } 47 | -------------------------------------------------------------------------------- /main/AStar/ASBuildStateNode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template class TParent, typename TTransition, typename TCost> 4 | class CASBuildStateNode : public CMemPoolNode> 5 | { 6 | public: 7 | typedef TParent, TTransition, TCost> CASParent; 8 | 9 | CASBuildStateNode(const TState &state, const TCost &expectedCost) : m_expectedCost(expectedCost) {} 10 | 11 | const CASParent &GetParent() const { return m_parent; } 12 | const TCost &GetCost() const { return m_parent.GetCost(); } 13 | const TCost &GetExpectedCost() const { return m_expectedCost; } 14 | void GetState(TState &state, const TConfig &config, const CVector &initialStates) const; 15 | bool AddParent(CASBuildStateNode *parent, const TCost &cost, const TTransition &transition) { return m_parent.AddParent(parent, cost, transition); } 16 | 17 | bool operator<(const CASBuildStateNode &node) const { return m_parent.GetCost() + m_expectedCost < node.GetCost() + node.GetExpectedCost(); } 18 | 19 | protected: 20 | CASParent m_parent; 21 | TCost m_expectedCost; 22 | }; 23 | 24 | template class TParent, typename TTransition, typename TCost> 25 | void CASBuildStateNode::GetState(TState &state, const TConfig &config, const CVector &initialStates) const 26 | { 27 | if(!m_parent.GetLastTransition()) 28 | state.Init(config); 29 | else 30 | { 31 | m_parent.GetParentNode()->GetState(state, config, initialStates); 32 | state.ApplyTransition(config, m_parent.GetParentNode()->GetCost(), m_parent.GetLastTransition()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /main/AStar/ASEngine.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | template class TParent, template class TParent, typename TTransition, typename TCost> class TNode, typename TTransition, typename TCost, template class TDuplicateManager, template class TOpenListManager> 6 | class CASEngine 7 | { 8 | public: 9 | typedef TNode CASNode; 10 | typedef TParent CASParent; 11 | typedef TDuplicateManager CASDuplicateManager; 12 | typedef TOpenListManager CASOpenListManager; 13 | 14 | CASEngine(const TConfig &config); 15 | ~CASEngine() { RemoveAllPointer(m_closedNodes); } 16 | 17 | void AddInitialState(const TState &state) { m_initialStates.push_back(state); } 18 | 19 | void Reset(); 20 | void Run(); 21 | void Stop() { m_stop = true; } 22 | 23 | const CASNode *GetFinalNode() const { return m_finalNode; } 24 | 25 | protected: 26 | const TConfig &m_config; 27 | CASDuplicateManager m_duplicateManager; 28 | CASOpenListManager m_openNodes; 29 | CVector m_initialStates; 30 | CVector m_closedNodes; 31 | bool m_stop; 32 | CASNode *m_finalNode; 33 | }; 34 | 35 | template class TParent, template class TParent, typename TTransition, typename TCost> class TNode, typename TTransition, typename TCost, template class TDuplicateManager, template class TOpenListManager> 36 | CASEngine::CASEngine(const TConfig &config) 37 | : m_config(config), m_duplicateManager(), m_openNodes(), m_initialStates(), m_closedNodes(), m_stop(false), m_finalNode(NULL) 38 | { 39 | } 40 | 41 | template class TParent, template class TParent, typename TTransition, typename TCost> class TNode, typename TTransition, typename TCost, template class TDuplicateManager, template class TOpenListManager> 42 | void CASEngine::Reset() 43 | { 44 | m_stop = false; 45 | for(size_t i=0; i < m_initialStates.size(); i++) 46 | m_openNodes.Insert(new CASNode(m_initialStates[i], m_initialStates[i].CalculateExpectedCost(m_config))); 47 | } 48 | 49 | template class TParent, template class TParent, typename TTransition, typename TCost> class TNode, typename TTransition, typename TCost, template class TDuplicateManager, template class TOpenListManager> 50 | void CASEngine::Run() 51 | { 52 | ofstream output("temp.txt"); 53 | 54 | CVector transitions; 55 | while(!m_stop && m_openNodes.size() > 0) 56 | { 57 | CASNode *node = m_openNodes.pop_front(); 58 | m_closedNodes.push_back(node); 59 | 60 | const CASNode *parentSearch = node; 61 | output << m_openNodes.size() << ", " << node->GetCost().GetTime() << ", " << node->GetExpectedCost().GetTime() << ": "; 62 | while(parentSearch) 63 | { 64 | output << tostring(eOutputFormatDetailed, parentSearch->GetParent().GetLastTransition()); 65 | output << ","; 66 | 67 | parentSearch = parentSearch->GetParent().GetParentNode(); 68 | } 69 | output << endl; 70 | 71 | TState state; 72 | node->GetState(state, m_config, m_initialStates); 73 | 74 | if(state.IsCompleted(m_config)) 75 | { 76 | m_finalNode = node; 77 | break; 78 | } 79 | 80 | transitions.clear(); 81 | state.GetTransitions(m_config, transitions); 82 | 83 | for(size_t i=0; i < transitions.size(); i++) 84 | { 85 | const TTransition &transition = transitions[i]; 86 | TState newState = state; 87 | TCost newCost = newState.ApplyTransition(m_config, node->GetCost(), transition); 88 | CASNode *duplicateNode = m_duplicateManager.GetDuplicate(newState); 89 | if(duplicateNode) 90 | { 91 | if(duplicateNode->AddParent(node, newCost, transition)) 92 | { 93 | m_openNodes.ReSort(duplicateNode); 94 | } 95 | } 96 | else 97 | { 98 | CASNode *newNode = new CASNode(newState, newState.CalculateExpectedCost(m_config)); 99 | newNode->AddParent(node, newCost, transition); 100 | m_openNodes.Insert(newNode); 101 | m_duplicateManager.Insert(newState, node); 102 | } 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /main/AStar/ASHashTableBuildStateDuplicateManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | class CASHashTableBuildStateDuplicateManager 5 | { 6 | public: 7 | CASHashTableBuildStateDuplicateManager(); 8 | 9 | void Insert(TNode *node); 10 | TNode *GetDuplicate(const TState &state); 11 | 12 | protected: 13 | Hashtable m_hashTable; 14 | }; 15 | -------------------------------------------------------------------------------- /main/AStar/ASHashTableStoreStateDuplicateManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Core/Hashtable.h" 4 | 5 | template 6 | class CASHashTableStoreStateDuplicateManager 7 | { 8 | public: 9 | CASHashTableStoreStateDuplicateManager() {} 10 | 11 | TNode *GetDuplicate(const TState &state); 12 | 13 | void Insert(const TState &state, TNode *node); 14 | 15 | protected: 16 | CHashtable m_hashTable; 17 | }; 18 | 19 | template 20 | TNode *CASHashTableStoreStateDuplicateManager::GetDuplicate(const TState &state) 21 | { 22 | TNode *pNode = NULL;; 23 | m_hashTable.Lookup(state, pNode); 24 | return pNode; 25 | } 26 | 27 | template 28 | void CASHashTableStoreStateDuplicateManager::Insert(const TState &state, TNode *node) 29 | { 30 | m_hashTable.SetAt(state, node); 31 | } 32 | -------------------------------------------------------------------------------- /main/AStar/ASMultipleParent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | class CASMultipleParent : public CMemPoolNode> 5 | { 6 | public: 7 | CASMultipleParent() : m_minimumCost() {} 8 | CASMultipleParent(TNode *parent, const TCost &cost, const TTransition &transition) : m_minimumCost(cost) { m_parents.push_back(CEntry(parent, transition, m_cost)); } 9 | ~CASMultipleParent() {} 10 | 11 | bool AddParent(TNode *parent, const TCost &cost, const TTransition &transition); 12 | const TCost &GetCost() const { return m_minimumCost; } 13 | 14 | protected: 15 | struct CEntry 16 | { 17 | CEntry(TNode *parent, const TTransition &transition, const TCost &cost) : m_parent(parent), m_transition(transition), m_cost(cost) {} 18 | 19 | TNode *m_parent; 20 | TTransition m_transition; 21 | TCost m_cost; 22 | }; 23 | 24 | CVector m_parents; 25 | TCost m_minimumCost; 26 | }; 27 | 28 | template 29 | bool CASMultipleParent::AddParent(TNode *parent, const TCost &cost, const TTransition &transition) 30 | { 31 | m_parents.push_back(CEntry(parent, transition, m_cost)); 32 | 33 | if(cost < m_minimumCost) 34 | { 35 | m_minimumCost = cost; 36 | return true; 37 | } 38 | else 39 | return false; // Cost hasn't changed 40 | } 41 | -------------------------------------------------------------------------------- /main/AStar/ASNoDuplicateManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | class CASNoDuplicateManager 5 | { 6 | public: 7 | CASNoDuplicateManager() {} 8 | 9 | TNode *GetDuplicate(const TState &state) { return NULL; } 10 | 11 | void Insert(const TState &state, TNode *node) {} 12 | }; 13 | -------------------------------------------------------------------------------- /main/AStar/ASPriorityQueueOpenListManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Core/PriorityQueue.h" 3 | 4 | template 5 | class CASPriorityQueueOpenListManager 6 | { 7 | public: 8 | class CASPriorityQueueOpenListManager() {} 9 | 10 | size_t size() const { return m_openList.size(); } 11 | TNode *pop_front() { return m_openList.pop(); } 12 | 13 | void Insert(TNode *node); 14 | void ReSort(TNode *node); 15 | 16 | protected: 17 | CPriorityQueue> m_openList; 18 | }; 19 | 20 | template 21 | void CASPriorityQueueOpenListManager::Insert(TNode *node) 22 | { 23 | m_openList.add(node); 24 | } 25 | 26 | template 27 | void CASPriorityQueueOpenListManager::ReSort(TNode *node) 28 | { 29 | for(size_t i=0; i < m_openList.size(); i++) 30 | { 31 | if(m_openList[i] == node) 32 | m_openList.pop(i); 33 | } 34 | 35 | Insert(node); 36 | } 37 | -------------------------------------------------------------------------------- /main/AStar/ASSingleParent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | class CASSingleParent : public CMemPoolNode> 5 | { 6 | public: 7 | CASSingleParent() : m_parent(NULL), m_lastTransition(), m_cost() {} 8 | CASSingleParent(TNode *parent, const TCost &cost, const TTransition &transition) : m_parent(parent), m_lastTransition(transition), m_cost(cost) {} 9 | ~CASSingleParent() {} 10 | 11 | bool AddParent(TNode *parent, const TCost &cost, const TTransition &transition); 12 | const TCost &GetCost() const { return m_cost; } 13 | const TTransition &GetLastTransition() const { return m_lastTransition; } 14 | const TNode *GetParentNode() const { return m_parent; } 15 | 16 | protected: 17 | TNode *m_parent; 18 | TTransition m_lastTransition; 19 | TCost m_cost; 20 | }; 21 | 22 | template 23 | bool CASSingleParent::AddParent(TNode *parent, const TCost &cost, const TTransition &transition) 24 | { 25 | if(m_parent && !(cost < m_cost)) 26 | return false; 27 | 28 | m_parent = parent; 29 | m_lastTransition = transition; 30 | m_cost = cost; 31 | 32 | return true; 33 | } 34 | -------------------------------------------------------------------------------- /main/AStar/ASStoreStateNode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template class TParent, typename TTransition, typename TCost> 4 | class CASStoreStateNode : public CMemPoolNode /*, 100000, 1 */> 5 | { 6 | public: 7 | typedef TParent, TTransition, TCost> CASParent; 8 | 9 | CASStoreStateNode(const TState &state, const TCost &expectedCost) : m_state(state), m_expectedCost(expectedCost) {} 10 | 11 | const CASParent &GetParent() const { return m_parent; } 12 | const TCost &GetCost() const { return m_parent.GetCost(); } 13 | void GetState(TState &state, const TConfig &config, const CVector &initialStates) const { state = m_state; } 14 | bool AddParent(CASStoreStateNode *parent, const TCost &cost, const TTransition &transition) { return m_parent.AddParent(parent, cost, transition); } 15 | 16 | protected: 17 | CASParent m_parent; 18 | TCost m_expectedCost; 19 | TState m_state; 20 | }; 21 | -------------------------------------------------------------------------------- /main/AStar/ASVectorOpenListManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | class CASVectorOpenListManager 5 | { 6 | public: 7 | CASVectorOpenListManager() {} 8 | ~CASVectorOpenListManager() { RemoveAllPointer(m_openList); } 9 | 10 | size_t size() const { return m_openList.size(); } 11 | TNode *pop_front() { return m_openList.pop_front(); } 12 | 13 | void Insert(TNode *node); 14 | void ReSort(TNode *node); 15 | 16 | protected: 17 | CVector m_openList; 18 | }; 19 | 20 | template 21 | void CASVectorOpenListManager::Insert(TNode *node) 22 | { 23 | size_t l = 0, r = m_openList.size(), i; 24 | 25 | while(r - l > 1) 26 | { 27 | i = (l + r)/2; 28 | if(m_openList[i]->GetCost() < node->GetCost()) 29 | l = i + 1; 30 | else 31 | r = i; 32 | } 33 | 34 | m_openList.insert(l, node); 35 | } 36 | 37 | template 38 | void CASVectorOpenListManager::ReSort(TNode *node) 39 | { 40 | for(size_t i=0; i < m_openList.size(); i++) 41 | { 42 | if(m_openList[i] == node) 43 | m_openList.erase(i); 44 | } 45 | 46 | Insert(node); 47 | } 48 | -------------------------------------------------------------------------------- /main/Application.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Application.h" 3 | #include "MDIParent.h" 4 | #include "winsparkle.h" 5 | 6 | IMPLEMENT_APP(MyApp) 7 | 8 | // Initialise this in OnInit, not statically 9 | bool MyApp::OnInit() 10 | { 11 | CMemoryPoolManager::InitialiseSingleton(); 12 | CMemPoolNodePoolManager::Get()->InitialiseThread(); 13 | 14 | if ( !wxApp::OnInit() ) 15 | return false; 16 | 17 | // Set Priority 18 | #ifndef _DEBUG 19 | if(!SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS)) 20 | { 21 | // Just fail silently 22 | //DWORD dwError = GetLastError(); 23 | //wxMessageBox(wxString::Format("Failed to set process priority (%d)", dwError)); 24 | } 25 | #endif 26 | 27 | // Create the main frame window 28 | MyFrame *frame = new MyFrame(); 29 | frame->Show(true); 30 | SetTopWindow(frame); 31 | 32 | // Initialize WinSparkle as soon as the app itself is initialized, right 33 | // before entering the event loop: 34 | #ifndef _DEBUG 35 | win_sparkle_set_appcast_url("https://andrew-j-armstrong.github.io/SCFusion/releases/appcast.xml"); 36 | win_sparkle_init(); 37 | #endif 38 | 39 | return true; 40 | } 41 | 42 | int MyApp::OnExit() 43 | { 44 | #ifndef _DEBUG 45 | win_sparkle_cleanup(); 46 | #endif 47 | return 0; 48 | } -------------------------------------------------------------------------------- /main/Application.h: -------------------------------------------------------------------------------- 1 | #ifndef _APPLICATION_H_ 2 | #define _APPLICATION_H_ 3 | 4 | class MyApp : public wxApp 5 | { 6 | public: 7 | virtual bool OnInit(); 8 | virtual int OnExit(); 9 | }; 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /main/ChartItem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class ChartItem 6 | { 7 | 8 | public: 9 | enum ChartItemType 10 | { 11 | tDefault, 12 | tBase, 13 | tSupply, 14 | tGas, 15 | tStatus, 16 | tMilitary, 17 | tMilitaryUnit, 18 | tWorker, 19 | tResearch, 20 | tMilestone 21 | }; 22 | 23 | enum QueueType 24 | { 25 | qSingle, 26 | qDoublePrimary, 27 | qDoubleSecondary 28 | }; 29 | 30 | ChartItem(wxString name, double startTime, double endTime, ChartItemType itemType = tDefault, QueueType queueType = qSingle) 31 | { 32 | this->startTime = startTime; 33 | this->endTime = endTime; 34 | this->name = name; 35 | this->itemType = itemType; 36 | this->queueType = queueType; 37 | } 38 | 39 | wxString name; 40 | double startTime; 41 | double endTime; 42 | ChartItemType itemType; 43 | QueueType queueType; 44 | }; -------------------------------------------------------------------------------- /main/ChartPanel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "ChartItem.h" 6 | 7 | using std::vector; 8 | 9 | class ChartPanel : public wxScrolledWindow 10 | { 11 | 12 | public: 13 | ChartPanel(wxFrame* parent, wxWindowID id); 14 | 15 | void OnDraw(wxDC& dc); 16 | bool ExportSVG(wxString filename); 17 | 18 | void SetChartItems(vector> chartItems); 19 | void SetColorfulOutput(); 20 | void SetPlainOutput(); 21 | 22 | wxColor ChartPanel::GetBrushColorByType(ChartItem::ChartItemType itemType); 23 | 24 | DECLARE_EVENT_TABLE() 25 | 26 | protected: 27 | vector> m_chart_items; 28 | vector> m_stray_chart_items; 29 | vector m_milestones; 30 | int m_width; 31 | int m_height; 32 | bool m_colorful = false; 33 | }; 34 | -------------------------------------------------------------------------------- /main/Core/Compare.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | struct PtrLess 5 | { 6 | public: 7 | bool operator()(const T &t1, const T &t2) { return (*t1) < (*t2); } 8 | }; 9 | 10 | template 11 | struct Less 12 | { 13 | public: 14 | bool operator()(const T &t1, const T &t2) { return t1 < t2; } 15 | }; 16 | -------------------------------------------------------------------------------- /main/Core/FastRand.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "FastRand.h" 3 | 4 | __declspec( align(16) ) static __m128i cur_seed; 5 | 6 | short rand_sse() 7 | { 8 | unsigned int result[4]; 9 | rand_sse(result); 10 | return (short)*result; 11 | } 12 | 13 | void srand_sse( unsigned int seed ) 14 | { 15 | cur_seed = _mm_set_epi32( seed, seed+1, seed, seed+1 ); 16 | } 17 | 18 | void rand_sse( unsigned int* result ) 19 | { 20 | __declspec( align(16) ) __m128i cur_seed_split; 21 | __declspec( align(16) ) __m128i multiplier; 22 | __declspec( align(16) ) __m128i adder; 23 | __declspec( align(16) ) __m128i mod_mask; 24 | __declspec( align(16) ) __m128i sra_mask; 25 | #ifdef RAND_SSE_COMPATABILITY 26 | __declspec( align(16) ) __m128i sseresult; 27 | #endif 28 | 29 | __declspec( align(16) ) static const unsigned int mult[4] ={ 214013, 17405, 214013, 69069 }; 30 | __declspec( align(16) ) static const unsigned int gadd[4] ={ 2531011, 10395331, 13737667, 1 }; 31 | __declspec( align(16) ) static const unsigned int mask[4] ={ 0xFFFFFFFF, 0, 0xFFFFFFFF, 0 }; 32 | __declspec( align(16) ) static const unsigned int masklo[4] ={ 0x00007FFF, 0x00007FFF, 0x00007FFF, 0x00007FFF }; 33 | 34 | adder = _mm_load_si128( (__m128i*) gadd); 35 | multiplier = _mm_load_si128( (__m128i*) mult); 36 | mod_mask = _mm_load_si128( (__m128i*) mask); 37 | sra_mask = _mm_load_si128( (__m128i*) masklo); 38 | cur_seed_split = _mm_shuffle_epi32( cur_seed, _MM_SHUFFLE( 2, 3, 0, 1 ) ); 39 | cur_seed = _mm_mul_epu32( cur_seed, multiplier ); 40 | multiplier = _mm_shuffle_epi32( multiplier, _MM_SHUFFLE( 2, 3, 0, 1 ) ); 41 | cur_seed_split = _mm_mul_epu32( cur_seed_split, multiplier ); 42 | cur_seed = _mm_and_si128( cur_seed, mod_mask); 43 | cur_seed_split = _mm_and_si128( cur_seed_split, mod_mask ); 44 | cur_seed_split = _mm_shuffle_epi32( cur_seed_split, _MM_SHUFFLE( 2, 3, 0, 1 ) ); 45 | cur_seed = _mm_or_si128( cur_seed, cur_seed_split ); 46 | cur_seed = _mm_add_epi32( cur_seed, adder); 47 | 48 | #ifdef RAND_SSE_COMPATABILITY // Add the lines below if you wish to reduce your results to 16-bit vals... 49 | sseresult = _mm_srai_epi32( cur_seed, 16); 50 | sseresult = _mm_and_si128( sseresult, sra_mask ); 51 | _mm_storeu_si128( (__m128i*) result, sseresult ); 52 | return; 53 | #endif 54 | _mm_storeu_si128( (__m128i*) result, cur_seed); 55 | return; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /main/Core/FastRand.h: -------------------------------------------------------------------------------- 1 | #ifndef RAND_SSE_H 2 | #define RAND_SSE_H 3 | 4 | #include "emmintrin.h" 5 | 6 | #define RAND_SSE_COMPATABILITY 7 | //define this if you wish to return values similar to the standard rand(); 8 | 9 | void srand_sse( unsigned int seed ); 10 | short rand_sse(); 11 | void rand_sse( unsigned int* ); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /main/Core/FastSortedQueue.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MemoryPool.h" 4 | #include "MemoryPoolManager.h" 5 | 6 | template 7 | class CFastSortedQueue : public CMemPoolNode> 8 | { 9 | public: 10 | CFastSortedQueue() : m_size(0), m_capacity(0), m_dataStart(0), m_dataEnd(0), m_queueFront(0), m_queueEnd(0) {} 11 | CFastSortedQueue(const CFastSortedQueue &queue); 12 | ~CFastSortedQueue(); 13 | 14 | size_t size() const { return m_size; } 15 | size_t capacity() const { return m_capacity; } 16 | 17 | void erase(size_t index, size_t count = 1); 18 | void capacity(size_t capacity); 19 | 20 | void insert(const T &val); 21 | void push_back(const T &val); 22 | T &pop_front() { m_size--; return *(m_queueFront++); } 23 | 24 | void truncate(size_t size) { if(size >= m_size) return; m_size = size; } 25 | 26 | const T &operator[](size_t index) const { return m_data[index]; } 27 | T &operator[](size_t index) { return m_data[index]; } 28 | 29 | const T *front() const { return m_queueFront; } 30 | const T *end() const { return m_queueEnd - 1; } 31 | 32 | T *front() { return m_queueFront; } 33 | T *end() { return m_queueEnd - 1; } 34 | 35 | protected: 36 | size_t m_size; 37 | size_t m_capacity; 38 | T *m_dataStart; 39 | T *m_dataEnd; 40 | T *m_queueFront; 41 | T *m_queueEnd; 42 | }; 43 | 44 | template 45 | CFastSortedQueue::CFastSortedQueue(const CFastSortedQueue &queue) 46 | : m_size(0), m_capacity(0), m_data(0) 47 | { 48 | capacity(queue.size()); 49 | T *data = m_dataStart; 50 | const T *vecData = queue.front(); 51 | for(size_t index = 0; index < queue.size(); index++) 52 | *(data++) = *(vecData++); 53 | m_size = queue.size(); 54 | } 55 | 56 | template 57 | CFastSortedQueue::~CFastSortedQueue() 58 | { 59 | if(m_dataStart) 60 | m_memoryPoolManager->GetMemoryPool(m_capacity * sizeof(T))->Free(m_dataStart); 61 | } 62 | 63 | template 64 | void CFastSortedQueue::push_back(const T &val) 65 | { 66 | capacity(m_size + 1); 67 | if(m_queueEnd == m_dataEnd) 68 | memmove(m_dataStart, m_queueStart, m_size * sizeof(T)); 69 | *(m_queueEnd++) = val; 70 | } 71 | 72 | template 73 | void CFastSortedQueue::insert(const T &val) 74 | { 75 | capacity(m_size + 1); 76 | 77 | // Binary search to find correct index 78 | T *start = m_queueFront; 79 | T *end = m_queueEnd; 80 | while(start != end) 81 | { 82 | T *mid = start + (end - start)/2; 83 | if(*mid < val) 84 | start = mid + 1; 85 | else 86 | end = mid; 87 | } 88 | 89 | if(m_queueFront > m_dataStart) 90 | { 91 | // Move first half backwards 92 | memmove(m_queueFront - 1, m_queueFront, (start - m_queueFront) * sizeof(T)); 93 | start--; 94 | m_queueFront--; 95 | } 96 | else 97 | { 98 | // Move second half forwards 99 | memmove(start + 1, start, (m_queueEnd - start) * sizeof(T)); 100 | m_queueEnd++; 101 | } 102 | 103 | *start = val; 104 | m_size++; 105 | } 106 | 107 | template 108 | void CFastSortedQueue::erase(size_t index, size_t count /* = 1 */) 109 | { 110 | memmove(&m_queueFront[index], &m_queueFront[index + count], (m_size - count - index) * sizeof(T)); 111 | m_size -= count; 112 | m_queueEnd -= count; 113 | } 114 | 115 | template 116 | void CFastSortedQueue::capacity(size_t capacity) 117 | { 118 | if(m_capacity > capacity) 119 | return; 120 | 121 | size_t newCapacity = m_capacity > 0 ? m_capacity : 128; 122 | while(newCapacity < capacity + 1) 123 | newCapacity <<= 1; 124 | 125 | T *newData = (T *)CMemoryPoolManager::Get()->GetMemoryPoolAddAsNeeded(newCapacity * sizeof(T))->Alloc(); 126 | if(m_dataStart) 127 | { 128 | memcpy(newData, m_queueFront, m_size * sizeof(T)); 129 | m_memoryPoolManager->GetMemoryPool(m_capacity * sizeof(T))->Free(m_dataStart); 130 | } 131 | 132 | // Initialise values 133 | T *init = &newData[m_capacity]; 134 | for(size_t index = m_capacity; index < newCapacity; index++) 135 | new (init++) T(); 136 | 137 | m_capacity = newCapacity; 138 | m_dataStart = newData; 139 | m_dataEnd = m_dataStart + m_capacity; 140 | m_queueFront = m_dataStart; 141 | m_queueEnd = m_dataStart + m_size; 142 | } 143 | -------------------------------------------------------------------------------- /main/Core/FastString.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "FastString.h" 3 | 4 | CFastString::CFastString(const CFastString &str) 5 | : m_capacity(0), m_length(0), m_data(0) 6 | { 7 | push_back(str); 8 | } 9 | 10 | CFastString::CFastString(const char *str) 11 | : m_capacity(0), m_length(0), m_data(0) 12 | { 13 | push_back(str); 14 | } 15 | 16 | CFastString::~CFastString() 17 | { 18 | if(m_data) 19 | CMemoryPoolManager::Get()->GetMemoryPool(m_capacity)->Free(m_data); 20 | } 21 | 22 | void CFastString::capacity(size_t size) 23 | { 24 | if(m_capacity >= size + 1) 25 | return; 26 | 27 | size_t newCapacity = m_capacity > 0 ? m_capacity : 16; 28 | while(newCapacity < size + 1) 29 | newCapacity <<= 1; 30 | 31 | char *newData = (char *)CMemoryPoolManager::Get()->GetMemoryPoolAddAsNeeded(newCapacity)->Alloc(); 32 | if(m_data) 33 | { 34 | memcpy(newData, m_data, m_capacity); 35 | CMemoryPoolManager::Get()->GetMemoryPool(m_capacity)->Free(m_data); 36 | } 37 | else 38 | newData[0] = '\0'; 39 | m_data = newData; 40 | m_capacity = newCapacity; 41 | } 42 | 43 | void CFastString::insert(size_t index, char c) 44 | { 45 | capacity(m_length + 1); 46 | memmove(&m_data[index+1], &m_data[index], m_length + 1 - index); 47 | m_data[index] = c; 48 | m_length++; 49 | } 50 | 51 | void CFastString::erase(size_t index, size_t count) 52 | { 53 | memmove(&m_data[index], &m_data[index+count], m_length + 1 - index - count); 54 | m_length -= count; 55 | } 56 | 57 | 58 | void CFastString::push_back(const CFastString &str, size_t length /* = str.length() */) 59 | { 60 | if(str.length() < length) 61 | length = str.length(); 62 | 63 | push_back(str.data(), length); 64 | } 65 | 66 | void CFastString::push_back(const char *str, size_t length /* = strlen(str) */) 67 | { 68 | if(length <= 0) 69 | return; 70 | 71 | capacity(m_length + length); 72 | memmove(&m_data[m_length], str, length + 1); 73 | m_length += length; 74 | } 75 | 76 | bool CFastString::operator==(const CFastString &str) const 77 | { 78 | if(str.length() != m_length) 79 | return false; 80 | else if(0 == m_length) 81 | return true; 82 | else 83 | return 0 == strcmp(m_data, str.data()); 84 | } 85 | 86 | bool CFastString::operator <(const CFastString &str) const 87 | { 88 | if(0 == m_length) 89 | return 0 != str.length(); 90 | else if(0 == str.length()) 91 | return false; 92 | else 93 | return strcmp(m_data, str.data()) < 0; 94 | } 95 | 96 | void CFastString::operator =(const CFastString &str) 97 | { 98 | capacity(str.length()); 99 | m_length = str.length(); 100 | memcpy(m_data, str.data(), m_length + 1); 101 | } 102 | 103 | void CFastString::push_back(char c) 104 | { 105 | capacity(m_length + 1); 106 | m_data[m_length] = c; 107 | m_data[m_length + 1] = '\0'; 108 | m_length++; 109 | } 110 | 111 | ostream& operator<< (ostream& out, const CFastString &str ) 112 | { 113 | if(str.length() > 0) 114 | out << str.data(); 115 | 116 | return out; 117 | } 118 | -------------------------------------------------------------------------------- /main/Core/FastString.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "MemoryPoolManager.h" 6 | #include "MemoryPool.h" 7 | 8 | class CFastString 9 | { 10 | public: 11 | CFastString() : m_capacity(0), m_length(0), m_data(0) { } 12 | CFastString(const CFastString &str); 13 | CFastString(const char *str); 14 | virtual ~CFastString(); 15 | 16 | const char &operator[](size_t index) const { return m_data[index]; } 17 | char &operator[](size_t index) { return m_data[index]; } 18 | void operator+=(const CFastString &str) { push_back(str); } 19 | void operator+=(char c) { push_back(c); } 20 | void operator =(const CFastString &str); 21 | bool operator==(const CFastString &str) const; 22 | bool operator <(const CFastString &str) const; 23 | 24 | void push_back(const CFastString &str) { push_back(str, str.length()); } 25 | void push_back(const CFastString &str, size_t length); 26 | void push_back(const char *str) { push_back(str, strlen(str)); } 27 | void push_back(const char *str, size_t length); 28 | void push_back(char c); 29 | 30 | size_t capacity() const { return m_capacity; } 31 | void capacity(size_t size); 32 | 33 | size_t length() const { return m_length; } 34 | void length(size_t size) { capacity(size); m_data[size] = '\0'; m_length = size; } 35 | const char *data() const { return m_data; } 36 | const char *mid(size_t index) const { if(index > m_length) return 0; return &m_data[index]; } 37 | void insert(size_t index, char c); 38 | void erase(size_t index, size_t count); 39 | 40 | void LargestCommonSubsequence(const CFastString &s1, const CFastString &s2) const; 41 | 42 | protected: 43 | size_t m_capacity; 44 | size_t m_length; 45 | char *m_data; 46 | }; 47 | 48 | ostream& operator<< (ostream& out, const CFastString &str ); -------------------------------------------------------------------------------- /main/Core/HashFunction.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | unsigned long MurmurHash2 ( const void * key, int len, unsigned long seed ) 4 | { 5 | // 'm' and 'r' are mixing constants generated offline. 6 | // They're not really 'magic', they just happen to work well. 7 | 8 | const unsigned long m = 0x5bd1e995; 9 | const int r = 24; 10 | 11 | // Initialize the hash to a 'random' value 12 | 13 | unsigned long h = seed ^ len; 14 | 15 | // Mix 4 bytes at a time into the hash 16 | 17 | const unsigned char * data = (const unsigned char *)key; 18 | 19 | while(len >= 4) 20 | { 21 | unsigned long k = *(unsigned long *)data; 22 | 23 | k *= m; 24 | k ^= k >> r; 25 | k *= m; 26 | 27 | h *= m; 28 | h ^= k; 29 | 30 | data += 4; 31 | len -= 4; 32 | } 33 | 34 | // Handle the last few bytes of the input array 35 | 36 | switch(len) 37 | { 38 | case 3: h ^= data[2] << 16; 39 | case 2: h ^= data[1] << 8; 40 | case 1: h ^= data[0]; 41 | h *= m; 42 | }; 43 | 44 | // Do a few final mixes of the hash to ensure the last few 45 | // bytes are well-incorporated. 46 | 47 | h ^= h >> 13; 48 | h *= m; 49 | h ^= h >> 15; 50 | 51 | return h; 52 | } 53 | -------------------------------------------------------------------------------- /main/Core/HashFunction.h: -------------------------------------------------------------------------------- 1 | unsigned long MurmurHash2 ( const void * key, int len, unsigned long seed ); -------------------------------------------------------------------------------- /main/Core/Hashtable.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Core/Hashtable.h" 3 | 4 | size_t GetNextPrimeSize(size_t nDesiredSize) 5 | { 6 | const static size_t arrPrimes[] = {17, 101, 251, 503, 1009, 2003, 4001, 8009, 12007, 16001, 32003, 64007, 128021, 256019, 512009, 1024021, 2048003, 4096013, 8192003, 16384001, 32768011, 65536043, 131072003}; 7 | 8 | int nCount = sizeof(arrPrimes)/sizeof(arrPrimes[0]); 9 | for(int n = 0 ; n < nCount ; ++n) 10 | { 11 | if(arrPrimes[n] > nDesiredSize) 12 | return arrPrimes[n]; 13 | } 14 | 15 | size_t nSize = arrPrimes[nCount-1]; 16 | 17 | // Pretty crude but should be alright 18 | while(nSize < nDesiredSize) 19 | nSize = 2*nSize + 1; 20 | 21 | return nSize; 22 | } 23 | -------------------------------------------------------------------------------- /main/Core/LinkedList.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Core/LinkedList.h" 3 | 4 | -------------------------------------------------------------------------------- /main/Core/LinkedList.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MemoryPool.h" 4 | #include "Compare.h" 5 | 6 | template 7 | class CLinkedList : public CMemPoolNode> 8 | { 9 | protected: 10 | T m_data; 11 | CLinkedList *m_pNext; 12 | 13 | public: 14 | CLinkedList(const T &data, CLinkedList *pNext = NULL); 15 | ~CLinkedList(); 16 | 17 | T &GetData() { return m_data; } 18 | const T &GetData() const { return m_data; } 19 | void SetData(const T &data) { m_data = data; } 20 | 21 | CLinkedList *GetNext() const { return m_pNext; } 22 | void SetNext(CLinkedList *pNode) { m_pNext = pNode; } 23 | 24 | template 25 | void InsertOrdered(const T &data) 26 | { 27 | Compare comp; 28 | if(!m_pNext) 29 | m_pNext = new CLinkedList(data); 30 | else 31 | { 32 | CLinkedList *pNext = this; 33 | while(NULL != pNext->GetNext() && comp(pNext->GetNext()->GetData(), data)) 34 | pNext = pNext->GetNext(); 35 | pNext->SetNext(new CLinkedList(data, pNext->GetNext())); 36 | } 37 | } 38 | 39 | template 40 | void InsertOrdered(CLinkedList *pEntry) 41 | { 42 | Compare comp; 43 | if(!m_pNext) 44 | { 45 | m_pNext = pEntry; 46 | pEntry->SetNext(NULL); 47 | } 48 | else 49 | { 50 | CLinkedList *pNext = this; 51 | while(NULL != pNext->GetNext() && comp(pNext->GetNext()->GetData(), pEntry->GetData())) 52 | pNext = pNext->GetNext(); 53 | pEntry->SetNext(pNext->GetNext()); 54 | pNext->SetNext(pEntry); 55 | } 56 | } 57 | 58 | template 59 | void ReOrder(CLinkedList *pNode) 60 | { 61 | Compare comp; 62 | CLinkedList *pCurNode = this; 63 | while(pCurNode->GetNext() && pCurNode->GetNext() != pNode && comp(pCurNode->GetNext()->GetData(), pNode->GetData())) 64 | { 65 | pCurNode = pCurNode->GetNext(); 66 | } 67 | 68 | if(pCurNode->GetNext() == pNode) 69 | { 70 | pCurNode->SetNext(pNode->GetNext()); 71 | while(pCurNode->GetNext() && comp(pCurNode->GetNext()->GetData(), pNode->GetData())) 72 | { 73 | pCurNode = pCurNode->GetNext(); 74 | } 75 | 76 | pNode->SetNext(pCurNode->GetNext()); 77 | pCurNode->SetNext(pNode); 78 | } 79 | else if(comp(pCurNode->GetNext()->GetData(), pNode->GetData())) 80 | { 81 | CLinkedList *pNext = pNode->GetNext(); 82 | pNode->SetNext(pCurNode->GetNext()); 83 | pCurNode->SetNext(pNode); 84 | pCurNode = pNode; 85 | 86 | while(pCurNode->GetNext() != pNode) 87 | { 88 | pCurNode = pCurNode->GetNext(); 89 | } 90 | 91 | pCurNode->SetNext(pNext); 92 | } 93 | else 94 | { 95 | throw "Not in list!!"; 96 | } 97 | } 98 | }; 99 | 100 | template 101 | CLinkedList::CLinkedList(const T &data, CLinkedList *pNext /* = NULL */) 102 | : m_data(data), m_pNext(pNext) 103 | { 104 | } 105 | 106 | template 107 | CLinkedList::~CLinkedList() 108 | { 109 | } 110 | -------------------------------------------------------------------------------- /main/Core/Lock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | class CLock 7 | { 8 | public: 9 | CLock(HANDLE gh) 10 | : m_ghSemaphore(gh) 11 | { 12 | while(WAIT_OBJECT_0 != WaitForSingleObject(m_ghSemaphore, 0)); 13 | } 14 | 15 | ~CLock() 16 | { 17 | if(!ReleaseSemaphore(m_ghSemaphore, 1, 0)) 18 | { 19 | DWORD dwErr = GetLastError(); 20 | std::cerr << dwErr << std::endl; 21 | } 22 | } 23 | 24 | protected: 25 | HANDLE m_ghSemaphore; 26 | }; 27 | -------------------------------------------------------------------------------- /main/Core/LockFreeCircularQueue.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | template 6 | class CLockFreeCircularQueue 7 | { 8 | public: 9 | CLockFreeCircularQueue(size_t capacity); 10 | ~CLockFreeCircularQueue(); 11 | 12 | bool push_back_unsafe(T val); 13 | bool pop_front_unsafe(T &popped); 14 | 15 | bool push_back(T val); 16 | bool pop_front(T &popped); 17 | bool is_empty() const; 18 | 19 | protected: 20 | T *m_queue; 21 | size_t m_capacity; 22 | std::atomic m_front; 23 | std::atomic m_backSubmitted; 24 | std::atomic m_backFree; 25 | }; 26 | 27 | template 28 | CLockFreeCircularQueue::CLockFreeCircularQueue(size_t capacity) 29 | : m_queue(new T[capacity]) 30 | , m_capacity(capacity) 31 | , m_front(0) 32 | , m_backSubmitted(0) 33 | , m_backFree(0) 34 | { 35 | } 36 | 37 | template 38 | CLockFreeCircularQueue::~CLockFreeCircularQueue() 39 | { 40 | delete[] m_queue; 41 | } 42 | 43 | template 44 | bool CLockFreeCircularQueue::push_back_unsafe(T val) 45 | { 46 | size_t nextFree = (m_backFree + 1) % m_capacity; 47 | 48 | if(nextFree == m_front) 49 | return false; // Full 50 | 51 | assert(m_backSubmitted == m_backFree); 52 | m_queue[m_backFree] = val; 53 | m_backFree = nextFree; 54 | m_backSubmitted = m_backFree; 55 | return true; 56 | } 57 | 58 | template 59 | bool CLockFreeCircularQueue::pop_front_unsafe(T &popped) 60 | { 61 | if(m_front == m_backSubmitted) 62 | return false; // Empty 63 | 64 | popped = m_queue[m_front++]; 65 | m_front %= m_capacity; 66 | return true; 67 | } 68 | 69 | template 70 | bool CLockFreeCircularQueue::push_back(T val) 71 | { 72 | size_t currentReadIndex; 73 | size_t currentWriteIndex; 74 | 75 | do 76 | { 77 | currentWriteIndex = m_backFree; 78 | currentReadIndex = m_front; 79 | if (currentWriteIndex - currentReadIndex == m_capacity) 80 | return false; // Full 81 | } while (!m_backFree.compare_exchange_weak(currentWriteIndex, currentWriteIndex + 1)); 82 | 83 | // We know now that this index is reserved for us. Use it to save the data 84 | m_queue[currentWriteIndex % m_capacity] = val; 85 | 86 | // update the maximum read index after saving the data. It wouldn't fail if there is only one thread 87 | // inserting in the queue. It might fail if there are more than 1 producer threads because this 88 | // operation has to be done in the same order as the previous CAS 89 | 90 | size_t tempIndex = currentWriteIndex; 91 | while (!m_backSubmitted.compare_exchange_weak(tempIndex, tempIndex + 1)) 92 | { 93 | // this is a good place to yield the thread in case there are more 94 | // software threads than hardware processors and you have more 95 | // than 1 producer thread 96 | // have a look at sched_yield (POSIX.1b) 97 | tempIndex = currentWriteIndex; 98 | Sleep(0); 99 | } 100 | 101 | return true; 102 | } 103 | 104 | template 105 | bool CLockFreeCircularQueue::pop_front(T &popped) 106 | { 107 | size_t currentMaximumReadIndex; 108 | size_t currentReadIndex; 109 | 110 | do 111 | { 112 | // to ensure thread-safety when there is more than 1 producer thread 113 | // a second index is defined (m_backSubmitted) 114 | currentReadIndex = m_front; 115 | currentMaximumReadIndex = m_backSubmitted; 116 | 117 | if (currentReadIndex == currentMaximumReadIndex) 118 | return false; // Empty 119 | 120 | // retrieve the data from the queue 121 | popped = m_queue[currentReadIndex % m_capacity]; 122 | 123 | // try to perfrom now the CAS operation on the read index. If we succeed 124 | // a_data already contains what m_front pointed to before we 125 | // increased it 126 | if (m_front.compare_exchange_weak(currentReadIndex, currentReadIndex + 1)) 127 | return true; 128 | 129 | // it failed retrieving the element off the queue. Someone else must 130 | // have read the element stored at countToIndex(currentReadIndex) 131 | // before we could perform the CAS operation 132 | 133 | } while(1); // keep looping to try again! 134 | 135 | // Something went wrong. it shouldn't be possible to reach here 136 | assert(0); 137 | 138 | // Add this return statement to avoid compiler warnings 139 | return false; 140 | } 141 | 142 | template 143 | bool CLockFreeCircularQueue::is_empty() const 144 | { 145 | return countToIndex(m_front) == countToIndex(m_backSubmitted); 146 | } 147 | -------------------------------------------------------------------------------- /main/Core/LockFreeMemoryPool.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Core/LockFreeMemoryPool.h" 3 | 4 | #include 5 | 6 | #define INITIAL_QUEUE_CAPACITY 1000 7 | #define INITIAL_BLOCK_CAPACITY 1000 8 | 9 | CLockFreeMemoryPool::CLockFreeMemoryPool(size_t size) 10 | : m_queue(NULL) 11 | , m_size(size) 12 | , m_nextBlockIndex(0) 13 | , m_nextQueueIndex(0) 14 | { 15 | for(size_t i=0; i < 32; i++) 16 | { 17 | m_arrBlocks[i] = NULL; 18 | m_arrQueues[i] = NULL; 19 | } 20 | ExtendStack(); 21 | AddBlock(); 22 | } 23 | 24 | CLockFreeMemoryPool::~CLockFreeMemoryPool() 25 | { 26 | for(size_t i=0; i < 32; i++) 27 | { 28 | delete[] m_arrBlocks[i]; 29 | delete m_arrQueues[i]; 30 | } 31 | } 32 | 33 | void CLockFreeMemoryPool::ExtendStack() 34 | { 35 | size_t nextQueueIndex = m_nextQueueIndex; 36 | if(!m_nextQueueIndex.compare_exchange_strong(nextQueueIndex, nextQueueIndex + 1)) 37 | { 38 | while(m_queue != m_arrQueues[m_nextQueueIndex - 1]) 39 | Sleep(1); 40 | 41 | return; 42 | } 43 | 44 | CLockFreeCircularQueue *newQueue = new CLockFreeCircularQueue(INITIAL_QUEUE_CAPACITY * (1 << nextQueueIndex)); 45 | m_arrQueues[nextQueueIndex] = newQueue; 46 | 47 | CLockFreeCircularQueue *queue; 48 | do 49 | { 50 | nextQueueIndex = m_nextQueueIndex - 1; 51 | queue = m_arrQueues[nextQueueIndex]; 52 | } while (nextQueueIndex != m_nextQueueIndex - 1); 53 | 54 | if(queue) 55 | { 56 | m_queue = queue; 57 | 58 | void *p; 59 | for(size_t i=0; i < nextQueueIndex; i++) 60 | { 61 | if(!m_arrQueues[i]) 62 | continue; 63 | 64 | while(m_arrQueues[i]->pop_front(p)) 65 | { 66 | while(!m_queue->push_back(p)) 67 | { 68 | ExtendStack(); 69 | } 70 | } 71 | } 72 | } 73 | } 74 | 75 | void CLockFreeMemoryPool::AddBlock() 76 | { 77 | size_t nextBlockIndex = m_nextBlockIndex; 78 | if(!m_nextBlockIndex.compare_exchange_strong(nextBlockIndex, nextBlockIndex + 1)) 79 | { 80 | while(0 == m_arrBlocks[m_nextBlockIndex - 1]) 81 | Sleep(1); 82 | 83 | return; 84 | } 85 | 86 | size_t capacity = INITIAL_BLOCK_CAPACITY * (1 << nextBlockIndex); 87 | char *block = new char[m_size * capacity]; 88 | 89 | char *p = block; 90 | for(size_t i=0; i < capacity; i++) 91 | { 92 | while(!m_queue->push_back(p)) 93 | ExtendStack(); 94 | 95 | p += m_size; 96 | } 97 | 98 | m_arrBlocks[nextBlockIndex] = block; 99 | } 100 | -------------------------------------------------------------------------------- /main/Core/LockFreeMemoryPool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "LockFreeCircularQueue.h" 6 | #include "Hashtable.h" 7 | 8 | class CLockFreeMemoryPool 9 | { 10 | public: 11 | CLockFreeMemoryPool(size_t size); 12 | ~CLockFreeMemoryPool(); 13 | 14 | inline void *Alloc(); 15 | inline void Free(void *p); 16 | 17 | protected: 18 | void AddBlock(); 19 | void ExtendStack(); 20 | 21 | CLockFreeCircularQueue *m_queue; 22 | 23 | size_t m_size; 24 | std::atomic m_nextBlockIndex; 25 | char *m_arrBlocks[32]; // Enough room for allocation up to (2^32) * initial size 26 | std::atomic m_nextQueueIndex; 27 | CLockFreeCircularQueue *m_arrQueues[32]; 28 | }; 29 | 30 | void *CLockFreeMemoryPool::Alloc() 31 | { 32 | void *p; 33 | while(!m_queue->pop_front(p)) 34 | { 35 | AddBlock(); 36 | } 37 | 38 | return p; 39 | } 40 | 41 | void CLockFreeMemoryPool::Free(void *p) 42 | { 43 | while(!m_queue->push_back(p)) 44 | { 45 | ExtendStack(); 46 | } 47 | } 48 | 49 | template 50 | class CLockFreeMemoryPoolFixedSize 51 | { 52 | public: 53 | static CLockFreeMemoryPool m_pool; 54 | }; 55 | 56 | template 57 | CLockFreeMemoryPool CLockFreeMemoryPoolFixedSize::m_pool(size); 58 | 59 | template 60 | class CLFMemPoolNode 61 | { 62 | public: 63 | void *operator new(size_t) 64 | { 65 | return m_pool.Alloc(); 66 | } 67 | 68 | void operator delete(void *p) 69 | { 70 | if(p) 71 | m_pool.Free(p); 72 | } 73 | 74 | void *operator new[](size_t size) 75 | { 76 | //return GetMemoryPool(size * sizeof(T))->Alloc(); 77 | return NULL; 78 | } 79 | 80 | void operator delete[](void *p) 81 | { 82 | // Hmm... 83 | } 84 | 85 | static const CLockFreeMemoryPool &GetMemoryPool() { return m_pool; } 86 | 87 | private: 88 | static CLockFreeMemoryPool &m_pool; 89 | }; 90 | 91 | template CLockFreeMemoryPool &CLFMemPoolNode::m_pool = CLockFreeMemoryPoolFixedSize::m_pool; 92 | 93 | -------------------------------------------------------------------------------- /main/Core/MemoryPool.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Core/MemoryPool.h" 3 | #include "Core/MemoryPoolManager.h" 4 | 5 | #include 6 | 7 | size_t CMemoryPool::m_nUsedMemory(0); 8 | 9 | CMemoryPool::CMemoryPool(float fGrowFactor /* = 2.0 */, float fGrowAdditional /* = 0.0 */) 10 | : m_parrFree(NULL) 11 | , m_pEndFree(NULL) 12 | , m_pEndStack(NULL) 13 | , m_nSize(0) 14 | , m_nAllocatedCount(0) 15 | , m_nStackCapacity(0) 16 | , m_nLastBlockSize(0) 17 | , m_nLastStackIncrease(0) 18 | , m_fGrowFactor(fGrowFactor) 19 | , m_fGrowAdditional(fGrowAdditional) 20 | { 21 | } 22 | 23 | CMemoryPool::CMemoryPool(size_t nSize, size_t nInitialCapacity /* = MEMORYPOOL_INITIALCAPACITY */, float fGrowFactor /* = 2.0 */, float fGrowAdditional /* = 0.0 */) 24 | : m_parrFree(NULL) 25 | , m_pEndFree(NULL) 26 | , m_pEndStack(NULL) 27 | , m_nSize(0) 28 | , m_nAllocatedCount(0) 29 | , m_nStackCapacity(0) 30 | , m_nLastBlockSize(0) 31 | , m_nLastStackIncrease(0) 32 | , m_fGrowFactor(fGrowFactor) 33 | , m_fGrowAdditional(fGrowAdditional) 34 | { 35 | Initialise(nSize, nInitialCapacity); 36 | } 37 | 38 | void CMemoryPool::Initialise(size_t nSize, size_t nInitialCapacity /* = MEMORYPOOL_INITIALCAPACITY */) 39 | { 40 | m_nSize = nSize; 41 | ExtendStack(nInitialCapacity); 42 | AddBlock(nInitialCapacity); 43 | } 44 | 45 | CMemoryPool::~CMemoryPool() 46 | { 47 | delete[] m_parrFree; 48 | while(m_vecBlocks.size()) 49 | { 50 | delete[] m_vecBlocks.back(); 51 | m_vecBlocks.pop_back(); 52 | } 53 | 54 | for(ArrayBlockMap::iterator iter = m_mapArrayBlocks.begin(); iter != m_mapArrayBlocks.end(); ++iter) 55 | delete[] iter->second; 56 | } 57 | 58 | void CMemoryPool::ExtendStack(size_t nCapacity) 59 | { 60 | void **pArray, **pEnd; 61 | 62 | m_nStackCapacity += nCapacity; 63 | pArray = new void*[m_nStackCapacity]; 64 | pEnd = pArray - 1; 65 | 66 | if(m_parrFree) 67 | { 68 | size_t nExistingCount = (m_pEndFree - m_parrFree) + 1; 69 | if(nExistingCount) 70 | { 71 | memcpy(pArray, m_parrFree, nExistingCount * sizeof(void *)); 72 | pEnd += nExistingCount; 73 | } 74 | 75 | delete[] m_parrFree; 76 | } 77 | 78 | m_pEndStack = pArray + m_nStackCapacity - 1; 79 | m_pEndFree = pEnd; 80 | m_parrFree = pArray; 81 | m_nLastStackIncrease = nCapacity; 82 | m_nUsedMemory += nCapacity * sizeof(void *); 83 | } 84 | 85 | void CMemoryPool::AddBlock(size_t nCapacity) 86 | { 87 | size_t nBlockSize = m_nSize * nCapacity; 88 | m_nUsedMemory += nBlockSize; 89 | char *pBlock = new char[nBlockSize]; 90 | m_vecBlocks.push_back(pBlock); 91 | m_nLastBlockSize = nCapacity; 92 | m_nAllocatedCount += nCapacity; 93 | 94 | for(; nCapacity > 0; nCapacity--) 95 | { 96 | AppendToFreeStack(pBlock); 97 | pBlock += m_nSize; 98 | } 99 | } 100 | 101 | void *CMemoryPool::AllocArray(size_t size) 102 | { 103 | ArrayBlockMap::iterator iter = m_mapArrayBlocks.begin(); 104 | while(iter != m_mapArrayBlocks.end()) 105 | { 106 | if(!iter->second->bUsed && iter->second->size >= size) 107 | break; 108 | ++iter; 109 | } 110 | 111 | CArrayBlock *pBlock; 112 | if(iter != m_mapArrayBlocks.end()) 113 | pBlock = iter->second; 114 | else 115 | { 116 | pBlock = (CArrayBlock *)new char[sizeof(CArrayBlock) + size]; 117 | pBlock->size = size; 118 | m_mapArrayBlocks[pBlock] = pBlock; 119 | } 120 | 121 | pBlock->bUsed = true; 122 | return (void *)(((char *)pBlock) + sizeof(CArrayBlock)); 123 | } 124 | 125 | void CMemoryPool::FreeArray(void *p) 126 | { 127 | CArrayBlock *pBlock = (CArrayBlock *)(((char *)p) - sizeof(CArrayBlock)); 128 | m_mapArrayBlocks[pBlock]->bUsed = false; 129 | } 130 | 131 | CMemPoolNodePoolManager *CMemPoolNodePoolManager::m_singleton = NULL; 132 | 133 | void CMemPoolNodePoolManager::InitialiseThread() 134 | { 135 | CLock lock(m_semaphore); 136 | 137 | map poolMap; 138 | 139 | for(map::iterator iter = m_poolFunctions.begin(); iter != m_poolFunctions.end(); ++iter) 140 | { 141 | if((*iter->first)() != NULL) 142 | continue; 143 | 144 | map::iterator iterPool = poolMap.find(iter->second); 145 | CMemoryPool *pool; 146 | if(poolMap.end() == iterPool) 147 | { 148 | pool = CMemoryPoolManager::Get()->GetMemoryPoolAddAsNeeded(iter->second); 149 | m_allPools.push_back(pool); 150 | poolMap[iter->second] = pool; 151 | } 152 | else 153 | pool = iterPool->second; 154 | 155 | (*iter->first)() = pool; 156 | } 157 | } 158 | 159 | CMemPoolNodePoolManager::~CMemPoolNodePoolManager() 160 | { 161 | for(vector::iterator iter = m_allPools.begin(); iter != m_allPools.end(); ++iter) 162 | delete *iter; 163 | } 164 | -------------------------------------------------------------------------------- /main/Core/MemoryPool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "Lock.h" 7 | 8 | using namespace std; 9 | 10 | #define MEMORYPOOL_INITIALMEMORYUSAGE 10000 11 | #define MEMORYPOOL_MINIMUMCAPACITY 10 12 | 13 | class CMemoryPool 14 | { 15 | public: 16 | CMemoryPool(float fGrowFactor = 2.0, float fGrowAdditional = 0.0); 17 | CMemoryPool(size_t nSize, size_t nInitialCapacity, float fGrowFactor = 2.0, float fGrowAdditional = 0.0); 18 | ~CMemoryPool(); 19 | 20 | void Initialise(size_t nSize, size_t nInitialCapacity); 21 | 22 | inline void *Alloc(); 23 | inline void Free(void *p); 24 | 25 | void *AllocArray(size_t size); 26 | void FreeArray(void *p); 27 | 28 | size_t GetSize() const { return m_nSize; } 29 | size_t GetStackCapacity() const { return m_nStackCapacity; } 30 | size_t GetAllocated() const { return m_nAllocatedCount; } 31 | size_t GetCurrentlyUsed() const { return m_nAllocatedCount - (m_pEndFree - m_parrFree); } 32 | 33 | static size_t GetUsedMemory() { return m_nUsedMemory; } 34 | 35 | protected: 36 | class CArrayBlock 37 | { 38 | public: 39 | struct Less 40 | { 41 | bool operator()(const CArrayBlock* p1, const CArrayBlock* p2) const 42 | { 43 | return p1->size < p2->size; 44 | } 45 | }; 46 | size_t size; 47 | bool bUsed; 48 | }; 49 | 50 | void AddBlock(size_t nCapacity); 51 | void ExtendStack(size_t nCapacity); 52 | 53 | inline void AppendToFreeStack(void *p); 54 | 55 | size_t m_nSize; 56 | size_t m_nAllocatedCount; 57 | size_t m_nStackCapacity; 58 | size_t m_nLastBlockSize; 59 | size_t m_nLastStackIncrease; 60 | float m_fGrowFactor; 61 | float m_fGrowAdditional; 62 | 63 | void **m_parrFree; 64 | void **m_pEndFree; 65 | void **m_pEndStack; 66 | 67 | vector m_vecBlocks; 68 | typedef map ArrayBlockMap; 69 | ArrayBlockMap m_mapArrayBlocks; 70 | 71 | static size_t m_nUsedMemory; 72 | }; 73 | 74 | void *CMemoryPool::Alloc() 75 | { 76 | if(m_parrFree > m_pEndFree) 77 | AddBlock((size_t)(((float)m_nLastBlockSize) * m_fGrowFactor + m_fGrowAdditional)); 78 | 79 | return (*(m_pEndFree--)); 80 | } 81 | 82 | void CMemoryPool::Free(void *p) 83 | { 84 | AppendToFreeStack(p); 85 | } 86 | 87 | void CMemoryPool::AppendToFreeStack(void *p) 88 | { 89 | if(m_pEndFree == m_pEndStack) 90 | ExtendStack((size_t)(((float)m_nLastStackIncrease) * m_fGrowFactor + m_fGrowAdditional)); 91 | 92 | (*(++m_pEndFree)) = p; 93 | } 94 | 95 | class CMemPoolNodePoolManager 96 | { 97 | public: 98 | CMemPoolNodePoolManager() { m_semaphore = CreateSemaphore(0, 1, 1, 0); } 99 | ~CMemPoolNodePoolManager(); 100 | 101 | static CMemPoolNodePoolManager *Get() { if(!m_singleton) m_singleton = new CMemPoolNodePoolManager(); return m_singleton; } 102 | 103 | void InitialiseThread(); 104 | void AddPoolFunction(CMemoryPool *&(*func)(), size_t size) { CLock lock(m_semaphore); m_poolFunctions[func] = size; } 105 | 106 | template 107 | class CAutoAddFunction 108 | { 109 | public: 110 | CAutoAddFunction() 111 | { 112 | CMemPoolNodePoolManager::Get()->AddPoolFunction(CMemPoolNode::GetMemoryPool, sizeof(T)); 113 | } 114 | }; 115 | 116 | protected: 117 | static CMemPoolNodePoolManager *m_singleton; 118 | 119 | HANDLE m_semaphore; 120 | map m_poolFunctions; 121 | vector m_allPools; 122 | }; 123 | 124 | template 125 | class CMemPoolNode 126 | { 127 | public: 128 | CMemPoolNode() 129 | { 130 | HasAutoAdd(); 131 | } 132 | 133 | void *operator new(size_t) 134 | { 135 | return m_pool->Alloc(); 136 | } 137 | 138 | void operator delete(void *p) 139 | { 140 | if(p) 141 | m_pool->Free(p); 142 | } 143 | 144 | void *operator new[](size_t size) 145 | { 146 | return m_pool->AllocArray(size); 147 | } 148 | 149 | void operator delete[](void *p) 150 | { 151 | if(p) 152 | m_pool->FreeArray(p); 153 | } 154 | 155 | static bool HasMemoryPool() { return m_pool == NULL; } 156 | static CMemoryPool *&GetMemoryPool() { return m_pool; } 157 | static bool SetMemoryPool(CMemoryPool *pool) { if(m_pool) return false; m_pool = pool; return true; } 158 | static bool HasAutoAdd() { return m_autoAddFunction != NULL; } 159 | 160 | private: 161 | __declspec(thread) static CMemoryPool *m_pool; 162 | static CMemPoolNodePoolManager::CAutoAddFunction *m_autoAddFunction; 163 | }; 164 | 165 | template CMemoryPool *CMemPoolNode::m_pool = NULL; 166 | template CMemPoolNodePoolManager::CAutoAddFunction *CMemPoolNode::m_autoAddFunction = new CMemPoolNodePoolManager::CAutoAddFunction(); 167 | -------------------------------------------------------------------------------- /main/Core/MemoryPoolManager.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Core/MemoryPoolManager.h" 3 | 4 | CMemoryPoolManager::CMemoryPoolManager() 5 | { 6 | } 7 | 8 | CMemoryPoolManager::~CMemoryPoolManager() 9 | { 10 | for(CMemoryPoolMap::iterator iter = m_mapPools.begin(); iter != m_mapPools.end(); ++iter) 11 | { 12 | delete iter->second; 13 | } 14 | } 15 | 16 | CMemoryPoolManager *CMemoryPoolManager::m_singleton = NULL; -------------------------------------------------------------------------------- /main/Core/MemoryPoolManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "Core/MemoryPool.h" 5 | 6 | using namespace std; 7 | 8 | class CMemoryPoolManager 9 | { 10 | public: 11 | CMemoryPoolManager(); 12 | ~CMemoryPoolManager(); 13 | 14 | void AddMemoryPool(size_t size) 15 | { 16 | size_t initialCapacity = MEMORYPOOL_INITIALMEMORYUSAGE / size; 17 | if(initialCapacity < MEMORYPOOL_MINIMUMCAPACITY) 18 | initialCapacity = MEMORYPOOL_MINIMUMCAPACITY; 19 | 20 | AddMemoryPool(size, initialCapacity); 21 | } 22 | void AddMemoryPool(size_t size, size_t initialCapacity) 23 | { 24 | if(m_mapPools.find(size) == m_mapPools.end()) 25 | m_mapPools[size] = new CMemoryPool(size, initialCapacity); 26 | } 27 | 28 | CMemoryPool *GetMemoryPool(size_t size) { return m_mapPools[size]; } 29 | 30 | CMemoryPool *GetMemoryPoolAddAsNeeded(size_t size) 31 | { 32 | size_t initialCapacity = MEMORYPOOL_INITIALMEMORYUSAGE / size; 33 | if(initialCapacity < MEMORYPOOL_MINIMUMCAPACITY) 34 | initialCapacity = MEMORYPOOL_MINIMUMCAPACITY; 35 | 36 | return GetMemoryPoolAddAsNeeded(size, initialCapacity); 37 | } 38 | 39 | CMemoryPool *GetMemoryPoolAddAsNeeded(size_t size, size_t initialCapacity) 40 | { 41 | CMemoryPoolMap::iterator iter = m_mapPools.find(size); 42 | if(iter == m_mapPools.end()) 43 | { 44 | CMemoryPool *pool = new CMemoryPool(size, initialCapacity); 45 | m_mapPools[size] = pool; 46 | return pool; 47 | } 48 | else 49 | return iter->second; 50 | } 51 | 52 | static void InitialiseSingleton() { if(NULL == m_singleton) m_singleton = new CMemoryPoolManager(); } 53 | static CMemoryPoolManager *Get() { return m_singleton; } 54 | 55 | protected: 56 | typedef map CMemoryPoolMap; 57 | CMemoryPoolMap m_mapPools; 58 | 59 | __declspec(thread) static CMemoryPoolManager *m_singleton; 60 | }; 61 | -------------------------------------------------------------------------------- /main/Core/PriorityQueue.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core/Vector.h" 4 | #include "Core/Compare.h" 5 | 6 | template> 7 | class CPriorityQueue 8 | { 9 | public: 10 | CPriorityQueue() {} 11 | CPriorityQueue(const CPriorityQueue &queue) { m_vecQueue = queue.getQueue(); } 12 | ~CPriorityQueue() {} 13 | 14 | inline size_t size() const { return m_vecQueue.size(); } 15 | 16 | inline void add(const T &val); 17 | inline void clear() { m_vecQueue.truncate(0); } 18 | inline T pop(int index = 0); 19 | 20 | const CVector &getQueue() const { return m_vecQueue; } 21 | 22 | inline const T &operator[](size_t index) const { return m_vecQueue[index]; } 23 | inline T &operator[](size_t index) { return m_vecQueue[index]; } 24 | 25 | inline bool operator==(const CPriorityQueue &queue) const { return m_vecQueue == queue.getQueue(); } 26 | inline bool operator!=(const CPriorityQueue &queue) const { return m_vecQueue != queue.getQueue(); } 27 | 28 | inline void operator =(const CPriorityQueue &queue) { m_vecQueue = queue.getQueue(); } 29 | 30 | protected: 31 | CVector m_vecQueue; 32 | }; 33 | 34 | template 35 | void CPriorityQueue::add(const T &val) 36 | { 37 | m_vecQueue.push_back_uninitialised(1); 38 | 39 | // Sift up 40 | Compare comp; 41 | size_t index = m_vecQueue.size() - 1; 42 | while(index > 0) 43 | { 44 | size_t parentIndex = (index - 1) / 2; 45 | 46 | if(comp(m_vecQueue[parentIndex], val)) 47 | break; 48 | 49 | m_vecQueue[index] = m_vecQueue[parentIndex]; 50 | 51 | index = parentIndex; 52 | } 53 | m_vecQueue[index] = val; 54 | } 55 | 56 | template 57 | T CPriorityQueue::pop(int index /* = 0 */) 58 | { 59 | if(m_vecQueue.size() > 1) 60 | { 61 | Compare comp; 62 | 63 | T popped = m_vecQueue[index]; 64 | T val = m_vecQueue.pop(); 65 | 66 | if(index > 0 && comp(val, popped)) 67 | { 68 | // Sift up 69 | while(index > 0) 70 | { 71 | size_t parentIndex = (index - 1) / 2; 72 | 73 | if(comp(m_vecQueue[parentIndex], val)) 74 | break; 75 | 76 | m_vecQueue[index] = m_vecQueue[parentIndex]; 77 | 78 | index = parentIndex; 79 | } 80 | m_vecQueue[index] = val; 81 | } 82 | else 83 | { 84 | // Sift down 85 | size_t parentIndex = index; 86 | size_t childIndex = 2 * index + 1; 87 | while(childIndex < m_vecQueue.size()) 88 | { 89 | if(childIndex + 1 < m_vecQueue.size() && comp(m_vecQueue[childIndex + 1], m_vecQueue[childIndex])) 90 | childIndex++; 91 | 92 | if(!comp(m_vecQueue[childIndex], val)) 93 | break; 94 | 95 | m_vecQueue[parentIndex] = m_vecQueue[childIndex]; 96 | 97 | parentIndex = childIndex; 98 | childIndex = (childIndex * 2) + 1; 99 | } 100 | 101 | m_vecQueue[parentIndex] = val; 102 | } 103 | 104 | return popped; 105 | } 106 | else 107 | return m_vecQueue.pop(); 108 | } 109 | -------------------------------------------------------------------------------- /main/Core/ThreadPool.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Core/ThreadPool.h" 3 | #include "Core/Lock.h" 4 | 5 | CThreadPool m_threadPool; 6 | 7 | CThreadPool *CThreadPool::Get() 8 | { 9 | return &m_threadPool; 10 | } 11 | 12 | CThreadPool::CThreadPool() 13 | { 14 | m_semaphore = CreateSemaphore(NULL, 1, 1, NULL); 15 | } 16 | 17 | CThreadPool::~CThreadPool() 18 | { 19 | while(m_busyThreads.size() > 0) 20 | Sleep(200); // Just have to keep waiting for it 21 | 22 | while(m_availableThreads.size() > 0) 23 | { 24 | CThreadInfo *info = NULL; 25 | { 26 | CLock lock(m_semaphore); 27 | if(m_availableThreads.size() > 0) 28 | { 29 | info = m_availableThreads.pop(); 30 | info->m_Func = NULL; 31 | SetEvent(info->m_eventHandle); 32 | } 33 | } 34 | 35 | if(info) 36 | { 37 | WaitForSingleObject(info->m_threadHandle, INFINITE); 38 | CloseHandle(info->m_threadHandle); 39 | delete info; 40 | } 41 | } 42 | } 43 | 44 | HANDLE CThreadPool::StartThread(void (*Func)(void *), void *parameter) 45 | { 46 | CLock lock(m_semaphore); 47 | 48 | CThreadInfo *info; 49 | if(m_availableThreads.size() <= 0) 50 | { 51 | info = new CThreadInfo(); 52 | info->m_eventHandle = CreateEvent(NULL, FALSE, FALSE, NULL); 53 | info->m_threadHandle = CreateThread(NULL, 0, ThreadExecute, info, 0, NULL); 54 | SetThreadPriority(info->m_threadHandle, THREAD_PRIORITY_BELOW_NORMAL); 55 | } 56 | else 57 | { 58 | info = m_availableThreads.pop(); 59 | } 60 | 61 | info->m_dummyHandle = CreateSemaphore(NULL, 0, 1, NULL); // Calling code's responsibility to close it 62 | 63 | m_busyThreads.push_back(info); 64 | info->m_Func = Func; 65 | info->m_parameter = parameter; 66 | SetEvent(info->m_eventHandle); 67 | 68 | return info->m_dummyHandle; 69 | } 70 | 71 | void CThreadPool::SetAvailable(HANDLE threadHandle) 72 | { 73 | CLock lock(m_semaphore); 74 | 75 | CThreadInfo *info; 76 | 77 | for(size_t i=0; i < m_busyThreads.size(); i++) 78 | { 79 | if(m_busyThreads[i]->m_threadHandle == threadHandle) 80 | { 81 | info = m_busyThreads[i]; 82 | m_busyThreads.erase(i); 83 | break; 84 | } 85 | } 86 | 87 | m_availableThreads.push_back(info); 88 | } 89 | 90 | DWORD WINAPI CThreadPool::ThreadExecute(LPVOID input) 91 | { 92 | CMemoryPoolManager::InitialiseSingleton(); 93 | CMemPoolNodePoolManager::Get()->InitialiseThread(); 94 | 95 | CThreadInfo *info = (CThreadInfo *)input; 96 | 97 | while(true) 98 | { 99 | WaitForSingleObject(info->m_eventHandle, INFINITE); 100 | 101 | if(!info->m_Func) 102 | break; // ThreadPool being destroyed 103 | 104 | info->m_Func(info->m_parameter); 105 | 106 | ReleaseSemaphore(info->m_dummyHandle, 1, 0); 107 | 108 | CThreadPool::Get()->SetAvailable(info->m_threadHandle); 109 | } 110 | 111 | return 0; 112 | } 113 | -------------------------------------------------------------------------------- /main/Core/ThreadPool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Core/Vector.h" 4 | 5 | class CThreadPool 6 | { 7 | public: 8 | CThreadPool(); 9 | ~CThreadPool(); 10 | 11 | static CThreadPool *Get(); 12 | 13 | HANDLE StartThread(void (*Func)(void *), void *parameter); 14 | void SetAvailable(HANDLE handle); 15 | 16 | protected: 17 | class CThreadInfo 18 | { 19 | public: 20 | CThreadInfo() : m_threadHandle(0), m_eventHandle(0), m_Func(NULL), m_parameter(NULL), m_dummyHandle(NULL) {} 21 | ~CThreadInfo() {} 22 | 23 | HANDLE m_threadHandle; 24 | HANDLE m_eventHandle; 25 | HANDLE m_dummyHandle; 26 | void (*m_Func)(void *); 27 | void *m_parameter; 28 | }; 29 | 30 | HANDLE m_semaphore; 31 | CVector m_busyThreads; 32 | CVector m_availableThreads; 33 | 34 | static DWORD WINAPI ThreadExecute(LPVOID input); 35 | }; 36 | -------------------------------------------------------------------------------- /main/Core/Tokeniser.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Core/Tokeniser.h" 3 | 4 | void Tokenize(const string &str, 5 | vector &tokens, 6 | const string &delimiters /* = " " */) 7 | { 8 | // Skip delimiters at beginning. 9 | string::size_type lastPos = str.find_first_not_of(delimiters, 0); 10 | // Find first "non-delimiter". 11 | string::size_type pos = str.find_first_of(delimiters, lastPos); 12 | 13 | while (string::npos != pos || string::npos != lastPos) 14 | { 15 | // Found a token, add it to the vector. 16 | tokens.push_back(str.substr(lastPos, pos - lastPos)); 17 | // Skip delimiters. Note the "not_of" 18 | lastPos = str.find_first_not_of(delimiters, pos); 19 | // Find next "non-delimiter" 20 | pos = str.find_first_of(delimiters, lastPos); 21 | } 22 | } 23 | 24 | bool TokenizeCSV(const string& str, 25 | vector& tokens) 26 | { 27 | string::size_type index = 0; 28 | while(index < str.length()) 29 | { 30 | bool bQuotes = false; 31 | 32 | string strToken; 33 | 34 | if(str[index] == '\"') 35 | { 36 | bQuotes = true; 37 | index++; 38 | if(index >= str.length()) 39 | break; 40 | 41 | while(index < str.length()) 42 | { 43 | string::size_type endIndex = str.find('\"', index); 44 | if(-1 == endIndex) 45 | return false; // Malformed CSV 46 | 47 | strToken += str.substr(index, endIndex - index); 48 | index = endIndex + 1; 49 | if(index < str.length()) 50 | { 51 | char c = str[index]; 52 | index++; 53 | if(c == '\"') 54 | strToken += '\"'; 55 | else if(c == ',') 56 | break; 57 | else 58 | return false; // Malformed CSV 59 | } 60 | } 61 | } 62 | else 63 | { 64 | string::size_type endIndex = str.find(',', index); 65 | if(string::npos == endIndex) 66 | endIndex = str.length(); 67 | strToken = str.substr(index, endIndex - index); 68 | index = endIndex + 1; 69 | } 70 | 71 | tokens.push_back(strToken); 72 | } 73 | if(index == str.length()) // Ended with a comma, last token is empty 74 | tokens.push_back(""); 75 | 76 | return true; 77 | } 78 | -------------------------------------------------------------------------------- /main/Core/Tokeniser.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | void Tokenize(const string &str, 9 | vector &tokens, 10 | const string &delimiters = " "); 11 | 12 | bool TokenizeCSV(const string &str, 13 | vector &tokens); 14 | -------------------------------------------------------------------------------- /main/Core/Vector.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Core/Vector.h" 3 | 4 | template<> 5 | void initArray(bool *data, size_t from, size_t to) {} 6 | 7 | template<> 8 | void initArray(short *data, size_t from, size_t to) {} 9 | 10 | template<> 11 | void initArray(int *data, size_t from, size_t to) {} 12 | 13 | template<> 14 | void initArray(size_t *data, size_t from, size_t to) {} 15 | 16 | template<> 17 | void initArray(double *data, size_t from, size_t to) {} 18 | -------------------------------------------------------------------------------- /main/Details.txt: -------------------------------------------------------------------------------- 1 | Commands: 2 | Build Unit 3 | Build Building 4 | Research Tech 5 | Building Ability 6 | Unit Ability 7 | 8 | 9 | Command ID structure: 10 | 8 bits 11 | 8 bits 12 | 16 bits 13 | 14 | 15 | 16 | Events: 17 | Building Complete 18 | Unit Complete 19 | Research Complete 20 | 21 | 22 | Event ID structure: 23 | 8 bits 24 | 8 bits 25 | 16 bits 26 | -------------------------------------------------------------------------------- /main/GA/GAChromosomeFitness.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | class CGAChromosomeFitness 5 | { 6 | public: 7 | CGAChromosomeFitness(TChromosome *chromosome) : m_chromosome(chromosome), m_fitness() {} 8 | CGAChromosomeFitness(TChromosome *chromosome, const TFitness &fitness) : m_chromosome(chromosome), m_fitness(fitness) {} 9 | CGAChromosomeFitness(const CGAChromosomeFitness &chromosomeFitness) : m_chromosome(new TChromosome(chromosomeFitness.GetChromosome())), m_fitness(chromosomeFitness.GetFitness()) {} 10 | 11 | ~CGAChromosomeFitness() { delete m_chromosome; } 12 | 13 | const TChromosome *GetChromosome() const { return m_chromosome; } 14 | const TFitness &GetFitness() const { return m_fitness; } 15 | 16 | TChromosome *GetChromosome() { return m_chromosome; } 17 | TFitness &GetFitness() { return m_fitness; } 18 | 19 | static int Compare(const void *p1, const void *p2) 20 | { 21 | const CGAChromosomeFitness *chromosome1 = *(const CGAChromosomeFitness **)(p1); 22 | const CGAChromosomeFitness *chromosome2 = *(const CGAChromosomeFitness **)(p2); 23 | if(!chromosome1) 24 | return 1; 25 | else if(!chromosome2) 26 | return -1; 27 | // else if(chromosome2->GetFitness() < chromosome1->GetFitness()) 28 | // return -1; 29 | // else if(chromosome1->GetFitness() < chromosome2->GetFitness()) 30 | // return 1; 31 | else 32 | { 33 | int fitnessDiff = chromosome1->GetFitness().Compare(chromosome2->GetFitness()); 34 | 35 | if(fitnessDiff != 0) 36 | return -fitnessDiff; 37 | else 38 | return chromosome1->GetChromosome()->Compare(*chromosome2->GetChromosome()); 39 | } 40 | } 41 | 42 | protected: 43 | TChromosome *m_chromosome; 44 | TFitness m_fitness; 45 | }; 46 | -------------------------------------------------------------------------------- /main/GA/GAConfiguration.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "GAConfiguration.h" 3 | 4 | #include 5 | 6 | -------------------------------------------------------------------------------- /main/GA/GAConfiguration.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | class CGAConfiguration 5 | { 6 | public: 7 | CGAConfiguration(const TMutator &mutator, const TFitnessCalc &fitnessCalc); 8 | 9 | bool Mutate(TChromosome &chromosome) const { return m_mutator.Mutate(chromosome); } 10 | void InitRandomChromosome(TChromosome &chromosome) const { return m_mutator.InitRandomChromosome(chromosome); } 11 | 12 | bool ValidateAndCalculateFitness(TChromosome &chromosome, TFitness &fitness) const; 13 | bool SatisfiesTarget(const TChromosome &chromosome) const { return m_fitnessCalc.SatisfiesTarget(chromosome); } 14 | 15 | protected: 16 | const TMutator &m_mutator; 17 | const TFitnessCalc &m_fitnessCalc; 18 | }; 19 | 20 | template 21 | CGAConfiguration::CGAConfiguration(const TMutator &mutator, const TFitnessCalc &fitnessCalc) 22 | : m_mutator(mutator), m_fitnessCalc(fitnessCalc) 23 | { 24 | } 25 | 26 | template 27 | bool CGAConfiguration::ValidateAndCalculateFitness(TChromosome &chromosome, TFitness &fitness) const 28 | { 29 | if(!m_fitnessCalc.ValidateAndCalculateFitness(chromosome, fitness)) 30 | return false; 31 | 32 | return true; 33 | } 34 | -------------------------------------------------------------------------------- /main/GA/GANNChromosome.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../NN/NNInput.h" 4 | #include "../NN/NNNode.h" 5 | #include "../NN/NNSynapse.h" 6 | #include "../NN/NNStepTransform.h" 7 | #include "../NN/NNDirectTransform.h" 8 | #include "../NN/NNSigmoidTransform.h" 9 | 10 | #include "../Core/Vector.h" 11 | #include "../Core/Hashtable.h" 12 | 13 | class CGANNChromosome : public CMemPoolNode 14 | { 15 | public: 16 | CGANNChromosome() {} 17 | CGANNChromosome(const CGANNChromosome &chromosome) { *this = chromosome; } 18 | ~CGANNChromosome() { RemoveAllPointer(m_nodes); RemoveAllPointer(m_outputs); } 19 | 20 | CGANNChromosome *Clone() const { return new CGANNChromosome(*this); } 21 | 22 | CGANNChromosome *Breed(const CGANNChromosome *spouse, short crossover) const; 23 | 24 | void operator=(const CGANNChromosome &chromosome); 25 | bool operator==(const CGANNChromosome &chromosome) const { return false; } 26 | int Compare(const CGANNChromosome &chromosome) const; 27 | 28 | class CNode : public CMemPoolNode 29 | { 30 | public: 31 | CNode() : m_inputWeights(), m_nodeWeights(), m_transform(NULL), m_summationFunction(NULL) {} 32 | CNode(const CNode &node); 33 | CNode(const CNode &node, const CVector &nodeMappings); 34 | ~CNode() { delete m_transform; } 35 | 36 | CVector m_inputWeights; 37 | CVector m_nodeWeights; 38 | CNNNode::SummationFunction m_summationFunction; 39 | CNNTransform *m_transform; 40 | }; 41 | 42 | void BuildRequiredNodes(CNode *node, size_t maxNodeIndex, CVector &requiredNodes) const; 43 | 44 | CVector m_nodes; 45 | CVector m_outputs; 46 | }; 47 | 48 | class CGANNChromosomeMutator 49 | { 50 | public: 51 | CGANNChromosomeMutator(size_t inputCount, size_t outputCount, double minValue, double maxValue, double mutationRate, double minFactor, double maxFactor, double minAdjustment, double maxAdjustment); 52 | 53 | bool Mutate(CGANNChromosome &chromosome) const; 54 | 55 | void InitRandomChromosome(CGANNChromosome &chromosome) const; 56 | 57 | protected: 58 | size_t m_inputCount; 59 | size_t m_outputCount; 60 | 61 | bool ShouldMutate() const { return rand_sse() < m_mutationCutOff; } 62 | double GetFactor() const { return m_minFactor + (rand_sse() * (m_maxFactor - m_minFactor)) / RAND_MAX + (rand_sse() * (m_maxFactor - m_minFactor)) / (RAND_MAX * RAND_MAX); } 63 | double GetAdjustment() const { return m_minAdjustment + (rand_sse() * (m_maxAdjustment - m_minAdjustment)) / RAND_MAX + (rand_sse() * (m_maxAdjustment - m_minAdjustment)) / (RAND_MAX * RAND_MAX); } 64 | 65 | double m_minValue, m_maxValue; 66 | short m_mutationCutOff; 67 | double m_minFactor, m_maxFactor; 68 | double m_minAdjustment, m_maxAdjustment; 69 | }; 70 | -------------------------------------------------------------------------------- /main/GA/GAPopulation.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "GAPopulation.h" 3 | #include 4 | 5 | -------------------------------------------------------------------------------- /main/GA/GASequenceChromosome.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include "GASequenceChromosome.h" 7 | 8 | -------------------------------------------------------------------------------- /main/GA/GAStringFitnessCalc.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "GAStringFitnessCalc.h" 3 | 4 | bool CGAStringFitnessCalc::ValidateAndCalculateFitness(CGASequenceChromosome &chromosome, double &fitness) const 5 | { 6 | size_t i; 7 | for(i=0; i < m_target.size() && i < chromosome.GetValue().size(); i++) 8 | { 9 | if(m_target[i] != chromosome.GetValue()[i]) 10 | break; 11 | } 12 | 13 | fitness = 10 * (double)i / (10 + chromosome.GetValue().size() - i); 14 | 15 | return true; 16 | } 17 | 18 | bool CGAStringFitnessCalc::SatisfiesTarget(const CGASequenceChromosome &chromosome) const 19 | { 20 | if(m_target.size() != chromosome.GetValue().size()) 21 | return false; 22 | 23 | for(size_t i=0; i < m_target.size(); i++) 24 | { 25 | if(m_target[i] != chromosome.GetValue()[i]) 26 | return false; 27 | } 28 | 29 | return true; 30 | } 31 | -------------------------------------------------------------------------------- /main/GA/GAStringFitnessCalc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Core/Vector.h" 4 | 5 | #include "GASequenceChromosome.h" 6 | 7 | // Demonstrates FitnessCalc class for evaluating matches to a string (using sequence chromosomes) 8 | class CGAStringFitnessCalc 9 | { 10 | public: 11 | CGAStringFitnessCalc(CVector &target) : m_target(target) {} 12 | 13 | bool ValidateAndCalculateFitness(CGASequenceChromosome &chromosome, double &fitness) const; 14 | bool SatisfiesTarget(const CGASequenceChromosome &chromosome) const; 15 | 16 | protected: 17 | CVector m_target; 18 | }; 19 | -------------------------------------------------------------------------------- /main/GA/GAVillage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Core/Lock.h" 4 | 5 | #include "GAPopulation.h" 6 | 7 | template class TPopulationSort> 8 | class CGAVillage 9 | { 10 | public: 11 | CGAVillage(const CGAConfiguration &config, const size_t &stagnationLimit, size_t populationLimit, size_t initialPopulation, bool recalcEliteFitness); 12 | ~CGAVillage() { CloseHandle(m_semaphore); CloseHandle(m_threadHandle); } 13 | 14 | size_t populationCount() const { if(!m_population) return 0; return m_population->populationCount(); } 15 | size_t evolution() const { return m_evolution; } 16 | size_t stagnationCount() const { if(!m_population) return 0; return m_population->StagnationCount(); } 17 | unsigned long long gameCount() const { if(!m_population) return 0; return m_population->gameCount(); } 18 | 19 | TFitness bestFitness() const { CLock lock(m_semaphore); return m_bestFitness; } 20 | void bestValue(TChromosome &value) const { CLock lock(m_semaphore); if(!m_bestValue) return; value = *m_bestValue; } 21 | 22 | void Start(); 23 | void Stop() { m_bContinueRunning = false; } 24 | void WaitForCompletion() { if(!m_bRunning) return; WaitForSingleObject(m_threadHandle, INFINITE); } 25 | 26 | size_t getStagnationLimit() const { return m_stagnationLimit; } 27 | 28 | static void Execute(void *input) { ((CGAVillage *)input)->Execute(); } 29 | void Execute(); 30 | void Run(); // Only call from static member above 31 | 32 | protected: 33 | void Initialise() { m_evolution = 0; m_population->Initialise(m_initialPopulation); } 34 | 35 | const CGAConfiguration &m_config; 36 | CGAPopulation *m_population; 37 | const size_t &m_stagnationLimit; 38 | 39 | bool m_recalcEliteFitness; 40 | size_t m_populationLimit; 41 | size_t m_initialPopulation; 42 | 43 | HANDLE m_threadHandle; 44 | DWORD m_threadId; 45 | 46 | HANDLE m_semaphore; 47 | 48 | bool m_bRunning; 49 | bool m_bContinueRunning; 50 | 51 | size_t m_evolution; 52 | 53 | TChromosome *m_bestValue; 54 | TFitness m_bestFitness; 55 | }; 56 | 57 | template class TPopulationSort> 58 | CGAVillage::CGAVillage(const CGAConfiguration &config, const size_t &stagnationLimit, size_t populationLimit, size_t initialPopulation, bool recalcEliteFitness) 59 | : m_config(config), m_populationLimit(populationLimit), m_recalcEliteFitness(recalcEliteFitness), m_population(0), m_stagnationLimit(stagnationLimit), m_initialPopulation(initialPopulation), m_threadHandle(0), m_threadId(0), m_bRunning(false), m_bContinueRunning(true), m_evolution(0), m_bestValue(0), m_bestFitness() 60 | { 61 | m_semaphore = CreateSemaphore(0, 1, 1, 0); 62 | } 63 | 64 | template class TPopulationSort> 65 | void CGAVillage::Start() 66 | { 67 | if(m_bRunning) 68 | return; 69 | 70 | m_threadHandle = CThreadPool::Get()->StartThread(CGAVillage::Execute, this); 71 | } 72 | 73 | template class TPopulationSort> 74 | void CGAVillage::Execute() 75 | { 76 | m_bRunning = true; 77 | 78 | m_population = new CGAPopulation(m_config, m_populationLimit, m_populationLimit/8, m_recalcEliteFitness); 79 | 80 | Initialise(); 81 | 82 | srand_sse((unsigned int)m_threadHandle + GetTickCount()); 83 | 84 | for(m_evolution = 0; m_bContinueRunning; m_evolution++) 85 | { 86 | if(m_evolution % 100 == 0) 87 | { 88 | CLock lock(m_semaphore); 89 | delete m_bestValue; 90 | m_bestValue = new TChromosome(m_population->GetBestChromosome()); 91 | m_bestFitness = m_population->GetBestFitness(); 92 | } 93 | 94 | if(m_population->StagnationCount() > m_stagnationLimit) 95 | { 96 | m_population->Clear(); 97 | Initialise(); 98 | } 99 | 100 | m_population->Evolve(); 101 | } 102 | 103 | CLock lock(m_semaphore); 104 | delete m_bestValue; 105 | m_bestValue = 0; 106 | 107 | delete m_population; 108 | 109 | m_bRunning = false; 110 | } 111 | -------------------------------------------------------------------------------- /main/GridItem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class GridItem 6 | { 7 | 8 | public: 9 | enum GridItemType 10 | { 11 | tDefault, 12 | tBase, 13 | tSupply, 14 | tGas, 15 | tStatus, 16 | tMilitary, 17 | tMilitaryUnit, 18 | tWorker, 19 | tResearch, 20 | tMilestone 21 | }; 22 | 23 | enum GridItemLevel 24 | { 25 | lSimple, 26 | lDetailed, 27 | lFull 28 | }; 29 | 30 | GridItem(wxString name, double time, GridItemType itemType = tDefault, GridItemLevel level = lFull) 31 | { 32 | this->name = name; 33 | this->time = time; 34 | this->itemType = itemType; 35 | this->level = level; 36 | } 37 | 38 | wxString name; 39 | double time; 40 | GridItemType itemType; 41 | GridItemLevel level; 42 | 43 | int minerals; 44 | int gas; 45 | int larvae; 46 | double mineralIncomeRate; 47 | double gasIncomeRate; 48 | int supply; 49 | int workers; 50 | int supplyCap; 51 | 52 | wxString buildingsCompleted; 53 | wxString unitsCompleted; 54 | wxString researchCompleted; 55 | }; -------------------------------------------------------------------------------- /main/GridOutput.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "GridItem.h" 5 | 6 | using std::vector; 7 | 8 | class GridOutput : public wxGrid 9 | { 10 | public: 11 | GridOutput(wxWindow* parent, wxWindowID id, bool hasLarvae); 12 | 13 | void SetData(vector data); 14 | 15 | void SetLevel(int level); 16 | 17 | private: 18 | int m_level; 19 | vector m_data; 20 | wxMenu* m_menu; 21 | vector m_visible_cols { true, true, true, true, true, true, true, true, true }; 22 | vector m_disabled_cols { true, false, false, false, false, false, false, false, true }; 23 | 24 | void UpdateGrid(); 25 | void DrawRow(size_t i, GridItem item); 26 | void OnMenuItemClick(wxCommandEvent& evt); 27 | void OnRightClick(wxContextMenuEvent& evt); 28 | void SetGridColumns(); 29 | 30 | DECLARE_EVENT_TABLE() 31 | }; -------------------------------------------------------------------------------- /main/MDIChild.h: -------------------------------------------------------------------------------- 1 | #ifndef _MDICHILD_H_ 2 | #define _MDICHILD_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "GA/GAEngine.h" 12 | #include "SC2Engine.h" 13 | #include "TimeValidator.h" 14 | #include "ChartPanel.h" 15 | #include "GridOutput.h" 16 | 17 | //template 18 | class MyChild : public wxMDIChildFrame 19 | { 20 | public: 21 | MyChild(wxMDIParentFrame *parent, CSC2Engine *engine, const char * const *xpmIcon, wxString fileName = wxEmptyString); 22 | virtual ~MyChild(); 23 | 24 | bool LoadSettingsFromXML(wxXmlNode *node); 25 | bool LoadWaypointsFromXML(wxXmlNode *node); 26 | bool LoadBuildOrderFromXML(wxXmlNode *node); 27 | 28 | static unsigned GetChildrenCount() { return ms_numChildren; } 29 | 30 | bool DoSave(); 31 | bool DoSaveAs(); 32 | bool DoExportSVG(); 33 | 34 | const wxString &GetFileName() const { return m_fileName; } 35 | 36 | private: 37 | void InitToolBar(wxToolBar* toolBar); 38 | 39 | void OnAction(wxCommandEvent& event); 40 | void OnPropertyGridChange(wxPropertyGridEvent& event); 41 | void OnPropertyGridChanging(wxPropertyGridEvent& event); 42 | void OnNotebookPageChanged(wxNotebookEvent& event); 43 | void OnMaxTime(wxCommandEvent& event); 44 | void OnScoutingWorker(wxCommandEvent& event); 45 | void OnScoutingWorkerTime(wxCommandEvent& event); 46 | void OnScoutingWorkerDies(wxCommandEvent& event); 47 | void OnScoutingWorkerReturns(wxCommandEvent& event); 48 | void OnScoutingWorkerEndTime(wxCommandEvent& event); 49 | void OnMaxAPM(wxCommandEvent& event); 50 | void OnOutputURL(wxTextUrlEvent &event); 51 | void OnSave(wxCommandEvent& event); 52 | void OnSaveAs(wxCommandEvent& event); 53 | void OnExportSVG(wxCommandEvent& event); 54 | void OnPrintButtonClicked(wxCommandEvent& event); 55 | 56 | void AddWaypoint(wxCommandEvent & WXUNUSED(event)); 57 | void RemoveWaypoint(wxCommandEvent & WXUNUSED(event)); 58 | void Start(wxCommandEvent & WXUNUSED(event)); 59 | void UpdateOutputFormat(wxCommandEvent & WXUNUSED(event)); 60 | void UpdateOutputLevel(wxCommandEvent& WXUNUSED(event)); 61 | void UpdateInitialBuildOrder(wxCommandEvent & WXUNUSED(event)); 62 | 63 | void UpdateScoutingCheckboxes(); 64 | void UpdateOutputFormat(); 65 | void UpdateOutputLevel(); 66 | 67 | private: 68 | wxString m_fileName; 69 | 70 | wxNotebook* m_notebookTargets; 71 | wxPropertyGrid* m_pgTarget; 72 | wxPanel *m_panelTarget; 73 | CVector m_pgWaypoints; 74 | CVector m_panelWaypoints; 75 | wxPanel* m_panelSettings; 76 | wxPropertyGrid* m_pgResult; 77 | wxButton* m_btnAddWaypoint; 78 | wxButton* m_btnRemoveWaypoint; 79 | wxButton* m_btnStart; 80 | wxButton* m_btnExportSVG; 81 | wxButton* m_btnPrint; 82 | wxStaticText* m_staticCompletionLikelihood; 83 | wxTextCtrl* m_txtCompletionLikelihood; 84 | wxListCtrl* m_listVillages; 85 | wxStaticText* m_staticText1; 86 | wxChoice* m_choiceOutput; 87 | wxChoice* m_choiceLevel; 88 | wxTextCtrl* m_txtOutput; 89 | ChartPanel* m_visualOutput; 90 | GridOutput* m_gridOutput; 91 | wxTimer* m_timer; 92 | 93 | wxTextCtrl *m_txtMaxTime; 94 | wxCheckBox *m_chkScoutingWorker; 95 | wxTextCtrl *m_txtScoutingWorkerTime; 96 | wxCheckBox *m_chkScoutingWorkerDies; 97 | wxCheckBox *m_chkScoutingWorkerReturns; 98 | wxTextCtrl *m_txtScoutingWorkerEndTime; 99 | 100 | wxChoice *m_choiceGasMicro; 101 | wxCheckBox *m_chkAllowTimeWaiting; 102 | wxCheckBox *m_chkMaxAPM; 103 | wxTextCtrl *m_txtMaxAPM; 104 | wxChoice *m_choiceInitialBuildOrder; 105 | wxTextCtrl *m_txtInitialBuildOrder; 106 | 107 | double m_scoutingWorkerTime; 108 | double m_scoutingWorkerEndTime; 109 | 110 | bool m_modified; 111 | 112 | CSC2Engine *m_engine; 113 | 114 | CSC2Engine::CPropertiesSet m_setDoubleProperties; 115 | CSC2Engine::CPropertiesSet m_setTimeProperties; 116 | CSC2Engine::CPropertiesSet m_setSizeTMinMaxProperties; 117 | CSC2Engine::CPropertiesSet m_setBoolMinMaxProperties; 118 | CSC2Engine::CPropertiesSet m_setBoolProperties; 119 | 120 | unsigned m_buildOrderNumber; 121 | 122 | bool StartEngine(CSC2Engine::EScoutingWorker scout, int scoutTime, int scoutEndTime, double minimumCommandDuration); 123 | void StopEngine(); 124 | 125 | void RefreshOutput(); 126 | void PrintBestGame(); 127 | void DrawBestGame(); 128 | void GetBestGameGridData(); 129 | 130 | private: 131 | wxBoxSizer* m_gridOptionsSizer; 132 | wxBoxSizer* m_outputControlsSizer; 133 | 134 | void OnActivate(wxActivateEvent& event); 135 | 136 | void OnClose(wxCommandEvent& event); 137 | void OnSize(wxSizeEvent& event); 138 | void OnMove(wxMoveEvent& event); 139 | void OnCloseWindow(wxCloseEvent& event); 140 | 141 | #if wxUSE_CLIPBOARD 142 | void OnPaste(wxCommandEvent& event); 143 | void OnUpdatePaste(wxUpdateUIEvent& event); 144 | #endif // wxUSE_CLIPBOARD 145 | 146 | void OnTimer(wxTimerEvent& event); 147 | 148 | DWORD m_startTickCount; 149 | void UpdateListBoxEntry(int nItem, size_t population, size_t evolution, size_t stagnationCount, unsigned long long gameCount, double bestFitness, DWORD timeDiff); 150 | void UpdateRemoveButton(); 151 | bool UpdatePropertySummary(wxPGProperty *prop); 152 | bool InterpretProperty(wxPGProperty *prop); 153 | 154 | bool WriteToFile(wxString fileName); 155 | 156 | void AddWaypoint(); 157 | 158 | void SetModified(bool modified = true); 159 | void UpdateTitle(); 160 | 161 | static unsigned ms_numChildren; 162 | 163 | // simple test event handler class 164 | class EventHandler : public wxEvtHandler 165 | { 166 | public: 167 | EventHandler(unsigned numChild) : m_numChild(numChild) { } 168 | 169 | private: 170 | void OnRefresh(wxCommandEvent& event) 171 | { 172 | wxLogMessage("Child #%u refreshed.", m_numChild); 173 | event.Skip(); 174 | } 175 | 176 | const unsigned m_numChild; 177 | 178 | DECLARE_EVENT_TABLE() 179 | 180 | wxDECLARE_NO_COPY_CLASS(EventHandler); 181 | }; 182 | 183 | DECLARE_EVENT_TABLE() 184 | }; 185 | 186 | #endif // _MDICHILD_H_ 187 | -------------------------------------------------------------------------------- /main/MDIParent.h: -------------------------------------------------------------------------------- 1 | #ifndef _MDIPARENT_H_ 2 | #define _MDIPARENT_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "SC2/SC2Version.h" 8 | 9 | // Define a new frame 10 | class MyFrame : public wxMDIParentFrame 11 | { 12 | public: 13 | MyFrame(); 14 | virtual ~MyFrame(); 15 | 16 | static wxMenuBar *CreateMainMenubar(); 17 | 18 | private: 19 | void InitToolBar(wxToolBar* toolBar); 20 | 21 | void OnSize(wxSizeEvent& event); 22 | void OnAbout(wxCommandEvent& event); 23 | void OnReportIssue(wxCommandEvent& event); 24 | void OnNewWindow(wxCommandEvent& event); 25 | void OnNewProtoss(wxCommandEvent& event); 26 | void OnNewTerran(wxCommandEvent& event); 27 | void OnNewZerg(wxCommandEvent& event); 28 | void OnOpen(wxCommandEvent& event); 29 | void OnSave(wxCommandEvent& event); 30 | void OnSaveAs(wxCommandEvent& event); 31 | void OnFullScreen(wxCommandEvent& event); 32 | void OnQuit(wxCommandEvent& event); 33 | void OnCloseAll(wxCommandEvent& event); 34 | 35 | void OnClose(wxCloseEvent& event); 36 | 37 | void OnGameSelected(wxCommandEvent& event); 38 | void OnVersionSelected(wxCommandEvent& event); 39 | 40 | void OnCheckForUpdates(wxCommandEvent& event); 41 | 42 | DECLARE_EVENT_TABLE() 43 | 44 | void DoGameSelected(); 45 | void DoVersionSelected(); 46 | 47 | void LoadVersions(); 48 | 49 | typedef std::map wxVersionOrderedMap; 50 | WX_DECLARE_HASH_MAP(wxString, wxVersionOrderedMap *, wxStringHash, wxStringEqual, wxGameHashTable); 51 | 52 | wxGameHashTable m_gamesByShortDescription; 53 | wxGameHashTable m_gamesByLongDescription; 54 | 55 | CSC2Version *m_version; 56 | wxChoice *m_choiceGame; 57 | wxChoice *m_choiceVersion; 58 | }; 59 | 60 | #endif // _MDIPARENT_H_ 61 | -------------------------------------------------------------------------------- /main/MinMax.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define mymin(x, y) ((x) < (y) ? (x) : (y)) 4 | #define mymax(x, y) ((x) > (y) ? (x) : (y)) 5 | -------------------------------------------------------------------------------- /main/OutputPrintout.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | OutputPrintout::OutputPrintout(wxGrid* g, const wxString& title) 7 | : wxPrintout(title) { 8 | grid = g; 9 | } 10 | 11 | bool OutputPrintout::OnPrintPage(int page) 12 | { 13 | wxDC* dc = GetDC(); 14 | dc->SetFont(grid->GetFont()); 15 | 16 | int pageWidth, pageHeight; 17 | GetPageSizePixels(&pageWidth, &pageHeight); 18 | 19 | int gridWidth = 0; 20 | wxGridSizesInfo colSizes = grid->GetColSizes(); 21 | int gridColCount = grid->GetNumberCols(); 22 | for (int i = 0; i < gridColCount; i++) 23 | { 24 | gridWidth += colSizes.GetSize(i); 25 | } 26 | 27 | int gridHeight = grid->GetColLabelSize(); 28 | wxGridSizesInfo rowSizes = grid->GetRowSizes(); 29 | int gridRowCount = grid->GetNumberRows(); 30 | for (int i = 0; i < gridRowCount; i++) 31 | { 32 | gridHeight += rowSizes.GetSize(i); 33 | } 34 | 35 | float scale = 1; 36 | if (gridWidth > 0) scale = (float)pageWidth / (float)gridWidth; 37 | int gridViewHeight = 1200; 38 | if (scale > 0) gridViewHeight = (int)((float)pageHeight / scale); 39 | 40 | int startRow = 0; 41 | int endRow = 0; 42 | 43 | int pages = 0; 44 | int row = 0; 45 | while ((row < gridRowCount) && (pages <= page)) 46 | { 47 | pages++; 48 | if (pages == page) startRow = row; 49 | int viewHeight = grid->GetColLabelSize(); 50 | while ((row < gridRowCount) && (viewHeight + rowSizes.GetSize(row) < gridViewHeight)) 51 | { 52 | viewHeight += rowSizes.GetSize(row); 53 | row++; 54 | } 55 | if (pages == page) endRow = row - 1; 56 | } 57 | 58 | grid->Render(*dc, wxPoint(0, 0), wxDefaultSize, 59 | wxGridCellCoords(startRow, 0), wxGridCellCoords(endRow, gridColCount - 1)); 60 | 61 | return true; 62 | } 63 | 64 | bool OutputPrintout::HasPage(int page) 65 | { 66 | return (page <= GetPageCount()); 67 | } 68 | 69 | bool OutputPrintout::OnBeginDocument(int startPage, int endPage) 70 | { 71 | if (!wxPrintout::OnBeginDocument(startPage, endPage)) 72 | return false; 73 | return true; 74 | } 75 | 76 | int OutputPrintout::GetPageCount() 77 | { 78 | int pageWidth, pageHeight; 79 | GetPageSizePixels(&pageWidth, &pageHeight); 80 | 81 | int gridWidth = 0; 82 | wxGridSizesInfo colSizes = grid->GetColSizes(); 83 | int gridColCount = grid->GetNumberCols(); 84 | for (int i = 0; i < gridColCount; i++) 85 | { 86 | gridWidth += colSizes.GetSize(i); 87 | } 88 | 89 | int gridHeight = grid->GetColLabelSize(); 90 | wxGridSizesInfo rowSizes = grid->GetRowSizes(); 91 | int gridRowCount = grid->GetNumberRows(); 92 | for (int i = 0; i < gridRowCount; i++) 93 | { 94 | gridHeight += rowSizes.GetSize(i); 95 | } 96 | 97 | float scale = (float)pageWidth / (float)gridWidth; 98 | int gridViewHeight = (int)((float)pageHeight / scale); 99 | 100 | int pages = 0; 101 | int row = 0; 102 | while (row < gridRowCount) 103 | { 104 | pages++; 105 | int viewHeight = grid->GetColLabelSize(); 106 | while (viewHeight + rowSizes.GetSize(row) < gridViewHeight) 107 | { 108 | viewHeight += rowSizes.GetSize(row); 109 | row++; 110 | } 111 | } 112 | 113 | return pages; 114 | } 115 | 116 | void OutputPrintout::GetPageInfo(int* minPage, int* maxPage, int* selPageFrom, int* selPageTo) 117 | { 118 | int pages = GetPageCount(); 119 | if (pages < 1) pages = 1; 120 | 121 | *minPage = 1; 122 | *maxPage = pages; 123 | *selPageFrom = 1; 124 | *selPageTo = pages; 125 | } 126 | -------------------------------------------------------------------------------- /main/OutputPrintout.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class OutputPrintout : public wxPrintout 8 | { 9 | public: 10 | OutputPrintout(wxGrid* g, const wxString& title = "My printout"); 11 | 12 | bool OnPrintPage(int page); 13 | bool HasPage(int page); 14 | bool OnBeginDocument(int startPage, int endPage); 15 | void GetPageInfo(int* minPage, int* maxPage, int* selPageFrom, int* selPageTo); 16 | 17 | private: 18 | wxGrid* grid; 19 | 20 | int GetPageCount(); 21 | }; 22 | -------------------------------------------------------------------------------- /main/RaceChoiceDlg.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "RaceChoiceDlg.h" 3 | 4 | BEGIN_EVENT_TABLE(CRaceChoiceDlg, wxDialog) 5 | EVT_BUTTON(wxID_OK, CRaceChoiceDlg::OnOK) 6 | END_EVENT_TABLE() 7 | 8 | IMPLEMENT_CLASS(CRaceChoiceDlg, wxDialog) 9 | 10 | CRaceChoiceDlg::CRaceChoiceDlg(wxWindow *parent /* = NULL */) 11 | : wxDialog(parent, -1, "Choose Race") 12 | { 13 | wxBeginBusyCursor(); 14 | 15 | wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL ); 16 | 17 | wxSizerFlags flagsBorder2; 18 | flagsBorder2.DoubleBorder(); 19 | 20 | topsizer->Add(CreateTextSizer("Select race:"), flagsBorder2); 21 | 22 | wxString races[] = {"Protoss", "Terran", "Zerg"}; 23 | 24 | m_combo = new wxComboBox(this, wxID_ANY, "Protoss", wxDefaultPosition, wxDefaultSize, 3, races, wxCB_READONLY|wxCB_SORT); 25 | 26 | topsizer->Add(m_combo, 27 | wxSizerFlags(0). 28 | Expand(). 29 | TripleBorder(wxLEFT | wxRIGHT)); 30 | 31 | wxSizer *buttonSizer = CreateSeparatedButtonSizer(wxOK | wxCANCEL); 32 | topsizer->Add(buttonSizer, wxSizerFlags(flagsBorder2).Expand()); 33 | 34 | SetAutoLayout( true ); 35 | SetSizer( topsizer ); 36 | 37 | topsizer->SetSizeHints( this ); 38 | topsizer->Fit( this ); 39 | 40 | Centre( wxBOTH ); 41 | 42 | m_combo->SetFocus(); 43 | 44 | wxEndBusyCursor(); 45 | } 46 | 47 | CRaceChoiceDlg::~CRaceChoiceDlg() 48 | { 49 | } 50 | 51 | void CRaceChoiceDlg::SetValue(const wxString &val) 52 | { 53 | m_value = val; 54 | 55 | m_combo->SetValue(val); 56 | } 57 | 58 | void CRaceChoiceDlg::OnOK(wxCommandEvent &WXUNUSED(event) ) 59 | { 60 | m_value = m_combo->GetValue(); 61 | 62 | EndModal(wxID_OK); 63 | } 64 | -------------------------------------------------------------------------------- /main/RaceChoiceDlg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CRaceChoiceDlg : public wxDialog 4 | { 5 | public: 6 | CRaceChoiceDlg(wxWindow *parent = NULL); 7 | ~CRaceChoiceDlg(); 8 | 9 | void OnOK(wxCommandEvent& event); 10 | 11 | void SetValue(const wxString& val); 12 | wxString GetValue() const { return m_value; } 13 | 14 | protected: 15 | wxComboBox *m_combo; 16 | wxString m_value; 17 | 18 | private: 19 | DECLARE_EVENT_TABLE() 20 | DECLARE_DYNAMIC_CLASS(wxTextEntryDialog) 21 | }; 22 | -------------------------------------------------------------------------------- /main/SC2/FitnessValue.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CFitnessValue 4 | { 5 | public: 6 | inline CFitnessValue(); 7 | inline CFitnessValue(const CFitnessValue &value); 8 | 9 | inline void StartRecalc() {} 10 | 11 | inline int Compare(const CFitnessValue &value) const 12 | { 13 | if(value < *this) 14 | return 1; 15 | else if(*this < value) 16 | return -1; 17 | else 18 | return 0; 19 | } 20 | 21 | inline void operator =(const CFitnessValue &value); 22 | inline bool operator <(const CFitnessValue &value) const; 23 | inline bool operator==(const CFitnessValue &value) const; 24 | operator double() const { return (m_requirementsValue + 0.01 * (m_optionalValue + 0.01 * m_economyValue)) / (m_requirementsTime > 0 ? (200.0 + m_requirementsTime) : 1); } 25 | 26 | bool m_succeeded; 27 | double m_requirementsValue; 28 | double m_requirementsTime; 29 | double m_optionalValue; 30 | double m_economyValue; 31 | double m_resourceValue; 32 | }; 33 | 34 | CFitnessValue::CFitnessValue() 35 | : m_succeeded(false) 36 | , m_requirementsValue(0.0) 37 | , m_requirementsTime(0.0) 38 | , m_optionalValue(0.0) 39 | , m_economyValue(0.0) 40 | , m_resourceValue(0.0) 41 | { 42 | } 43 | 44 | CFitnessValue::CFitnessValue(const CFitnessValue &value) 45 | { 46 | m_succeeded = value.m_succeeded; 47 | m_requirementsValue = value.m_requirementsValue; 48 | m_requirementsTime = value.m_requirementsTime; 49 | m_optionalValue = value.m_optionalValue; 50 | m_economyValue = value.m_economyValue; 51 | m_resourceValue = value.m_resourceValue; 52 | } 53 | 54 | void CFitnessValue::operator =(const CFitnessValue &value) 55 | { 56 | m_requirementsValue = value.m_requirementsValue; 57 | m_succeeded = value.m_succeeded; 58 | m_requirementsTime = value.m_requirementsTime; 59 | m_optionalValue = value.m_optionalValue; 60 | m_economyValue = value.m_economyValue; 61 | m_resourceValue = value.m_resourceValue; 62 | } 63 | 64 | #define VERY_SMALL_DOUBLE 0.000001 65 | 66 | bool CFitnessValue::operator <(const CFitnessValue &value) const 67 | { 68 | if(!m_succeeded && value.m_succeeded) 69 | return true; 70 | else if(m_succeeded != value.m_succeeded) 71 | return false; 72 | 73 | if(m_requirementsValue < value.m_requirementsValue - VERY_SMALL_DOUBLE) 74 | return true; 75 | else if(m_requirementsValue > value.m_requirementsValue + VERY_SMALL_DOUBLE) 76 | return false; 77 | 78 | if(m_requirementsTime > value.m_requirementsTime + VERY_SMALL_DOUBLE) 79 | return true; 80 | else if(m_requirementsTime < value.m_requirementsTime - VERY_SMALL_DOUBLE) 81 | return false; 82 | 83 | if(m_optionalValue < value.m_optionalValue - VERY_SMALL_DOUBLE) 84 | return true; 85 | else if(m_optionalValue > value.m_optionalValue + VERY_SMALL_DOUBLE) 86 | return false; 87 | 88 | if(m_economyValue < value.m_economyValue - VERY_SMALL_DOUBLE) 89 | return true; 90 | else if(m_economyValue > value.m_economyValue + VERY_SMALL_DOUBLE) 91 | return false; 92 | 93 | return m_resourceValue < value.m_resourceValue - VERY_SMALL_DOUBLE; 94 | } 95 | 96 | bool CFitnessValue::operator==(const CFitnessValue &value) const 97 | { 98 | return m_succeeded == value.m_succeeded 99 | && VERY_SMALL_DOUBLE > abs(m_requirementsValue - value.m_requirementsValue) 100 | && VERY_SMALL_DOUBLE > abs(m_requirementsTime - value.m_requirementsTime) 101 | && VERY_SMALL_DOUBLE > abs(m_optionalValue - value.m_optionalValue) 102 | && VERY_SMALL_DOUBLE > abs(m_economyValue - value.m_economyValue) 103 | && VERY_SMALL_DOUBLE > abs(m_resourceValue - value.m_resourceValue); 104 | } 105 | -------------------------------------------------------------------------------- /main/SC2/GameCalcs.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "GameCalcs.h" 3 | 4 | CGameCalcs CGameCalcs::m_init; 5 | 6 | double CGameCalcs::m_mineralIncomeRates[SC2_BASE_LIMIT + 1][300]; 7 | 8 | void CGameCalcs::InitData() 9 | { 10 | for(int baseCount=0; baseCount <= SC2_BASE_LIMIT; baseCount++) 11 | for(int workerCount=0; workerCount < 300; workerCount++) 12 | m_mineralIncomeRates[baseCount][workerCount] = CalculateMineralIncomeRate(baseCount, workerCount); 13 | } 14 | 15 | size_t CGameCalcs::MineralWorkerLimit(size_t baseCount) 16 | { 17 | if(baseCount > SC2_BASE_LIMIT) 18 | baseCount = SC2_BASE_LIMIT; 19 | return 3 * 8 * baseCount; 20 | } 21 | 22 | size_t CGameCalcs::GasWorkerLimit2Near(size_t baseCount, size_t geyserBuildingCount) 23 | { 24 | if(geyserBuildingCount > 2 * baseCount) 25 | geyserBuildingCount = 2 * baseCount; 26 | return 3 * geyserBuildingCount; 27 | } 28 | 29 | double CGameCalcs::CalculateMineralIncomeRate(size_t baseCount, size_t workerCount) 30 | { 31 | static double sumIncome[] = {0.0, 236/60.0, 470/60.0, 704/60.0, 936/60.0, 1070/60.0, 1115/60.0}; // Sum of income rates 32 | static double incomeRate[] = {59/60.0, 58.5/60.0, 58.5/60.0, 58/60.0, 33.5/60.0, 11.25/60.0, 0.0}; // Income rates 33 | 34 | size_t patchCount = 4 * baseCount; // Yes, I know it's 8 per base, this is per type of patch (near/far) & how many workers on that patch (1,2,3), in the order that they'd get used 35 | if(workerCount > 24*baseCount) 36 | workerCount = 24*baseCount; 37 | 38 | if(patchCount == 0 || workerCount == 0) 39 | return 0; 40 | 41 | size_t incomeRateIndex = workerCount/patchCount; 42 | return baseCount*sumIncome[incomeRateIndex] + (workerCount % patchCount)*incomeRate[incomeRateIndex]; 43 | } 44 | 45 | double CGameCalcs::CalculateGasIncomeRate2Near(size_t baseCount, size_t geyserBuildingCount, size_t workerCount) 46 | { 47 | static double closeGeyserSumIncome[] = {0.0, 62.5/60.0, 125/60.0, 163/60.0}; // Sum of income rates 48 | static double incomeRate[] = {62.5/60.0, 62.5/60.0, 38/60.0, 0.0}; // Income rates 49 | 50 | if (geyserBuildingCount == 0) 51 | return 0; 52 | 53 | if(geyserBuildingCount > 2 * baseCount) 54 | geyserBuildingCount = 2 * baseCount; 55 | 56 | if(workerCount > 3*geyserBuildingCount) 57 | workerCount = 3*geyserBuildingCount; 58 | 59 | size_t incomeRateIndex = workerCount / geyserBuildingCount; 60 | return geyserBuildingCount* closeGeyserSumIncome[incomeRateIndex] + (workerCount % geyserBuildingCount)*incomeRate[incomeRateIndex]; 61 | } 62 | -------------------------------------------------------------------------------- /main/SC2/GameCalcs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define SC2_BASE_LIMIT 10 4 | 5 | class CGameCalcs 6 | { 7 | public: 8 | CGameCalcs() { InitData(); } 9 | 10 | static void InitData(); 11 | 12 | static size_t MineralWorkerLimit(size_t baseCount); 13 | static size_t GasWorkerLimit2Near(size_t baseCount, size_t geyserBuildingCount); 14 | 15 | static double GetMineralIncomeRate(size_t baseCount, size_t workerCount) { return m_mineralIncomeRates[mymin(baseCount, (size_t)SC2_BASE_LIMIT)][workerCount]; } 16 | static double GetGasIncomeRate2Near(size_t baseCount, size_t geyserBuildingCount, size_t workerCount) { return CalculateGasIncomeRate2Near(baseCount, geyserBuildingCount, workerCount); } 17 | 18 | protected: 19 | static CGameCalcs m_init; 20 | 21 | static double CalculateMineralIncomeRate(size_t baseCount, size_t workerCount); 22 | static double CalculateGasIncomeRate2Near(size_t baseCount, size_t geyserBuildingCount, size_t workerCount); 23 | 24 | static double m_mineralIncomeRates[SC2_BASE_LIMIT + 1][300]; 25 | }; 26 | -------------------------------------------------------------------------------- /main/SC2/GasMicro.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | enum EGasMicro 4 | { 5 | eGasMicroOneBackAndForth = 1 6 | , eGasMicroThreeBackAndForth 7 | , eGasMicroOneToGasOnly 8 | , eGasMicroThreeToGasOnly 9 | , eGasMicroThreeUponCompletion 10 | }; 11 | -------------------------------------------------------------------------------- /main/SC2/SC2Building.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "SC2Building.h" 3 | 4 | CSC2Building::CSC2Building() 5 | : m_name() 6 | , m_gameStartCount(0) 7 | , m_isBase(false) 8 | , m_isGeyserBuilding(false) 9 | , m_isVisual(true) 10 | , m_providedSupply(0) 11 | , m_startingEnergy(0.0) 12 | , m_maxEnergy(0.0) 13 | , m_energyRechargeRate(0.0) 14 | , m_gameStartLarvaeCount(0) 15 | , m_initialLarvaeCount(0) // Upon building completion 16 | , m_maxLarvaeSpawningCount(0) 17 | , m_maxLarvaeCount(0) 18 | , m_larvaeSpawnTime(0.0) 19 | , m_initialStatusNames() 20 | , m_initialStatus(0) 21 | , m_initialStatusList() 22 | , m_initialStatusDurations() 23 | , m_initialProductionBoost(1.0) 24 | , m_gameStartStatusNames() 25 | , m_gameStartStatus(0) 26 | , m_gameStartStatusList() 27 | , m_gameStartStatusDurations() 28 | , m_gameStartProductionBoost(1.0) 29 | { 30 | } 31 | 32 | bool CSC2Building::LoadXML(const wxXmlNode *xmlBuilding) 33 | { 34 | for(wxXmlNode *child = xmlBuilding->GetChildren(); child; child = child->GetNext()) 35 | { 36 | if(wxXML_COMMENT_NODE == child->GetType()) 37 | continue; 38 | 39 | wxString content = child->GetNodeContent(); 40 | if (child->GetName() == wxT("Name")) 41 | { 42 | m_name = content; 43 | } 44 | else if (child->GetName() == wxT("ProvidedSupply")) 45 | { 46 | unsigned long providedSupply; 47 | content.ToULong(&providedSupply); 48 | m_providedSupply = (size_t)providedSupply; 49 | } 50 | else if (child->GetName() == wxT("IsBase")) 51 | { 52 | if(content == "True") 53 | m_isBase = true; 54 | else 55 | m_isBase = false; 56 | } 57 | else if (child->GetName() == wxT("IsGeyserBuilding")) 58 | { 59 | if (content == "True") 60 | m_isGeyserBuilding = true; 61 | else 62 | m_isGeyserBuilding = false; 63 | } 64 | else if (child->GetName() == wxT("IsVisual")) 65 | { 66 | if (content == "False") 67 | m_isVisual = false; 68 | else 69 | m_isVisual = true; 70 | } 71 | else if (child->GetName() == wxT("StartingEnergy")) 72 | { 73 | content.ToCDouble(&m_startingEnergy); 74 | } 75 | else if (child->GetName() == wxT("MaxEnergy")) 76 | { 77 | content.ToCDouble(&m_maxEnergy); 78 | } 79 | else if (child->GetName() == wxT("EnergyRechargeRate")) 80 | { 81 | content.ToCDouble(&m_energyRechargeRate); 82 | } 83 | else if (child->GetName() == wxT("GameStartCount")) 84 | { 85 | unsigned long gameStartCount; 86 | content.ToULong(&gameStartCount); 87 | m_gameStartCount = (size_t)gameStartCount; 88 | } 89 | else if (child->GetName() == wxT("GameStartLarvaeCount")) 90 | { 91 | unsigned long gameStartLarvaeCount; 92 | content.ToULong(&gameStartLarvaeCount); 93 | m_gameStartLarvaeCount = (size_t)gameStartLarvaeCount; 94 | } 95 | else if (child->GetName() == wxT("InitialLarvaeCount")) 96 | { 97 | unsigned long initialLarvaeCount; 98 | content.ToULong(&initialLarvaeCount); 99 | m_initialLarvaeCount = (size_t)initialLarvaeCount; 100 | } 101 | else if (child->GetName() == wxT("MaxLarvaeSpawningCount")) 102 | { 103 | unsigned long maxLarvaeSpawningCount; 104 | content.ToULong(&maxLarvaeSpawningCount); 105 | m_maxLarvaeSpawningCount = (size_t)maxLarvaeSpawningCount; 106 | } 107 | else if (child->GetName() == wxT("MaxLarvaeCount")) 108 | { 109 | unsigned long maxLarvaeCount; 110 | content.ToULong(&maxLarvaeCount); 111 | m_maxLarvaeCount = (size_t)maxLarvaeCount; 112 | } 113 | else if (child->GetName() == wxT("LarvaeSpawnTime")) 114 | { 115 | content.ToCDouble(&m_larvaeSpawnTime); 116 | } 117 | else if (child->GetName() == wxT("InitialStatus")) 118 | { 119 | double initialStatusDuration = 0.0; 120 | child->GetAttribute(wxT("time"), wxT("0.0")).ToCDouble(&initialStatusDuration); 121 | m_initialStatusDurations.push_back(initialStatusDuration); 122 | m_initialStatusNames.push_back(content); 123 | } 124 | else if (child->GetName() == wxT("GameStartStatus")) 125 | { 126 | double gameStartStatusDuration = 0.0; 127 | child->GetAttribute(wxT("time"), wxT("0.0")).ToCDouble(&gameStartStatusDuration); 128 | m_gameStartStatusDurations.push_back(gameStartStatusDuration); 129 | m_gameStartStatusNames.push_back(content); 130 | } 131 | else 132 | { 133 | wxFAIL_MSG(wxString::Format("Unexpected XML tag in : '%s'", child->GetName())); 134 | return false; 135 | } 136 | } 137 | 138 | return true; 139 | } 140 | 141 | bool CSC2Building::ResolveIDs(const CVector &buildingStatuses) 142 | { 143 | for (size_t i = 0; i < m_initialStatusNames.size(); i++) 144 | { 145 | size_t statusID = UINT_MAX; 146 | for (size_t j = 0; j < buildingStatuses.size(); j++) 147 | { 148 | if (m_initialStatusNames[i] == buildingStatuses[j]->GetName()) 149 | { 150 | statusID = j; 151 | break; 152 | } 153 | } 154 | 155 | wxCHECK_MSG(statusID < buildingStatuses.size(), false, wxString::Format("Undefined building state '%s'", m_initialStatusNames[i])); 156 | m_initialStatus |= ((SC2BuildingStatusFlags)1 << statusID); 157 | m_initialStatusList.push_back(statusID); 158 | m_initialProductionBoost *= buildingStatuses[statusID]->GetProductionBoostFactor(); 159 | } 160 | 161 | for (size_t i = 0; i < m_gameStartStatusNames.size(); i++) 162 | { 163 | size_t statusID = UINT_MAX; 164 | for (size_t j = 0; j < buildingStatuses.size(); j++) 165 | { 166 | if (m_gameStartStatusNames[i] == buildingStatuses[j]->GetName()) 167 | { 168 | statusID = j; 169 | break; 170 | } 171 | } 172 | 173 | wxCHECK_MSG(statusID < buildingStatuses.size(), false, wxString::Format("Undefined building state '%s'", m_gameStartStatusNames[i])); 174 | m_gameStartStatus |= ((SC2BuildingStatusFlags)1 << statusID); 175 | m_gameStartStatusList.push_back(statusID); 176 | m_gameStartProductionBoost *= buildingStatuses[statusID]->GetProductionBoostFactor(); 177 | } 178 | 179 | return true; 180 | } 181 | -------------------------------------------------------------------------------- /main/SC2/SC2Building.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../Core/Vector.h" 6 | #include "SC2Defines.h" 7 | #include "SC2BuildingStatus.h" 8 | 9 | class CSC2Building 10 | { 11 | public: 12 | CSC2Building(); 13 | ~CSC2Building() {} 14 | 15 | bool LoadXML(const wxXmlNode *xmlBuilding); 16 | 17 | const wxString &GetName() const { return m_name; } 18 | size_t GetGameStartCount() const { return m_gameStartCount; } 19 | bool IsBase() const { return m_isBase; } 20 | bool IsGeyserBuilding() const { return m_isGeyserBuilding; } 21 | bool IsVisual() const { return m_isVisual; } 22 | size_t GetProvidedSupply() const { return m_providedSupply; } 23 | double GetStartingEnergy() const { return m_startingEnergy; } 24 | double GetMaxEnergy() const { return m_maxEnergy; } 25 | double GetEnergyRechargeRate() const { return m_energyRechargeRate; } 26 | size_t GetGameStartLarvaeCount() const { return m_gameStartLarvaeCount; } 27 | size_t GetInitialLarvaeCount() const { return m_initialLarvaeCount; } 28 | size_t GetMaxLarvaeSpawningCount() const { return m_maxLarvaeSpawningCount; } 29 | size_t GetMaxLarvaeCount() const { return m_maxLarvaeCount; } 30 | double GetLarvaeSpawnTime() const { return m_larvaeSpawnTime; } 31 | SC2BuildingStatusFlags GetInitialStatus() const { return m_initialStatus; } 32 | const CVector &GetInitialStatusList() const { return m_initialStatusList; } 33 | const CVector &GetInitialStatusDurations() const { return m_initialStatusDurations; } 34 | double GetInitialProductionBoost() const { return m_initialProductionBoost; } 35 | SC2BuildingStatusFlags GetGameStartStatus() const { return m_gameStartStatus; } 36 | const CVector &GetGameStartStatusList() const { return m_gameStartStatusList; } 37 | const CVector &GetGameStartStatusDurations() const { return m_gameStartStatusDurations; } 38 | double GetGameStartProductionBoost() const { return m_gameStartProductionBoost; } 39 | 40 | bool ResolveIDs(const CVector &buildingStatuses); 41 | 42 | protected: 43 | wxString m_name; 44 | size_t m_gameStartCount; 45 | bool m_isBase; 46 | bool m_isGeyserBuilding; 47 | bool m_isVisual; 48 | size_t m_providedSupply; 49 | double m_startingEnergy; 50 | double m_maxEnergy; 51 | double m_energyRechargeRate; 52 | size_t m_gameStartLarvaeCount; 53 | size_t m_initialLarvaeCount; // Upon building completion 54 | size_t m_maxLarvaeSpawningCount; 55 | size_t m_maxLarvaeCount; 56 | double m_larvaeSpawnTime; 57 | std::vector m_initialStatusNames; 58 | SC2BuildingStatusFlags m_initialStatus; 59 | CVector m_initialStatusList; 60 | CVector m_initialStatusDurations; 61 | double m_initialProductionBoost; 62 | std::vector m_gameStartStatusNames; 63 | SC2BuildingStatusFlags m_gameStartStatus; 64 | CVector m_gameStartStatusList; 65 | CVector m_gameStartStatusDurations; 66 | double m_gameStartProductionBoost; 67 | }; 68 | -------------------------------------------------------------------------------- /main/SC2/SC2BuildingStatus.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "SC2BuildingStatus.h" 3 | 4 | CSC2BuildingStatus::CSC2BuildingStatus() 5 | : m_name() 6 | , m_productionBoostFactor(1.0) 7 | , m_isVisual(false) 8 | { 9 | } 10 | 11 | bool CSC2BuildingStatus::LoadXML(const wxXmlNode *xmlStatus) 12 | { 13 | for (wxXmlNode *child = xmlStatus->GetChildren(); child; child = child->GetNext()) 14 | { 15 | if (wxXML_COMMENT_NODE == child->GetType()) 16 | continue; 17 | 18 | wxString content = child->GetNodeContent(); 19 | if (child->GetName() == wxT("Name")) 20 | { 21 | m_name = content; 22 | } 23 | else if (child->GetName() == wxT("ProductionBoostFactor")) 24 | { 25 | content.ToCDouble(&m_productionBoostFactor); 26 | } 27 | else if (child->GetName() == wxT("IsVisual")) 28 | { 29 | m_isVisual = content == "True"; 30 | } 31 | else 32 | { 33 | wxFAIL_MSG(wxString::Format("Unexpected XML tag in : '%s'", child->GetName())); 34 | return false; 35 | } 36 | } 37 | 38 | return true; 39 | } 40 | -------------------------------------------------------------------------------- /main/SC2/SC2BuildingStatus.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../Core/Vector.h" 6 | 7 | class CSC2BuildingStatus 8 | { 9 | public: 10 | CSC2BuildingStatus(); 11 | ~CSC2BuildingStatus() {} 12 | 13 | bool LoadXML(const wxXmlNode *xmlRace); 14 | 15 | const wxString &GetName() const { return m_name; } 16 | double GetProductionBoostFactor() const { return m_productionBoostFactor; } 17 | bool IsVisual() const { return m_isVisual; } 18 | 19 | protected: 20 | wxString m_name; 21 | double m_productionBoostFactor; 22 | bool m_isVisual; 23 | }; 24 | -------------------------------------------------------------------------------- /main/SC2/SC2Defines.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define SC2_BUILDING_ID_LIMIT 32 4 | #define SC2_BUILDING_TRACKING_LIMIT 8 5 | #define SC2_UNIT_ID_LIMIT 32 6 | #define SC2_UNIT_TRACKING_LIMIT 8 7 | #define SC2_RESEARCH_ID_LIMIT 64 8 | 9 | #if SC2_BUILDING_ID_LIMIT <= 32 10 | typedef unsigned long SC2BuildingFlags; 11 | #else 12 | typedef unsigned long long SC2BuildingFlags; 13 | #endif 14 | 15 | #if SC2_UNIT_ID_LIMIT <= 32 16 | typedef unsigned long SC2UnitFlags; 17 | #else 18 | typedef unsigned long long SC2UnitFlags; 19 | #endif 20 | 21 | #if SC2_RESEARCH_ID_LIMIT <= 32 22 | typedef unsigned long SC2ResearchFlags; 23 | #else 24 | typedef unsigned long long SC2ResearchFlags; 25 | #endif 26 | 27 | typedef unsigned char SC2BuildingStatusFlags; 28 | 29 | typedef unsigned char SC2UnitStatusFlags; 30 | 31 | enum ESC2SourceType 32 | { 33 | eSourceTypeNone = -1 34 | , eSourceTypeUnit = 0 35 | , eSourceTypeBuilding = 1 36 | }; 37 | -------------------------------------------------------------------------------- /main/SC2/SC2Event.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "SC2Event.h" 3 | 4 | template<> 5 | void initArray(CSC2Event *data, size_t from, size_t to) {} 6 | -------------------------------------------------------------------------------- /main/SC2/SC2Event.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define SC2EVENT_BITFIELDS 4 | 5 | #include "../Core/Vector.h" 6 | #include "ChartItem.h" 7 | 8 | class CSC2Event 9 | { 10 | public: 11 | enum EEventCategory 12 | { 13 | eWorkerStartMiningMinerals = 0 14 | , eWorkerStartMiningGas 15 | , eSendScout 16 | , eKillScout 17 | , eReturnScout 18 | , eBuildingComplete 19 | , eUnitComplete 20 | , eUnitMorph 21 | , eUnitDies // MULEs and other temporary units 22 | , eResearchComplete 23 | , eBuildingConsume 24 | , eBuildingMorph 25 | , eBuildingStatusApply 26 | , eBuildingStatusLapse 27 | , eBuildingSpawnLarvae 28 | , eBuildingSpawnBonusLarvae 29 | , eSpawnBase 30 | , eEventCount 31 | }; 32 | 33 | #ifdef SC2EVENT_BITFIELDS 34 | struct SEvent 35 | { 36 | SEvent(const SEvent &event) 37 | : m_data(event.m_data) 38 | { 39 | } 40 | 41 | SEvent(double startTime, size_t eventCategory, bool sourceIsBuilding, size_t sourceID, size_t targetID, size_t data, ChartItem::QueueType queueType) 42 | { 43 | m_data.m_startTime = startTime; 44 | m_data.m_eventCategory = eventCategory; 45 | m_data.m_sourceIsBuilding = sourceIsBuilding; 46 | m_data.m_sourceID = sourceID; 47 | m_data.m_targetID = targetID; 48 | m_data.m_data = data; 49 | m_data.m_queueType = queueType; 50 | } 51 | 52 | void operator=(const SEvent &event) 53 | { 54 | m_data = event.m_data; 55 | } 56 | 57 | struct SData 58 | { 59 | double m_startTime; 60 | size_t m_eventCategory : 5; 61 | bool m_sourceIsBuilding : 1; 62 | size_t m_sourceID : 10; 63 | size_t m_targetID : 10; 64 | size_t m_data : 6; 65 | ChartItem::QueueType m_queueType; 66 | } m_data; 67 | }; 68 | 69 | CSC2Event(double time, size_t eventCategory, bool sourceIsBuilding = false, size_t sourceID = 0, size_t targetID = 0, size_t data = 0, double startTime = 0, ChartItem::QueueType queueType = ChartItem::qSingle) : m_time(time), m_event(startTime, eventCategory, sourceIsBuilding, sourceID, targetID, data, queueType) {} 70 | 71 | #elif SC2EVENT_UNIONBITFIELD 72 | union SEvent 73 | { 74 | SEvent(const SEvent &event) 75 | : m_copyMember(event.m_copyMember) 76 | { 77 | } 78 | 79 | SEvent(size_t eventCategory, bool sourceIsBuilding, size_t sourceID, size_t targetID, size_t data) 80 | : m_data.m_eventCategory(eventCategory) 81 | , m_data.m_sourceID(sourceID) 82 | , m_data.m_targetID(targetID) 83 | , m_data.m_data(data) 84 | { 85 | } 86 | 87 | void operator=(const SEvent &event) 88 | { 89 | m_copyMember = event.m_copyMember; 90 | } 91 | 92 | unsigned long m_copyMember; 93 | 94 | struct SData 95 | { 96 | size_t m_eventCategory : 5; 97 | bool m_sourceIsBuilding : 1; 98 | size_t m_sourceID : 10; 99 | size_t m_targetID : 10; 100 | size_t m_data : 6 101 | } m_data; 102 | } 103 | 104 | CSC2Event(double time, size_t eventCategory, bool sourceIsBuilding = false, size_t sourceID = 0, size_t targetID = 0, size_t data = 0) : m_time(time), m_event(eventCategory, sourceIsBuilding, sourceID, targetID, data) {} 105 | 106 | #else 107 | struct SEvent 108 | { 109 | SEvent(const SEvent &event) 110 | : m_data(event.m_data) 111 | { 112 | } 113 | 114 | SEvent(unsigned char eventCategory, bool sourceIsBuilding, unsigned short sourceID, unsigned short targetID, unsigned char data) 115 | : m_data.m_eventCategory(eventCategory) 116 | , m_data.m_sourceID(sourceID) 117 | , m_data.m_targetID(targetID) 118 | , m_data.m_data(data) 119 | { 120 | } 121 | 122 | void operator=(const SEvent &event) 123 | { 124 | m_data = event.m_data; 125 | } 126 | 127 | struct SData 128 | { 129 | unsigned char m_eventCategory; 130 | bool m_sourceIsBuilding; 131 | unsigned short m_sourceID; 132 | unsigned short m_targetID; 133 | unsigned char m_data; 134 | } m_data; 135 | }; 136 | 137 | CSC2Event(double time, unsigned char eventCategory, bool sourceIsBuilding = false, unsigned short sourceID = 0, unsigned short targetID = 0, unsigned char data = 0) : m_time(time), m_event(eventCategory, sourceIsBuilding, sourceID, targetID, data) {} 138 | 139 | #endif 140 | 141 | CSC2Event(double time, const SEvent &event) : m_time(time), m_event(event) {} 142 | 143 | double m_time; 144 | SEvent m_event; 145 | 146 | bool operator <(const CSC2Event &event) const { return m_time < event.m_time; } 147 | }; 148 | 149 | //const WCHAR *tostring(EOutputFormat format, CSC2Event::EEvent event); 150 | 151 | //bool DisplayEvent(EOutputFormat format, CSC2Event::EEvent event); 152 | 153 | template<> 154 | void initArray(CSC2Event *data, size_t from, size_t to); 155 | -------------------------------------------------------------------------------- /main/SC2/SC2FitnessCalc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "../Core/Vector.h" 6 | #include "../Core/PriorityQueue.h" 7 | #include "FitnessValue.h" 8 | #include "GasMicro.h" 9 | #include "SC2State.h" 10 | #include "SC2Event.h" 11 | #include "SC2Output.h" 12 | #include "SC2RaceInfo.h" 13 | 14 | #define START_TIME 2.0 // Assume it takes 2 secs to start building/mining anything 15 | 16 | class CSC2FitnessCalc 17 | { 18 | public: 19 | CSC2FitnessCalc(ESC2Race race, const CSC2RaceInfo &raceInfo, double timeLimit, EGasMicro gasMicro, double minimumCommandDuration) : m_race(race), m_raceInfo(raceInfo), m_timeLimit(timeLimit), m_gasMicro(gasMicro), m_minimumCommandDuration(minimumCommandDuration), m_initialState(race, raceInfo.GetData()), m_initialEvents() {} 20 | ~CSC2FitnessCalc(); 21 | 22 | void SetInitialBuildOrder(const CVector &initialBuildOrder) { m_initialBuildOrder = initialBuildOrder; } 23 | bool InitialiseBuildOrder(); 24 | void InitData(CSC2State &state, CPriorityQueue &events) const { state = m_initialState; InitEvents(events); } 25 | void InitEvents(CPriorityQueue &events) const; 26 | void BuildAlphabet(CVector &alphabet); 27 | void AddWaypoint(const CSC2Waypoint &target); 28 | 29 | void ClearCustomEvents() { m_customEvents.erase(0, m_customEvents.size()); } 30 | void AddCustomEvent(const CSC2Event &event) { m_customEvents.push_back(event); } 31 | 32 | bool ValidateAndCalculateFitness(CGASequenceChromosome &chromosome, CFitnessValue &fitness) const; 33 | bool SatisfiesTarget(const CGASequenceChromosome &chromosome) const { return false; } 34 | 35 | CSC2State *PrintGame(CSC2Output &output, const CGASequenceChromosome &chromosome) const; 36 | 37 | const CVector &GetTargets() const { return m_waypoints; } 38 | 39 | protected: 40 | template 41 | void ValidateAndCalculateFitness(CVector &buildOrder, CSC2State &state, CPriorityQueue &events, TResult &result) const; 42 | 43 | ESC2Race m_race; 44 | const CSC2RaceInfo &m_raceInfo; 45 | double m_timeLimit; 46 | EGasMicro m_gasMicro; 47 | double m_minimumCommandDuration; 48 | CVector m_waypoints; 49 | CVector m_customEvents; 50 | CVector m_initialBuildOrder; 51 | CSC2State m_initialState; 52 | CPriorityQueue m_initialEvents; 53 | }; 54 | -------------------------------------------------------------------------------- /main/SC2/SC2Output.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "SC2Command.h" 4 | #include "SC2Waypoint.h" 5 | #include "SC2State.h" 6 | #include "SC2Event.h" 7 | #include "ChartItem.h" 8 | #include "GridItem.h" 9 | 10 | class CSC2Output 11 | { 12 | public: 13 | virtual ~CSC2Output() {} 14 | 15 | virtual void ProcessCommand(const CSC2Command *command, const CSC2Waypoint &waypoint, const CSC2State &state) {} 16 | virtual void ProcessEvent(const CSC2Event &event, const CSC2Waypoint &waypoint, const CSC2State &state) {} 17 | virtual void ProcessWaypointComplete(bool succeeded, size_t waypointIndex, const CSC2Waypoint &waypoint, const CSC2State &state) {} 18 | 19 | virtual void Reset() = 0; 20 | 21 | virtual void GetOutput(wxString &output) const = 0; 22 | 23 | protected: 24 | CSC2Output() {} 25 | }; 26 | 27 | class CSC2OutputMinimal : public CSC2Output 28 | { 29 | public: 30 | CSC2OutputMinimal() : m_lastCommand(NULL), m_lastCommandCount(0), m_lastCommandSupplyCount(0), m_lastCommandTime(0.0), m_lastCommandWaitDuration(0.0) {} 31 | ~CSC2OutputMinimal() {} 32 | 33 | void ProcessCommand(const CSC2Command *command, const CSC2Waypoint &waypoint, const CSC2State &state) override; 34 | void ProcessEvent(const CSC2Event &event, const CSC2Waypoint &waypoint, const CSC2State &state) override; 35 | void ProcessWaypointComplete(bool succeeded, size_t waypointIndex, const CSC2Waypoint &waypoint, const CSC2State &state) override; 36 | 37 | void Reset() { m_lastCommandCount = 0; m_output.clear(); } 38 | 39 | void GetOutput(wxString &output) const override { output = m_output; } 40 | 41 | protected: 42 | const CSC2Command *m_lastCommand; 43 | size_t m_lastCommandCount; 44 | size_t m_lastCommandSupplyCount; 45 | double m_lastCommandTime; 46 | double m_lastCommandWaitDuration; 47 | wxString m_output; 48 | }; 49 | 50 | class CSC2OutputChart : public CSC2Output 51 | { 52 | public: 53 | CSC2OutputChart() {} 54 | ~CSC2OutputChart() {} 55 | 56 | void ProcessCommand(const CSC2Command* command, const CSC2Waypoint& waypoint, const CSC2State& state) override; 57 | void ProcessEvent(const CSC2Event& event, const CSC2Waypoint& waypoint, const CSC2State& state) override; 58 | void ProcessWaypointComplete(bool succeeded, size_t waypointIndex, const CSC2Waypoint& waypoint, const CSC2State& state) override; 59 | 60 | void Reset() 61 | { 62 | m_output.clear(); 63 | m_chart_items.clear(); 64 | } 65 | 66 | void GetOutput(wxString& output) const override { output = m_output; } 67 | void GetChartItems(vector>& chartItems) const { chartItems = m_chart_items; } 68 | 69 | void AddChartItem(size_t buildingId, ChartItem item); 70 | 71 | protected: 72 | wxString m_output; 73 | vector> m_chart_items; 74 | }; 75 | 76 | class CSC2OutputGrid : public CSC2Output 77 | { 78 | public: 79 | CSC2OutputGrid() {} 80 | ~CSC2OutputGrid() {} 81 | 82 | void ProcessCommand(const CSC2Command* command, const CSC2Waypoint& waypoint, const CSC2State& state) override; 83 | void ProcessEvent(const CSC2Event& event, const CSC2Waypoint& waypoint, const CSC2State& state) override; 84 | void ProcessWaypointComplete(bool succeeded, size_t waypointIndex, const CSC2Waypoint& waypoint, const CSC2State& state) override; 85 | 86 | void Reset() 87 | { 88 | m_data.clear(); 89 | }; 90 | 91 | void GetOutput(wxString& output) const override { output = m_output; } 92 | 93 | void GetData(vector& data) const { data = m_data; } 94 | 95 | protected: 96 | vector m_data; 97 | wxString m_output; 98 | 99 | }; -------------------------------------------------------------------------------- /main/SC2/SC2Race.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "SC2Race.h" 3 | 4 | wxString tostring(const ESC2Race &race) 5 | { 6 | switch(race) 7 | { 8 | case eProtoss: 9 | return wxT("Protoss"); 10 | case eTerran: 11 | return wxT("Terran"); 12 | case eZerg: 13 | return wxT("Zerg"); 14 | } 15 | 16 | return wxT(""); 17 | } 18 | -------------------------------------------------------------------------------- /main/SC2/SC2Race.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | enum ESC2Race 4 | { 5 | eProtoss 6 | , eTerran 7 | , eZerg 8 | }; 9 | 10 | wxString tostring(const ESC2Race &race); 11 | -------------------------------------------------------------------------------- /main/SC2/SC2RaceData.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "SC2RaceData.h" 3 | #include "SC2Building.h" 4 | #include "SC2Unit.h" 5 | #include "SC2Research.h" 6 | 7 | CSC2RaceData::CSC2RaceData() 8 | : m_buildings() 9 | , m_buildingStatuses() 10 | , m_units() 11 | , m_research() 12 | , m_buildingNames() 13 | , m_buildingStatusNames() 14 | , m_unitNames() 15 | , m_researchNames() 16 | , m_hasLarvae(false) 17 | { 18 | } 19 | 20 | CSC2RaceData::~CSC2RaceData() 21 | { 22 | RemoveAllPointer(m_buildings); 23 | RemoveAllPointer(m_buildingStatuses); 24 | RemoveAllPointer(m_units); 25 | RemoveAllPointer(m_research); 26 | } 27 | 28 | bool CSC2RaceData::LoadBuildingStatusesXML(const wxXmlNode *xmlBuildingStatuses) 29 | { 30 | for(wxXmlNode *child = xmlBuildingStatuses->GetChildren(); child; child = child->GetNext()) 31 | { 32 | if(wxXML_COMMENT_NODE == child->GetType()) 33 | continue; 34 | 35 | if (child->GetName() == wxT("BuildingStatus")) 36 | { 37 | CSC2BuildingStatus *buildingStatus = new CSC2BuildingStatus(); 38 | if (!buildingStatus->LoadXML(child)) 39 | { 40 | delete buildingStatus; 41 | return false; 42 | } 43 | 44 | m_buildingStatuses.push_back(buildingStatus); 45 | m_buildingStatusNames.push_back(buildingStatus->GetName()); 46 | } 47 | else 48 | { 49 | wxFAIL_MSG(wxString::Format("Unexpected XML tag in : '%s'", child->GetName())); 50 | return false; 51 | } 52 | } 53 | 54 | return true; 55 | } 56 | 57 | bool CSC2RaceData::LoadBuildingXML(const wxXmlNode *xmlBuildings) 58 | { 59 | for(wxXmlNode *child = xmlBuildings->GetChildren(); child; child = child->GetNext()) 60 | { 61 | if(wxXML_COMMENT_NODE == child->GetType()) 62 | continue; 63 | 64 | if (child->GetName() == wxT("Building")) 65 | { 66 | CSC2Building *building = new CSC2Building(); 67 | if(!building->LoadXML(child)) 68 | { 69 | delete building; 70 | return false; 71 | } 72 | 73 | m_buildings.push_back(building); 74 | m_buildingNames.push_back(building->GetName()); 75 | 76 | if(building->GetMaxLarvaeCount() > 0) 77 | m_hasLarvae = true; 78 | } 79 | else 80 | { 81 | wxFAIL_MSG(wxString::Format("Unexpected XML tag in : '%s'", child->GetName())); 82 | return false; 83 | } 84 | } 85 | 86 | return true; 87 | } 88 | 89 | bool CSC2RaceData::LoadUnitXML(const wxXmlNode *xmlUnits) 90 | { 91 | for(wxXmlNode *child = xmlUnits->GetChildren(); child; child = child->GetNext()) 92 | { 93 | if(wxXML_COMMENT_NODE == child->GetType()) 94 | continue; 95 | 96 | if (child->GetName() == wxT("Unit")) 97 | { 98 | CSC2Unit *unit = new CSC2Unit(); 99 | if(!unit->LoadXML(child)) 100 | { 101 | delete unit; 102 | return false; 103 | } 104 | 105 | m_units.push_back(unit); 106 | m_unitNames.push_back(unit->GetName()); 107 | } 108 | else 109 | { 110 | wxFAIL_MSG(wxString::Format("Unexpected XML tag in : '%s'", child->GetName())); 111 | return false; 112 | } 113 | } 114 | 115 | return true; 116 | } 117 | 118 | bool CSC2RaceData::LoadResearchXML(const wxXmlNode *xmlResearch) 119 | { 120 | for(wxXmlNode *child = xmlResearch->GetChildren(); child; child = child->GetNext()) 121 | { 122 | if(wxXML_COMMENT_NODE == child->GetType()) 123 | continue; 124 | 125 | if (child->GetName() == wxT("Research")) 126 | { 127 | CSC2Research *research = new CSC2Research(); 128 | if(!research->LoadXML(child)) 129 | { 130 | delete research; 131 | return false; 132 | } 133 | 134 | m_research.push_back(research); 135 | m_researchNames.push_back(research->GetName()); 136 | } 137 | else 138 | { 139 | wxFAIL_MSG(wxString::Format("Unexpected XML tag in : '%s'", child->GetName())); 140 | return false; 141 | } 142 | } 143 | 144 | return true; 145 | } 146 | 147 | bool CSC2RaceData::ResolveIDs() 148 | { 149 | for (size_t i = 0; i < m_buildings.size(); i++) 150 | { 151 | if (!m_buildings[i]->ResolveIDs(m_buildingStatuses)) 152 | return false; 153 | } 154 | for (size_t i = 0; i < m_research.size(); i++) 155 | { 156 | if (!m_research[i]->ResolveIDs(m_researchNames)) 157 | return false; 158 | } 159 | 160 | return true; 161 | } 162 | -------------------------------------------------------------------------------- /main/SC2/SC2RaceData.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Core/Vector.h" 4 | 5 | #include "SC2Defines.h" 6 | #include "SC2Race.h" 7 | #include "SC2Building.h" 8 | #include "SC2BuildingStatus.h" 9 | #include "SC2Unit.h" 10 | #include "SC2Research.h" 11 | 12 | #include 13 | 14 | class CSC2RaceData 15 | { 16 | public: 17 | CSC2RaceData(); 18 | ~CSC2RaceData(); 19 | 20 | bool LoadBuildingStatusesXML(const wxXmlNode *xmlBuildingStatuses); 21 | bool LoadBuildingXML(const wxXmlNode *xmlBuildings); 22 | bool LoadUnitXML(const wxXmlNode *xmlUnits); 23 | bool LoadResearchXML(const wxXmlNode *xmlResearch); 24 | 25 | bool ResolveIDs(); 26 | 27 | CVector m_buildings; 28 | CVector m_buildingStatuses; 29 | CVector m_units; 30 | CVector m_research; 31 | bool m_hasLarvae; 32 | 33 | protected: 34 | std::vector m_buildingNames; 35 | std::vector m_buildingStatusNames; 36 | std::vector m_unitNames; 37 | std::vector m_researchNames; 38 | }; 39 | -------------------------------------------------------------------------------- /main/SC2/SC2RaceInfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../Core/Vector.h" 6 | 7 | #include "SC2Defines.h" 8 | #include "SC2Race.h" 9 | #include "SC2RaceData.h" 10 | #include "SC2Command.h" 11 | #include "SC2Target.h" 12 | #include "SC2RequiredCommand.h" 13 | 14 | class CSC2RaceInfo 15 | { 16 | public: 17 | CSC2RaceInfo(); 18 | ~CSC2RaceInfo(); 19 | 20 | bool LoadXML(const wxXmlNode *xmlRace); 21 | 22 | const wxString &GetName() const { return m_name; } 23 | const CSC2RaceData &GetData() const { return m_data; } 24 | const CVector &GetCommands() const { return m_allCommands; } 25 | 26 | const CVector *> &GetBuildingPrerequisitCommands() const { return m_buildingPrerequisitCommands; } 27 | const CVector *> *> &GetBuildingStatusPrerequisitCommands() const { return m_buildingStatusPrerequisitCommands; } 28 | const CVector *> &GetUnitPrerequisitCommands() const { return m_unitPrerequisitCommands; } 29 | const CVector *> &GetResearchPrerequisitCommands() const { return m_researchPrerequisitCommands; } 30 | const CVector &GetBuildGeyserBuildingCommands() const { return m_buildGeyserBuildingCommands; } 31 | const CVector &GetMoveWorkersToMineralsCommands() const { return m_moveWorkersToMineralsCommands; } 32 | const CVector &GetMoveWorkersToGasCommands() const { return m_moveWorkersToGasCommands; } 33 | const CVector &GetProvideSupplyCommands() const { return m_provideSupplyCommands; } 34 | 35 | const CVector &GetMacroAbilityCommands() const { return m_macroAbilityCommands; } 36 | 37 | const CVector &GetTargets() const { return m_targets; } 38 | 39 | const CSC2Command *GetRequiredCommand(EGasMicro gasMicro, const CSC2State &state) const; 40 | 41 | protected: 42 | wxString m_name; 43 | CSC2RaceData m_data; 44 | CVector m_allCommands; 45 | CVector m_xmlCommands; 46 | CVector m_requiredCommands; 47 | CVector m_targets; 48 | 49 | CVector *> m_buildingPrerequisitCommands; 50 | CVector *> *> m_buildingStatusPrerequisitCommands; 51 | CVector *> m_unitPrerequisitCommands; 52 | CVector *> m_researchPrerequisitCommands; 53 | CVector m_buildGeyserBuildingCommands; 54 | CVector m_macroAbilityCommands; 55 | CVector m_moveWorkersToMineralsCommands; 56 | CVector m_moveWorkersToGasCommands; 57 | CVector m_provideSupplyCommands; 58 | 59 | bool LoadCommandXML(const wxXmlNode *xmlRace); 60 | bool LoadRequiredCommandXML(const wxXmlNode *xmlRace); 61 | bool LoadTargets(const wxXmlNode *xmlTargets); 62 | }; 63 | -------------------------------------------------------------------------------- /main/SC2/SC2RequiredCommand.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "SC2Command.h" 4 | #include "SC2State.h" 5 | #include "TargetMinMax.h" 6 | 7 | class CSC2RequiredCommand 8 | { 9 | public: 10 | CSC2RequiredCommand(); 11 | ~CSC2RequiredCommand(); 12 | 13 | bool LoadXML(const wxXmlNode *xmlCommand); 14 | bool ResolveIDs(const CSC2RaceData &raceData, const CVector &commands); 15 | 16 | bool MeetsRequirements(const CSC2State &state) const; 17 | const CSC2Command *GetCommand() const { return m_command; } 18 | 19 | protected: 20 | std::vector m_buildingRequirementNames; 21 | SC2BuildingFlags m_buildingRequirements; 22 | std::vector m_unitRequirementNames; 23 | SC2UnitFlags m_unitRequirements; 24 | std::vector m_researchRequirementNames; 25 | SC2ResearchFlags m_researchRequirements; 26 | 27 | std::vector m_buildingNames; 28 | CVector m_buildingIDs; 29 | CVector> m_buildingRange; 30 | std::vector m_unitNames; 31 | CVector m_unitIDs; 32 | CVector> m_unitRange; 33 | 34 | wxString m_commandName; 35 | const CSC2Command *m_command; 36 | }; 37 | -------------------------------------------------------------------------------- /main/SC2/SC2Research.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "SC2Research.h" 3 | 4 | CSC2Research::CSC2Research() 5 | : m_name() 6 | , m_deprecateResearchIDs() 7 | { 8 | } 9 | 10 | bool CSC2Research::LoadXML(const wxXmlNode *xmlResearch) 11 | { 12 | for(wxXmlNode *child = xmlResearch->GetChildren(); child; child = child->GetNext()) 13 | { 14 | if(wxXML_COMMENT_NODE == child->GetType()) 15 | continue; 16 | 17 | wxString content = child->GetNodeContent(); 18 | if (child->GetName() == wxT("Name")) 19 | { 20 | m_name = content; 21 | } 22 | else if (child->GetName() == wxT("DeprecateResearch")) 23 | { 24 | m_deprecateResearch.push_back(content); 25 | } 26 | else 27 | { 28 | wxFAIL_MSG(wxString::Format("Unexpected XML tag in : '%s'", child->GetName())); 29 | return false; 30 | } 31 | } 32 | 33 | return true; 34 | } 35 | 36 | bool CSC2Research::ResolveIDs(const std::vector &researchNames) 37 | { 38 | for(size_t i=0; i < m_deprecateResearch.size(); i++) 39 | { 40 | size_t researchID = UINT_MAX; 41 | for(size_t j=0; j < researchNames.size(); j++) 42 | { 43 | if(m_deprecateResearch[i] == researchNames[j]) 44 | { 45 | researchID = j; 46 | break; 47 | } 48 | } 49 | 50 | wxCHECK_MSG(researchID < researchNames.size(), false, wxString::Format("Unknown research to be deprecated: '%s'", m_deprecateResearch[i])); 51 | 52 | m_deprecateResearchIDs.push_back(researchID); 53 | } 54 | 55 | return true; 56 | } 57 | -------------------------------------------------------------------------------- /main/SC2/SC2Research.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../Core/Vector.h" 6 | 7 | class CSC2Research 8 | { 9 | public: 10 | CSC2Research(); 11 | ~CSC2Research() {} 12 | 13 | bool LoadXML(const wxXmlNode *xmlRace); 14 | 15 | const wxString &GetName() const { return m_name; } 16 | 17 | bool ResolveIDs(const std::vector &researchNames); 18 | 19 | protected: 20 | wxString m_name; 21 | std::vector m_deprecateResearch; 22 | CVector m_deprecateResearchIDs; 23 | }; 24 | -------------------------------------------------------------------------------- /main/SC2/SC2State.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "../Core/PriorityQueue.h" 5 | 6 | #include "SC2Event.h" 7 | #include "SC2Race.h" 8 | #include "SC2RaceData.h" 9 | #include "SC2Defines.h" 10 | #include "SC2Building.h" 11 | #include "SC2Unit.h" 12 | #include "SC2Research.h" 13 | #include "GasMicro.h" 14 | #include "GridItem.h" 15 | 16 | class CSC2State 17 | { 18 | public: 19 | CSC2State(ESC2Race race, const CSC2RaceData &raceData); 20 | CSC2State(const CSC2State &state); 21 | ~CSC2State(); 22 | 23 | void SetInitialState(CPriorityQueue &events); 24 | void StartMining(); 25 | 26 | void operator=(const CSC2State &state); 27 | 28 | void RecalculateMineralIncomeRate(); 29 | void RecalculateGasIncomeRate(); 30 | 31 | void ProgressTime(double duration); 32 | void ProcessEvent(CPriorityQueue &events); 33 | 34 | void PrintSummary(wxString &output) const; 35 | void PrintDetails(wxString &output) const; 36 | void FillData(GridItem& item) const; 37 | void FillMilestoneData(GridItem& item) const; 38 | 39 | const ESC2Race m_race; 40 | const CSC2RaceData &m_raceData; 41 | 42 | // Status 43 | double m_time; 44 | 45 | // Resources 46 | double m_minerals; 47 | double m_gas; 48 | double m_mineralsMined; 49 | double m_gasMined; 50 | 51 | // Income Rates 52 | double m_bonusMineralIncomeRate; // MULEs 53 | double m_mineralIncomeRate; 54 | double m_gasIncomeRate; 55 | 56 | // Buildings 57 | size_t m_baseCount; 58 | size_t m_geyserCount; 59 | size_t m_basesUnderConstruction; 60 | size_t m_geysersUnderConstruction; 61 | SC2BuildingFlags m_buildingCompletedFlags; 62 | SC2BuildingFlags m_buildingUnderConstructionFlags; 63 | CVector m_buildingUnderConstruction; 64 | CVector m_buildingMorphing; 65 | struct SBuildingState : public CMemPoolNode 66 | { 67 | size_t buildingTypeID; 68 | size_t buildingID; 69 | size_t larvaeCount; 70 | double maxEnergyTime; 71 | double larvaeDelayTime; 72 | double productionBoost; 73 | SC2BuildingStatusFlags status; 74 | }; 75 | class CBuildingStateList : public CMemPoolNode 76 | { 77 | public: 78 | CBuildingStateList(const CSC2Building &building) 79 | : m_building(building) 80 | , m_buildingList() 81 | { 82 | } 83 | 84 | ~CBuildingStateList() 85 | { 86 | } 87 | 88 | size_t size() const { return m_buildingList.size(); } 89 | void erase(size_t index, size_t count = 1) { m_buildingList.erase(index, count); } 90 | SBuildingState *GetAt(size_t index) { return m_buildingList[index]; } 91 | const SBuildingState *GetAt(size_t index) const { return m_buildingList[index]; } 92 | 93 | SBuildingState *operator[](size_t index) { return m_buildingList[index]; } 94 | const SBuildingState *operator[](size_t index) const { return m_buildingList[index]; } 95 | 96 | double CalculateEnergy(size_t index, double time) const; 97 | void UseEnergy(size_t index, double energy, double time); 98 | 99 | const CSC2Building &m_building; 100 | CVector m_buildingList; 101 | }; 102 | CVector m_buildings; 103 | CVector m_allBuildings; 104 | CVector m_larvaeSpawningBuildings; 105 | 106 | // Units 107 | size_t m_totalLarvaeCount; 108 | size_t m_workerCount; 109 | size_t m_workersOnMinerals; 110 | size_t m_workersOnGas; 111 | size_t m_workersMovingToMinerals; 112 | size_t m_workersMovingToGas; 113 | SC2UnitFlags m_unitCompletedFlags; 114 | SC2UnitFlags m_unitUnderConstructionFlags; 115 | CVector m_unitUnderConstruction; 116 | struct SUnitState : public CMemPoolNode 117 | { 118 | size_t unitTypeID; 119 | size_t unitID; 120 | double maxEnergyTime; 121 | SC2UnitStatusFlags status; 122 | }; 123 | class CUnitStateList : public CMemPoolNode 124 | { 125 | public: 126 | CUnitStateList(const CSC2Unit &unit) 127 | : m_unit(unit) 128 | , m_unitList() 129 | { 130 | } 131 | 132 | ~CUnitStateList() 133 | { 134 | } 135 | 136 | size_t size() const { return m_unitList.size(); } 137 | void erase(size_t index, size_t count = 1) { m_unitList.erase(index, count); } 138 | SUnitState *operator[](size_t index) { return m_unitList[index]; } 139 | const SUnitState *operator[](size_t index) const { return m_unitList[index]; } 140 | 141 | double CalculateEnergy(size_t index, double time) const; 142 | void UseEnergy(size_t index, double energy, double time); 143 | 144 | const CSC2Unit &m_unit; 145 | CVector m_unitList; 146 | }; 147 | CVector m_units; 148 | CVector m_allUnits; 149 | 150 | // Research 151 | SC2ResearchFlags m_researchCompletedFlags; 152 | SC2ResearchFlags m_researchUnderConstructionFlags; 153 | CVector m_researchCompleted; 154 | CVector m_researchUnderConstruction; 155 | 156 | // Supply 157 | size_t m_supply; 158 | size_t m_supplyCap; 159 | size_t m_supplyCapUnderConstruction; 160 | }; 161 | -------------------------------------------------------------------------------- /main/SC2/SC2Unit.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "SC2Unit.h" 3 | 4 | CSC2Unit::CSC2Unit() 5 | : m_name() 6 | , m_gameStartCount(0) 7 | , m_isWorker(false) 8 | , m_isUnique(false) 9 | , m_supplyCost(0.0) 10 | , m_providedSupply(0) 11 | , m_mineralIncomeRate(0.0) 12 | , m_expirationTime(0.0) 13 | , m_startingEnergy(0.0) 14 | , m_maxEnergy(0.0) 15 | , m_energyRechargeRate(0.0) 16 | { 17 | } 18 | 19 | bool CSC2Unit::LoadXML(const wxXmlNode *xmlUnit) 20 | { 21 | for(wxXmlNode *child = xmlUnit->GetChildren(); child; child = child->GetNext()) 22 | { 23 | if(wxXML_COMMENT_NODE == child->GetType()) 24 | continue; 25 | 26 | wxString content = child->GetNodeContent(); 27 | if (child->GetName() == wxT("Name")) 28 | { 29 | m_name = content; 30 | } 31 | else if (child->GetName() == wxT("ProvidedSupply")) 32 | { 33 | unsigned long providedSupply; 34 | content.ToULong(&providedSupply); 35 | m_providedSupply = (size_t)providedSupply; 36 | } 37 | else if (child->GetName() == wxT("SupplyCost")) 38 | { 39 | content.ToCDouble(&m_supplyCost); 40 | } 41 | else if (child->GetName() == wxT("IsWorker")) 42 | { 43 | if(content == "True") 44 | m_isWorker = true; 45 | else 46 | m_isWorker = false; 47 | } 48 | else if (child->GetName() == wxT("IsUnique")) 49 | { 50 | if(content == "True") 51 | m_isUnique = true; 52 | else 53 | m_isUnique = false; 54 | } 55 | else if (child->GetName() == wxT("StartingEnergy")) 56 | { 57 | content.ToCDouble(&m_startingEnergy); 58 | } 59 | else if (child->GetName() == wxT("MaxEnergy")) 60 | { 61 | content.ToCDouble(&m_maxEnergy); 62 | } 63 | else if (child->GetName() == wxT("EnergyRechargeRate")) 64 | { 65 | content.ToCDouble(&m_energyRechargeRate); 66 | } 67 | else if (child->GetName() == wxT("GameStartCount")) 68 | { 69 | unsigned long gameStartCount; 70 | content.ToULong(&gameStartCount); 71 | m_gameStartCount = (size_t)gameStartCount; 72 | } 73 | else if (child->GetName() == wxT("MineralIncomeRate")) 74 | { 75 | content.ToCDouble(&m_mineralIncomeRate); 76 | } 77 | else if (child->GetName() == wxT("ExpirationTime")) 78 | { 79 | content.ToCDouble(&m_expirationTime); 80 | } 81 | else 82 | { 83 | wxFAIL_MSG(wxString::Format("Unexpected XML tag in : '%s'", child->GetName())); 84 | return false; 85 | } 86 | } 87 | 88 | return true; 89 | } 90 | 91 | -------------------------------------------------------------------------------- /main/SC2/SC2Unit.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../Core/Vector.h" 6 | 7 | class CSC2Unit 8 | { 9 | public: 10 | CSC2Unit(); 11 | ~CSC2Unit() {} 12 | 13 | bool LoadXML(const wxXmlNode *xmlRace); 14 | 15 | const wxString &GetName() const { return m_name; } 16 | size_t GetGameStartCount() const { return m_gameStartCount; } 17 | bool IsWorker() const { return m_isWorker; } 18 | bool IsUnique() const { return m_isUnique; } 19 | size_t GetProvidedSupply() const { return m_providedSupply; } 20 | double GetSupplyCost() const { return m_supplyCost; } 21 | double GetStartingEnergy() const { return m_startingEnergy; } 22 | double GetMaxEnergy() const { return m_maxEnergy; } 23 | double GetEnergyRechargeRate() const { return m_energyRechargeRate; } 24 | double GetMineralIncomeRate() const { return m_mineralIncomeRate; } 25 | double GetExpirationTime() const { return m_expirationTime; } 26 | 27 | protected: 28 | wxString m_name; 29 | size_t m_gameStartCount; 30 | bool m_isWorker; 31 | bool m_isUnique; 32 | double m_supplyCost; 33 | size_t m_providedSupply; 34 | double m_mineralIncomeRate; 35 | double m_expirationTime; 36 | double m_startingEnergy; 37 | double m_maxEnergy; 38 | double m_energyRechargeRate; 39 | }; 40 | -------------------------------------------------------------------------------- /main/SC2/SC2Version.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #include 4 | 5 | #include "SC2Version.h" 6 | 7 | CSC2Version::CSC2Version() 8 | { 9 | } 10 | 11 | CSC2Version::~CSC2Version() 12 | { 13 | RemoveAllPointer(m_races); 14 | } 15 | 16 | bool CSC2Version::Load(const wxString &fileName) 17 | { 18 | wxXmlDocument doc; 19 | if(!doc.Load(fileName)) 20 | return false; 21 | 22 | wxXmlNode *node = doc.GetRoot()->GetChildren(); 23 | while(node) 24 | { 25 | if(node->GetName() == wxT("XMLFileVersion")) 26 | { 27 | } 28 | else if(node->GetName() == wxT("GameShortDescription")) 29 | { 30 | m_gameShortDescription = node->GetNodeContent(); 31 | } 32 | else if(node->GetName() == wxT("GameLongDescription")) 33 | { 34 | m_gameLongDescription = node->GetNodeContent(); 35 | } 36 | else if(node->GetName() == wxT("MinVersion")) 37 | { 38 | m_minVersion = node->GetNodeContent(); 39 | } 40 | else if(node->GetName() == wxT("Races")) 41 | { 42 | wxXmlNode *raceChild = node->GetChildren(); 43 | while(raceChild) 44 | { 45 | CSC2RaceInfo *raceData = new CSC2RaceInfo(); 46 | if(!raceData->LoadXML(raceChild)) 47 | { 48 | delete raceData; 49 | return false; 50 | } 51 | 52 | m_races.push_back(raceData); 53 | 54 | raceChild = raceChild->GetNext(); 55 | } 56 | } 57 | else 58 | { 59 | wxFAIL_MSG(wxString::Format("Unexpected XML tag in : '%s'", node->GetName())); 60 | return false; 61 | } 62 | 63 | node = node->GetNext(); 64 | } 65 | 66 | return true; 67 | } 68 | 69 | const CSC2RaceInfo *CSC2Version::GetRace(const wxString &name) const 70 | { 71 | for(size_t i=0; i < m_races.size(); i++) 72 | { 73 | if(m_races[i]->GetName() == name) 74 | return m_races[i]; 75 | } 76 | 77 | return NULL; 78 | } -------------------------------------------------------------------------------- /main/SC2/SC2Version.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Core/Vector.h" 4 | 5 | #include "SC2RaceInfo.h" 6 | 7 | class CSC2Version 8 | { 9 | public: 10 | CSC2Version(); 11 | ~CSC2Version(); 12 | 13 | bool Load(const wxString &fileName); 14 | 15 | const wxString &GetGameShortDescription() const { return m_gameShortDescription; } 16 | const wxString &GetGameLongDescription() const { return m_gameLongDescription; } 17 | const wxString &GetMinGameVersion() const { return m_minVersion; } 18 | const CSC2RaceInfo *GetRace(const wxString &name) const; 19 | 20 | protected: 21 | wxString m_gameShortDescription; 22 | wxString m_gameLongDescription; 23 | wxString m_minVersion; 24 | 25 | CVector m_races; 26 | }; 27 | -------------------------------------------------------------------------------- /main/SC2/SC2Waypoint.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../GA/GAEngine.h" 4 | #include "../GA/GASequenceChromosome.h" 5 | #include "FitnessValue.h" 6 | #include "SC2Command.h" 7 | #include "SC2State.h" 8 | #include "GasMicro.h" 9 | #include "TargetMinMax.h" 10 | #include "SC2RaceInfo.h" 11 | 12 | class CSC2Waypoint 13 | { 14 | public: 15 | CSC2Waypoint(const CSC2RaceInfo &raceInfo, bool finalTarget = false); 16 | ~CSC2Waypoint() {} 17 | 18 | void SetDefaults(); 19 | 20 | double targetValue(const CSC2State &state, bool bSatisfied) const; 21 | double targetTimePenalty(const CSC2State &state) const; 22 | void AddExtraValue(CFitnessValue &fitness, const CSC2State &state) const; 23 | 24 | void AddStateDuration(CFitnessValue &fitness, const CSC2State &state, double time) const; 25 | 26 | bool hasTarget() const; 27 | bool satisfiesTarget(const CSC2State &state) const; 28 | 29 | void AddRequirements(); 30 | void RestrictRequirements(); 31 | 32 | void operator+=(const CSC2Waypoint &target); 33 | 34 | void DoPreCalculation(); 35 | void BuildAlphabet(CVector &alphabet, EGasMicro gasMicro) const; 36 | 37 | bool IsFinalTarget() const; 38 | 39 | const CSC2RaceInfo &m_raceInfo; 40 | const bool m_final_target; 41 | 42 | // State 43 | CDoubleMinMax m_targetTime; 44 | CSizeTOptionalMinMax m_supplyCount; 45 | CSizeTOptionalMinMax m_baseCount; 46 | CSizeTOptionalMinMax m_baseUnderConstructionCount; 47 | 48 | // Resources 49 | double m_minerals; 50 | double m_gas; 51 | double m_mineralsMined; 52 | double m_gasMined; 53 | 54 | // Targets 55 | struct STargetRequirement 56 | { 57 | STargetRequirement(const CSC2Target *target = NULL, size_t count = 0) : m_target(target), m_count(count) {} 58 | ~STargetRequirement() {} 59 | 60 | const CSC2Target *m_target; 61 | size_t m_count; 62 | }; 63 | CVector m_minRequirements; 64 | CVector m_maxRequirements; 65 | CVector m_minUnderConstructionRequirements; 66 | CVector m_maxUnderConstructionRequirements; 67 | 68 | CVector m_stateDurationRequirements; 69 | 70 | protected: 71 | SC2BuildingFlags m_buildingMinRequirements; 72 | SC2BuildingFlags m_buildingMaxRequirements; 73 | CVector m_buildingStatusMinRequirements; 74 | CVector m_buildingStatusMaxRequirements; 75 | SC2UnitFlags m_unitMinRequirements; 76 | SC2UnitFlags m_unitMaxRequirements; 77 | SC2ResearchFlags m_researchMinRequirements; 78 | SC2ResearchFlags m_researchMaxRequirements; 79 | 80 | WX_DECLARE_HASH_MAP(const CSC2Target *, size_t, wxPointerHash, wxPointerEqual, wxHashMapSC2TargetToCount); 81 | }; 82 | -------------------------------------------------------------------------------- /main/SC2/TargetMinMax.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "TargetMinMax.h" 3 | 4 | template<> 5 | bool CTargetMinMax::IsWithinRange(bool value) const 6 | { 7 | return min <= value && value <= max; 8 | } 9 | -------------------------------------------------------------------------------- /main/SC2/TargetMinMax.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | class CTargetMinMax 5 | { 6 | public: 7 | TVal min; 8 | TVal max; 9 | 10 | CTargetMinMax() : min(0), max(0) {} 11 | CTargetMinMax(TVal _min, TVal _max) : min(_min), max(_max) {} 12 | ~CTargetMinMax() {} 13 | 14 | inline const TVal &GetValue(bool getMax) const { return getMax ? max : min; } 15 | inline bool IsWithinRange(TVal val) const { return min <= val && val <= max; } 16 | inline void Combine(const CTargetMinMax &value) { min = mymax(min, value.min); max = mymax(max, value.max); } 17 | 18 | double GetRequirementValue(TVal stateVal, double valuePerUnit) const 19 | { 20 | if(stateVal <= min) 21 | return stateVal * valuePerUnit; 22 | else if(stateVal > max) 23 | return (min + max - (double)stateVal) * valuePerUnit; 24 | else 25 | return min * valuePerUnit; 26 | } 27 | }; 28 | 29 | //template<> 30 | //bool CTargetMinMax::IsWithinRange(bool value) const; 31 | 32 | typedef CTargetMinMax CSizeTMinMax; 33 | typedef CTargetMinMax CDoubleMinMax; 34 | typedef CTargetMinMax CBoolMinMax; 35 | 36 | 37 | template 38 | class CTargetOptionalMinMax 39 | { 40 | public: 41 | bool haveMin; 42 | bool haveMax; 43 | TVal min; 44 | TVal max; 45 | 46 | CTargetOptionalMinMax() : haveMin(false), haveMax(false), min(0), max(0) {} 47 | CTargetOptionalMinMax(TVal _min, TVal _max) : min(_min), max(_max) {} 48 | ~CTargetOptionalMinMax() {} 49 | 50 | inline bool IsWithinRange(TVal val) const { return (!haveMin || min <= val) && (!haveMax || val <= max); } 51 | inline void Combine(const CTargetMinMax &value) { haveMin ||= value.haveMin; min = mymax(min, value.min); haveMax ||= value.haveMax; max = mymax(max, value.max); } 52 | 53 | double GetRequirementValue(TVal stateVal, double valuePerUnit) const 54 | { 55 | if(stateVal <= min) 56 | return stateVal * valuePerUnit; 57 | else if(stateVal > max) 58 | return (min + max - (double)stateVal) * valuePerUnit; 59 | else 60 | return min * valuePerUnit; 61 | } 62 | }; 63 | 64 | typedef CTargetOptionalMinMax CSizeTOptionalMinMax; 65 | typedef CTargetOptionalMinMax CDoubleOptionalMinMax; 66 | typedef CTargetOptionalMinMax CBoolOptionalMinMax; 67 | -------------------------------------------------------------------------------- /main/SCFusion.aps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrew-j-armstrong/SCFusion/d2e248e0f21194b10aa0f0bf64b93f715675534a/main/SCFusion.aps -------------------------------------------------------------------------------- /main/SCFusion.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrew-j-armstrong/SCFusion/d2e248e0f21194b10aa0f0bf64b93f715675534a/main/SCFusion.rc -------------------------------------------------------------------------------- /main/SCFusion_vc10.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SCFusion", "SCFusion_vc10.vcxproj", "{9F028A49-3F1C-527D-8A3B-B02716C5851E}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | DLL Debug|Win32 = DLL Debug|Win32 10 | DLL Release|Win32 = DLL Release|Win32 11 | DLL Universal Debug|Win32 = DLL Universal Debug|Win32 12 | DLL Universal Release|Win32 = DLL Universal Release|Win32 13 | Release|Win32 = Release|Win32 14 | Universal Debug|Win32 = Universal Debug|Win32 15 | Universal Release|Win32 = Universal Release|Win32 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {9F028A49-3F1C-527D-8A3B-B02716C5851E}.Debug|Win32.ActiveCfg = Debug|Win32 19 | {9F028A49-3F1C-527D-8A3B-B02716C5851E}.Debug|Win32.Build.0 = Debug|Win32 20 | {9F028A49-3F1C-527D-8A3B-B02716C5851E}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 21 | {9F028A49-3F1C-527D-8A3B-B02716C5851E}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 22 | {9F028A49-3F1C-527D-8A3B-B02716C5851E}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 23 | {9F028A49-3F1C-527D-8A3B-B02716C5851E}.DLL Release|Win32.Build.0 = DLL Release|Win32 24 | {9F028A49-3F1C-527D-8A3B-B02716C5851E}.DLL Universal Debug|Win32.ActiveCfg = DLL Universal Debug|Win32 25 | {9F028A49-3F1C-527D-8A3B-B02716C5851E}.DLL Universal Debug|Win32.Build.0 = DLL Universal Debug|Win32 26 | {9F028A49-3F1C-527D-8A3B-B02716C5851E}.DLL Universal Release|Win32.ActiveCfg = DLL Universal Release|Win32 27 | {9F028A49-3F1C-527D-8A3B-B02716C5851E}.DLL Universal Release|Win32.Build.0 = DLL Universal Release|Win32 28 | {9F028A49-3F1C-527D-8A3B-B02716C5851E}.Release|Win32.ActiveCfg = Release|Win32 29 | {9F028A49-3F1C-527D-8A3B-B02716C5851E}.Release|Win32.Build.0 = Release|Win32 30 | {9F028A49-3F1C-527D-8A3B-B02716C5851E}.Universal Debug|Win32.ActiveCfg = Universal Debug|Win32 31 | {9F028A49-3F1C-527D-8A3B-B02716C5851E}.Universal Debug|Win32.Build.0 = Universal Debug|Win32 32 | {9F028A49-3F1C-527D-8A3B-B02716C5851E}.Universal Release|Win32.ActiveCfg = Universal Release|Win32 33 | {9F028A49-3F1C-527D-8A3B-B02716C5851E}.Universal Release|Win32.Build.0 = Universal Release|Win32 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | EndGlobal 39 | -------------------------------------------------------------------------------- /main/SCFusion_vc10.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /main/SampleSaveFile.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.0 4 | Starcraft II: Heart of the Swarm 5 | 2.0.7 6 | Protoss 7 | 8 | 1000 9 | 150 10 | Three to gas only 11 | False 12 | 300 13 | 14 | Build Probe 15 | Build Probe 16 | Build Probe 17 | Build Pylon 18 | Build Probe 19 | 20 | 21 | 22 | 23 | 300 24 | 25 | 100 26 | 27 | 28 | 9 29 | 30 | 31 | 32 | 300 33 | 34 | 12 35 | 1 36 | 37 | 38 | 5 39 | 40 | 41 | Required 42 | 43 | 44 | 45 | 46 | Build Probe 47 | Chrono Boost Nexus 48 | Build Probe 49 | Build Pylon 50 | Build Probe 51 | Build Gateway 52 | Build Probe 53 | Build Assimilator 54 | Build Probe 55 | Move Three Probes To Gas 56 | Build Probe 57 | Build Cybernetics Core 58 | Build Gateway 59 | Build Pylon 60 | Build Stalker 61 | Research Warp Gate Transformation 62 | Chrono Boost Cybernetics Core 63 | Build Stalker 64 | Build Stalker 65 | Chrono Boost Cybernetics Core 66 | Build Pylon 67 | Build Stalker 68 | Build Stalker 69 | Chrono Boost Cybernetics Core 70 | Chrono Boost Cybernetics Core 71 | Build Probe 72 | Chrono Boost Cybernetics Core 73 | Build Probe 74 | Chrono Boost Cybernetics Core 75 | Build Probe 76 | 77 | -------------------------------------------------------------------------------- /main/SampleSaveFile2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.0 4 | Starcraft II: Heart of the Swarm 5 | 2.0.7 6 | Zerg 7 | 8 | 1200 9 | Three to gas only 10 | False 11 | 12 | 13 | 14 | 15 | 5 16 | 17 | 18 | 19 | 20 | Build Spawning Pool 21 | Build Drone 22 | Build Drone 23 | Build Zergling 24 | Build Zergling 25 | Build Zergling 26 | Build Macro Hatchery 27 | 28 | 29 | -------------------------------------------------------------------------------- /main/TimeTextCtrl.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "TimeTextCtrl.h" 3 | 4 | wxTimeTextCtrl::wxTimeTextCtrl() 5 | : wxTextCtrl() 6 | { 7 | } 8 | 9 | wxTimeTextCtrl::wxTimeTextCtrl(wxWindow *parent, 10 | wxWindowID id, 11 | const wxString& value /* = wxEmptyString */, 12 | const wxPoint& pos /* = wxDefaultPosition */, 13 | const wxSize& size /* = wxDefaultSize */, 14 | long style /* = 0 */, 15 | const wxValidator& validator /* = wxDefaultValidator */, 16 | const wxString& name /* = wxTextCtrlNameStr */) 17 | : wxTextCtrl(parent, id, value, pos, size, style, validator, name) 18 | , m_time(0.0) 19 | { 20 | } 21 | 22 | void wxTimeTextCtrl::OnKillFocus(wxFocusEvent& event) 23 | { 24 | wxString value = GetValue().Trim(false).Trim(true); 25 | int minutesSep = value.Find(":"); 26 | if(-1 != minutesSep) 27 | { 28 | double minutes; 29 | value.SubString(0, minutesSep).Trim(false).Trim(true).ToDouble(&minutes); 30 | value.SubString(minutesSep+1, value.Length()).Trim(false).Trim(true).ToDouble(&m_time); 31 | m_time += minutes * 60.0; 32 | } 33 | else 34 | value.Trim(false).Trim(true).ToDouble(&m_time); 35 | 36 | int nDecimalPlaces = 0; 37 | ChangeValue(wxString::Format(wxString::Format("%d:%%0%d.%df", (int)(m_time/60), nDecimalPlaces == 0 ? 2 : (nDecimalPlaces + 3), nDecimalPlaces), m_time - 60*(int)(m_time/60))); 38 | } 39 | -------------------------------------------------------------------------------- /main/TimeTextCtrl.h: -------------------------------------------------------------------------------- 1 | #ifndef TIMETEXTCTRL_H 2 | #define TIMETEXTCTRL_H 3 | 4 | class wxTimeTextCtrl : public wxTextCtrl 5 | { 6 | public: 7 | wxTimeTextCtrl(); 8 | 9 | wxTimeTextCtrl(wxWindow *parent, 10 | wxWindowID id, 11 | const wxString& value = wxEmptyString, 12 | const wxPoint& pos = wxDefaultPosition, 13 | const wxSize& size = wxDefaultSize, 14 | long style = 0, 15 | const wxValidator& validator = wxDefaultValidator, 16 | const wxString& name = wxTextCtrlNameStr); 17 | 18 | virtual ~wxTimeTextCtrl() {} 19 | 20 | protected: 21 | virtual void OnKillFocus(wxFocusEvent& event); 22 | 23 | double m_time; 24 | }; 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /main/TimeValidator.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "TimeValidator.h" 3 | #include "SC2Engine.h" 4 | 5 | bool CTimeValidator::TransferFromWindow() 6 | { 7 | wxString s; 8 | 9 | try 10 | { 11 | wxTextCtrl *text = dynamic_cast(m_validatorWindow); 12 | s = text->GetValue(); 13 | } 14 | catch(...) 15 | { 16 | wxFAIL_MSG( _T("CTimeValidator works only with wxTextCtrl")); 17 | return false; 18 | } 19 | 20 | if(!CSC2Engine::InterpretTimeValue(s, m_value)) 21 | return false; 22 | 23 | return true; 24 | } 25 | 26 | bool CTimeValidator::TransferToWindow() 27 | { 28 | try 29 | { 30 | wxTextCtrl *text = dynamic_cast(m_validatorWindow); 31 | text->ChangeValue(CSC2Engine::TimeToString(m_value, m_decimalPlaces)); 32 | } 33 | catch(...) 34 | { 35 | wxFAIL_MSG( _T("CTimeValidator works only with wxTextCtrl")); 36 | return false; 37 | } 38 | 39 | return true; 40 | } 41 | 42 | bool CTimeValidator::Validate(wxWindow *parent) 43 | { 44 | wxString s; 45 | 46 | try 47 | { 48 | wxTextCtrl *text = dynamic_cast(m_validatorWindow); 49 | s = text->GetValue(); 50 | } 51 | catch(...) 52 | { 53 | wxFAIL_MSG( _T("CTimeValidator works only with wxTextCtrl")); 54 | return false; 55 | } 56 | 57 | double value; 58 | return CSC2Engine::InterpretTimeValue(s, value); 59 | } 60 | -------------------------------------------------------------------------------- /main/TimeValidator.h: -------------------------------------------------------------------------------- 1 | #ifndef TIMEVALIDATOR_H 2 | #define TIMEVALIDATOR_H 3 | 4 | #include 5 | 6 | class CTimeValidator : public wxValidator 7 | { 8 | public: 9 | CTimeValidator(double &value, int decimalPlaces = 0) : wxValidator(), m_value(value), m_decimalPlaces(decimalPlaces) {} 10 | CTimeValidator(const CTimeValidator &validator) : wxValidator(), m_value(validator.GetValue()), m_decimalPlaces(validator.GetDecimalPlaces()) { Copy(validator); } 11 | ~CTimeValidator() {} 12 | 13 | wxObject *Clone() const { return new CTimeValidator(*this); } 14 | bool TransferFromWindow(); 15 | bool TransferToWindow(); 16 | bool Validate(wxWindow *parent); 17 | 18 | double &GetValue() const { return m_value; } 19 | int GetDecimalPlaces() const { return m_decimalPlaces; } 20 | 21 | protected: 22 | double &m_value; 23 | int m_decimalPlaces; 24 | }; 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /main/VisualItem.cpp: -------------------------------------------------------------------------------- 1 | #include "VisualItem.h" 2 | 3 | #include 4 | 5 | VisualItem::VisualItem(wxString name, double startTime, double endTime, VisualItemType itemType, QueueType queueType) 6 | { 7 | this->startTime = startTime; 8 | this->endTime = endTime; 9 | this->name = name; 10 | this->itemType = itemType; 11 | this->queueType = queueType; 12 | } -------------------------------------------------------------------------------- /main/bitmaps/P.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrew-j-armstrong/SCFusion/d2e248e0f21194b10aa0f0bf64b93f715675534a/main/bitmaps/P.gif -------------------------------------------------------------------------------- /main/bitmaps/Protoss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrew-j-armstrong/SCFusion/d2e248e0f21194b10aa0f0bf64b93f715675534a/main/bitmaps/Protoss.png -------------------------------------------------------------------------------- /main/bitmaps/Protoss.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char *Protoss_xpm[] = { 3 | /* columns rows colors chars-per-pixel */ 4 | "16 16 82 1 ", 5 | " c None", 6 | ". c #937853", 7 | "X c #AD883B", 8 | "o c #B18F36", 9 | "O c #B39238", 10 | "+ c #C39D33", 11 | "@ c #C89D33", 12 | "# c #DBAA27", 13 | "$ c #DEB43B", 14 | "% c #E0B434", 15 | "& c #8F8256", 16 | "* c #B09540", 17 | "= c #B39044", 18 | "- c #BF934A", 19 | "; c #AE9370", 20 | ": c #BA9D7D", 21 | "> c #AEA061", 22 | ", c #AFA963", 23 | "< c #B8A363", 24 | "1 c #B6AF6A", 25 | "2 c #B7A37F", 26 | "3 c #C89546", 27 | "4 c #C9A847", 28 | "5 c #CBA04F", 29 | "6 c #C8A053", 30 | "7 c #D1A35F", 31 | "8 c #CEB956", 32 | "9 c #D2B558", 33 | "0 c #C5AB77", 34 | "q c #C8B879", 35 | "w c #DBC151", 36 | "e c #E2C244", 37 | "r c #EEC94E", 38 | "t c #E2CA54", 39 | "y c #E3CC55", 40 | "u c #DAC876", 41 | "i c #DDCE76", 42 | "p c #F0D868", 43 | "a c #7AA3A2", 44 | "s c #7CB7C3", 45 | "d c #68BEF9", 46 | "f c #6ED1F7", 47 | "g c #A79B87", 48 | "h c #83B2B9", 49 | "j c #C3BC82", 50 | "k c #D1BDA4", 51 | "l c #9DC3A7", 52 | "z c #D6CA88", 53 | "x c #D5C79B", 54 | "c c #E1C291", 55 | "v c #F5E981", 56 | "b c #D6C9A0", 57 | "n c #D3C0AB", 58 | "m c #DBD4A5", 59 | "M c #D2CABF", 60 | "N c #D4D2B1", 61 | "B c #D9D1BA", 62 | "V c #D7CDC0", 63 | "C c #D5CFC4", 64 | "Z c #D7D3C3", 65 | "A c #D5D2C4", 66 | "S c #D5D3C4", 67 | "D c #D9D2C4", 68 | "F c #DCD6D2", 69 | "G c #E4D2C0", 70 | "H c #E0D9CA", 71 | "J c #E2DDD5", 72 | "K c #E3DED4", 73 | "L c #E2DED7", 74 | "P c #EDE7D7", 75 | "I c #E6E3DB", 76 | "U c #E7E2DC", 77 | "Y c #E5E3DF", 78 | "T c #EBE6DD", 79 | "R c #DCE5E6", 80 | "E c #DCE5F0", 81 | "W c #DFE9F0", 82 | "Q c #E5E4E3", 83 | "! c #E6E5E2", 84 | "~ c #E9E6E3", 85 | "^ c #EBE7E2", 86 | "/ c #E9E7E4", 87 | /* pixels */ 88 | " L ", 89 | " VG ", 90 | " M7 ", 91 | " Zwc ", 92 | " S*;U UT ", 93 | " SOL!b 0 ", 94 | " D8x 4H = ", 95 | " Rh>u c #E90066", 22 | ", c #EA0066", 23 | "< c #ED0066", 24 | "1 c #EE0066", 25 | "2 c #F10066", 26 | "3 c #F20066", 27 | "4 c #F50066", 28 | "5 c #F80066", 29 | "6 c #FA0066", 30 | "7 c #FB0066", 31 | "8 c #FD0066", 32 | "9 c #FF0066", 33 | /* pixels */ 34 | " 888888", 35 | " 888888", 36 | " 866886", 37 | " 466 ", 38 | " 444 ", 39 | "222222222 22222 ", 40 | "<<<<<2<<< 2<<<< ", 41 | ">>>>>>>>> >>>>> ", 42 | ";;; ;;; ", 43 | "--------- --- ", 44 | "********* *** ", 45 | "%%%%%%%%% %%% ", 46 | " $$$ $$$ ", 47 | "+++++++++ +$+ ", 48 | ".++.++.++ +.+ ", 49 | "......... ... " 50 | }; 51 | -------------------------------------------------------------------------------- /main/bitmaps/SF32.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char *SF32Icon[] = { 3 | /* columns rows colors chars-per-pixel */ 4 | "32 32 53 1 ", 5 | " c None", 6 | ". c #CC0066", 7 | "X c #CD0066", 8 | "o c #CE0066", 9 | "O c #CF0066", 10 | "+ c #D00066", 11 | "@ c #D10066", 12 | "# c #D20066", 13 | "$ c #D30066", 14 | "% c #D40066", 15 | "& c #D50066", 16 | "* c #D60066", 17 | "= c #D70066", 18 | "- c #D80066", 19 | "; c #D90066", 20 | ": c #DA0066", 21 | "> c #DB0066", 22 | ", c #DC0066", 23 | "< c #DD0066", 24 | "1 c #DE0066", 25 | "2 c #DF0066", 26 | "3 c #E00066", 27 | "4 c #E10066", 28 | "5 c #E20066", 29 | "6 c #E30066", 30 | "7 c #E40066", 31 | "8 c #E50066", 32 | "9 c #E60066", 33 | "0 c #E70066", 34 | "q c #E80066", 35 | "w c #E90066", 36 | "e c #EA0066", 37 | "r c #EB0066", 38 | "t c #EC0066", 39 | "y c #ED0066", 40 | "u c #EE0066", 41 | "i c #EF0066", 42 | "p c #F00066", 43 | "a c #F10066", 44 | "s c #F20066", 45 | "d c #F30066", 46 | "f c #F40066", 47 | "g c #F50066", 48 | "h c #F60066", 49 | "j c #F70066", 50 | "k c #F80066", 51 | "l c #F90066", 52 | "z c #FA0066", 53 | "x c #FB0066", 54 | "c c #FC0066", 55 | "v c #FD0066", 56 | "b c #FE0066", 57 | "n c #FF0066", 58 | /* pixels */ 59 | " cccccccccccc", 60 | " cccccccccccc", 61 | " cccccccccccc", 62 | " ccxxcccccccc", 63 | " xxxxxxxxcxxx", 64 | " xxxhhxxxxxhx", 65 | " hxhxhx ", 66 | " hhhhhh ", 67 | " hhhhah ", 68 | " aaaaha ", 69 | "aaaaaaaiaaaaaaaaaa aaaaaaaaaa ", 70 | "iiiiiiiiiaiiiiiiii iaiiiaiiia ", 71 | "iieiieiiiiiiieiiii iieieiiiii ", 72 | "eeieeeeeeeieieeeee eeeeeeeeee ", 73 | "eeeeee0eee0eeeeeee ee0eeeeeee ", 74 | "0e00e00e0e00000000 0e00e0e000 ", 75 | "400040 000004 ", 76 | "404400 404004 ", 77 | "444444444444444444 444444 ", 78 | "442242222424442442 222222 ", 79 | "22222222222;222222 22222; ", 80 | ";2;;;2;;;2;2;2;;;; 2;;2;2 ", 81 | ";;;;;;;;;;;;;;;;;; ;;;;;; ", 82 | ";;;;;;;;;;=;=;;;;; ;=;;;; ", 83 | " ===#== ====;= ", 84 | " =#==#= #=#=#= ", 85 | "##=####==######### ###### ", 86 | "##O###O########### ###### ", 87 | "#OOO##O#OO#OO#OOO# OO#OO# ", 88 | "OOOOOOOOOOOOOOOOOO OOOOOO ", 89 | "OOO..OOO.OO.OOOOOO O.OOOO ", 90 | "...O.O...O..O....O O....O " 91 | }; 92 | -------------------------------------------------------------------------------- /main/bitmaps/T.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrew-j-armstrong/SCFusion/d2e248e0f21194b10aa0f0bf64b93f715675534a/main/bitmaps/T.gif -------------------------------------------------------------------------------- /main/bitmaps/Terran.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrew-j-armstrong/SCFusion/d2e248e0f21194b10aa0f0bf64b93f715675534a/main/bitmaps/Terran.png -------------------------------------------------------------------------------- /main/bitmaps/Terran.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char *Terran_xpm[] = { 3 | /* columns rows colors chars-per-pixel */ 4 | "16 16 137 2 ", 5 | " c None", 6 | ". c #2D2317", 7 | "X c #2E2319", 8 | "o c #2B241B", 9 | "O c #28241E", 10 | "+ c #29251F", 11 | "@ c #2F241E", 12 | "# c #3A2019", 13 | "$ c #3C201A", 14 | "% c #292622", 15 | "& c #3C2623", 16 | "* c #4C1814", 17 | "= c #4D1E17", 18 | "- c #5A1D16", 19 | "; c #5B1D1B", 20 | ": c #6F1011", 21 | "> c #6C1213", 22 | ", c #611D15", 23 | "< c #6D1A1A", 24 | "1 c #761112", 25 | "2 c #751415", 26 | "3 c #7E1316", 27 | "4 c #7C1518", 28 | "5 c #761B1D", 29 | "6 c #7A181A", 30 | "7 c #442013", 31 | "8 c #442118", 32 | "9 c #442618", 33 | "0 c #47261A", 34 | "q c #4A271A", 35 | "w c #472B1F", 36 | "e c #68281F", 37 | "r c #771E21", 38 | "t c #4A2D21", 39 | "y c #582722", 40 | "u c #5C2522", 41 | "i c #512C21", 42 | "p c #522F21", 43 | "a c #5E2E23", 44 | "s c #5C2B24", 45 | "d c #5A2E25", 46 | "f c #493223", 47 | "g c #403329", 48 | "h c #41342E", 49 | "j c #503226", 50 | "k c #543024", 51 | "l c #563324", 52 | "z c #5E3220", 53 | "x c #5B362B", 54 | "c c #593B2D", 55 | "v c #6E2A28", 56 | "b c #7B2527", 57 | "n c #7D2524", 58 | "m c #6E332C", 59 | "M c #623D2A", 60 | "N c #613D2C", 61 | "B c #603D34", 62 | "V c #574237", 63 | "C c #5F4133", 64 | "Z c #57443A", 65 | "A c #634032", 66 | "S c #6C4737", 67 | "D c #6A4E41", 68 | "F c #7C4E4A", 69 | "G c #665342", 70 | "H c #920C0F", 71 | "J c #860D10", 72 | "K c #801314", 73 | "L c #891418", 74 | "P c #891419", 75 | "I c #81181C", 76 | "U c #891C1F", 77 | "Y c #8F1F1F", 78 | "T c #92191D", 79 | "R c #841F21", 80 | "E c #911F22", 81 | "W c #A61D21", 82 | "Q c #BA1A21", 83 | "! c #BF1A20", 84 | "~ c #BF1A21", 85 | "^ c #832722", 86 | "/ c #812727", 87 | "( c #8F2225", 88 | ") c #852C24", 89 | "_ c #832729", 90 | "` c #802F29", 91 | "' c #8D282C", 92 | "] c #982E2E", 93 | "[ c #843126", 94 | "{ c #813133", 95 | "} c #8D3830", 96 | "| c #80373B", 97 | " . c #8B3939", 98 | ".. c #963D36", 99 | "X. c #A52728", 100 | "o. c #B32326", 101 | "O. c #A62A31", 102 | "+. c #A12E30", 103 | "@. c #AA2F30", 104 | "#. c #BD2730", 105 | "$. c #BD2A34", 106 | "%. c #A8373C", 107 | "&. c #C23035", 108 | "*. c #A03C40", 109 | "=. c #B13D45", 110 | "-. c #B23E46", 111 | ";. c #BA3C41", 112 | ":. c #C63846", 113 | ">. c #834A4C", 114 | ",. c #92494C", 115 | "<. c #865149", 116 | "1. c #A94448", 117 | "2. c #A8494C", 118 | "3. c #AB484E", 119 | "4. c #B0464A", 120 | "5. c #B34B4F", 121 | "6. c #A15153", 122 | "7. c #AE5D5D", 123 | "8. c #B15155", 124 | "9. c #BF5358", 125 | "0. c #BA5B5F", 126 | "q. c #9C7272", 127 | "w. c #9E7D7D", 128 | "e. c #9F7F7E", 129 | "r. c #A37170", 130 | "t. c #A07574", 131 | "y. c #A97C7D", 132 | "u. c #9C8281", 133 | "i. c #A18082", 134 | "p. c #A08282", 135 | "a. c #A49394", 136 | "s. c #C69093", 137 | "d. c #C69B9E", 138 | "f. c #C7ADAF", 139 | "g. c #CBB3B5", 140 | "h. c #DED3D4", 141 | "j. c #DCD5D6", 142 | /* pixels */ 143 | " j.s.8.9.d.h. ", 144 | " g.0.] ) M N [ @.5.f. ", 145 | " 2.D j v 6.7.<.G S *. ", 146 | " E c O.o.2.1.:.-.A . ", 147 | " ' x $.;.V Z 4.#.A _ ", 148 | " { l -.&...} %.+.f _ ", 149 | " 6 t F X.! Q ! s . 4 ", 150 | " r 0 y h Y W ^ @ $ 3 ", 151 | " >.q < o X g % # e 5 ", 152 | " ,.w I ; + % B U z b ", 153 | " ( d a P * = T ` p | ", 154 | " y.P 8 u J H m i R a. ", 155 | " r.2 & - , l n i. ", 156 | " u.1 7 9 K t. ", 157 | " w.: > q. ", 158 | " i.w. " 159 | }; 160 | -------------------------------------------------------------------------------- /main/bitmaps/Z.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrew-j-armstrong/SCFusion/d2e248e0f21194b10aa0f0bf64b93f715675534a/main/bitmaps/Z.gif -------------------------------------------------------------------------------- /main/bitmaps/Z.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char * Z_xpm[] = { 3 | "25 25 227 2", 4 | " c None", 5 | ". c #000000", 6 | "+ c #FFFFFF", 7 | "@ c #8F282A", 8 | "# c #210405", 9 | "$ c #812125", 10 | "% c #510E12", 11 | "& c #491317", 12 | "* c #200407", 13 | "= c #641A21", 14 | "- c #450B13", 15 | "; c #330B10", 16 | "> c #6F2731", 17 | ", c #D3929A", 18 | "' c #6C1C28", 19 | ") c #44131A", 20 | "! c #5B1521", 21 | "~ c #C33A53", 22 | "{ c #230C10", 23 | "] c #4E2028", 24 | "^ c #510C19", 25 | "/ c #B22542", 26 | "( c #64202E", 27 | "_ c #1A0B0E", 28 | ": c #090002", 29 | "< c #6A172A", 30 | "[ c #280910", 31 | "} c #712034", 32 | "| c #DA99A9", 33 | "1 c #170007", 34 | "2 c #25050E", 35 | "3 c #7F2540", 36 | "4 c #0C0507", 37 | "5 c #640523", 38 | "6 c #120509", 39 | "7 c #57172E", 40 | "8 c #3D1A27", 41 | "9 c #170009", 42 | "0 c #840E3D", 43 | "a c #663447", 44 | "b c #280212", 45 | "c c #3B1E2A", 46 | "d c #5B092C", 47 | "e c #7F254F", 48 | "f c #671E40", 49 | "g c #DCA4BE", 50 | "h c #6C1940", 51 | "i c #3A1728", 52 | "j c #040002", 53 | "k c #71274C", 54 | "l c #A43A71", 55 | "m c #7F0C4C", 56 | "n c #811C54", 57 | "o c #1C0512", 58 | "p c #4C1736", 59 | "q c #3D0527", 60 | "r c #64234A", 61 | "s c #4E1A3A", 62 | "t c #A94584", 63 | "u c #752A5B", 64 | "v c #AF2C85", 65 | "w c #0B0509", 66 | "x c #3F0B2F", 67 | "y c #983378", 68 | "z c #7F1963", 69 | "A c #561944", 70 | "B c #B04F95", 71 | "C c #251320", 72 | "D c #170713", 73 | "E c #560E47", 74 | "F c #511544", 75 | "G c #A63691", 76 | "H c #CA59B4", 77 | "I c #401338", 78 | "J c #C963B9", 79 | "K c #DC9FD2", 80 | "L c #711364", 81 | "M c #64235C", 82 | "N c #A6429A", 83 | "O c #E0A1D8", 84 | "P c #C16CB9", 85 | "Q c #672863", 86 | "R c #B74EAF", 87 | "S c #280027", 88 | "T c #662364", 89 | "U c #C466C1", 90 | "V c #B666B4", 91 | "W c #050005", 92 | "X c #490E49", 93 | "Y c #B642B6", 94 | "Z c #0C050C", 95 | "` c #B563B4", 96 | " . c #BC6ABB", 97 | ".. c #1E151E", 98 | "+. c #DCA3DC", 99 | "@. c #D9A5D9", 100 | "#. c #E6B4E6", 101 | "$. c #EDBFED", 102 | "%. c #903892", 103 | "&. c #AE4AB0", 104 | "*. c #C35BC4", 105 | "=. c #B85FBA", 106 | "-. c #B45CB5", 107 | ";. c #D186D3", 108 | ">. c #AD59B0", 109 | ",. c #AC5BAF", 110 | "'. c #C771CB", 111 | "). c #C781CB", 112 | "!. c #D089D3", 113 | "~. c #D495D7", 114 | "{. c #DEA0E1", 115 | "]. c #CF9BD2", 116 | "^. c #F0C1F2", 117 | "/. c #A64EAC", 118 | "(. c #824086", 119 | "_. c #AC5BB1", 120 | ":. c #BA67C0", 121 | "<. c #D696DA", 122 | "[. c #DEA8E2", 123 | "}. c #DCB2DF", 124 | "|. c #2F0234", 125 | "1. c #6C1C75", 126 | "2. c #792882", 127 | "3. c #A557AD", 128 | "4. c #B766BF", 129 | "5. c #915796", 130 | "6. c #C88ACE", 131 | "7. c #E4B8E8", 132 | "8. c #962FA4", 133 | "9. c #6C2774", 134 | "0. c #9B4CA5", 135 | "a. c #230228", 136 | "b. c #751386", 137 | "c. c #903B9E", 138 | "d. c #7E3389", 139 | "e. c #AE57BB", 140 | "f. c #AA57B7", 141 | "g. c #B067BC", 142 | "h. c #33103A", 143 | "i. c #662174", 144 | "j. c #5B1E66", 145 | "k. c #B759C9", 146 | "l. c #A451B5", 147 | "m. c #C371D3", 148 | "n. c #3A0B45", 149 | "o. c #471353", 150 | "p. c #9628AD", 151 | "q. c #79238C", 152 | "r. c #7B388A", 153 | "s. c #3B2340", 154 | "t. c #85219E", 155 | "u. c #662377", 156 | "v. c #69257C", 157 | "w. c #280E2F", 158 | "x. c #27152C", 159 | "y. c #270431", 160 | "z. c #25072E", 161 | "A. c #15041A", 162 | "B. c #250C2C", 163 | "C. c #9533B4", 164 | "D. c #882FA1", 165 | "E. c #84389B", 166 | "F. c #1E0E23", 167 | "G. c #9A57AD", 168 | "H. c #884F98", 169 | "I. c #7C159E", 170 | "J. c #49125B", 171 | "K. c #9F38C2", 172 | "L. c #C457E7", 173 | "M. c #B753D9", 174 | "N. c #381A42", 175 | "O. c #782C95", 176 | "P. c #200C28", 177 | "Q. c #913BB2", 178 | "R. c #280C34", 179 | "S. c #9536BD", 180 | "T. c #1C0C23", 181 | "U. c #7207A3", 182 | "V. c #8212B9", 183 | "W. c #7F19B0", 184 | "X. c #8C31BA", 185 | "Y. c #13041C", 186 | "Z. c #751EAA", 187 | "`. c #12021C", 188 | " + c #3D1756", 189 | ".+ c #1A0727", 190 | "++ c #090010", 191 | "@+ c #050009", 192 | "#+ c #0C0512", 193 | "$+ c #0C0415", 194 | "%+ c #000007", 195 | "&+ c #000002", 196 | "*+ c #000905", 197 | "=+ c #000400", 198 | "-+ c #000200", 199 | ";+ c #050900", 200 | ">+ c #1A1A05", 201 | ",+ c #120E00", 202 | "'+ c #040200", 203 | ")+ c #150900", 204 | "!+ c #2E251E", 205 | "~+ c #070200", 206 | "{+ c #2A1005", 207 | "]+ c #613321", 208 | "^+ c #090200", 209 | "/+ c #210904", 210 | "(+ c #120C0B", 211 | "_+ c #341510", 212 | ":+ c #0C0504", 213 | "<+ c #200502", 214 | "[+ c #1E0402", 215 | "}+ c #3F0704", 216 | "|+ c #7F1C17", 217 | "1+ c #6A1A15", 218 | "2+ c #6C201C", 219 | "3+ c #AA635F", 220 | "4+ c #310705", 221 | "5+ c #120000", 222 | "6+ c #070000", 223 | "7+ c #050000", 224 | "8+ c #100202", 225 | "9+ c #310B0B", 226 | "0+ c #691C1C", 227 | "a+ c #230B0B", 228 | "b+ c #050202", 229 | "c+ c #090505", 230 | "d+ c #120C0C", 231 | " ", 232 | " ", 233 | " ) ! :+ ", 234 | " > 3 k o . 7 h '+c ", 235 | " . ~+x G Y `.S H F 8+= ", 236 | " . . } A . t.q.. %.*.y.: n D ", 237 | " 9+0+2+y &.. ].~.5.$.(.Z Q J I /+ ", 238 | " ^+. @+%+l.}.).3./.-.` 7.^.f.a.a. ", 239 | " d+t V $+<. .o.Y.++h.2.'._.. s a. ", 240 | " b M u.{.:.|.-+{ a+. .+1.@.6.K p <+ ", 241 | " b+b w.F.!.9.. E m 0 - &+i.+.,.R.9 }+ ", 242 | " b+r R e.;.z.#+p.L d 5 . r.>.c.8 @ [+ ", 243 | " j f W n.=.T.A.M. +. 1 ..4.k.#.| 1+. ", 244 | " 2 N.d.[.B.w S.X.P.x.g.C.8.g 3+6+ ", 245 | " 6 B j.0.H.>+J.W.Z.Q.K.U.U , _+. ", 246 | " [ < . E.m.C ,+X b.I.V.L.O ]+. ", 247 | " 4+. q O.G.s.;+i u N P a . ", 248 | " q . v.D.T !+=+)+{+. ", 249 | " 7+# * . v z l ; ", 250 | " 5+% * * ~ / ' ( ( (+ ", 251 | " c+& |+$ ] 4 (+ ", 252 | " . *+. ", 253 | " ", 254 | " ", 255 | " "}; 256 | -------------------------------------------------------------------------------- /main/bitmaps/Zerg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrew-j-armstrong/SCFusion/d2e248e0f21194b10aa0f0bf64b93f715675534a/main/bitmaps/Zerg.png -------------------------------------------------------------------------------- /main/bitmaps/Zerg.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char *Zerg_xpm[] = { 3 | /* columns rows colors chars-per-pixel */ 4 | "16 16 166 2 ", 5 | " c None", 6 | ". c #51132D", 7 | "X c #4E143E", 8 | "o c #501E3C", 9 | "O c #6E1726", 10 | "+ c #632F36", 11 | "@ c #61333B", 12 | "# c #3C0A55", 13 | "$ c #541340", 14 | "% c #5C3241", 15 | "& c #5A2E5F", 16 | "* c #5D2C5D", 17 | "= c #583A5F", 18 | "- c #6B2857", 19 | "; c #74245D", 20 | ": c #69385E", 21 | "> c #5A1E66", 22 | ", c #4E1970", 23 | "< c #501171", 24 | "1 c #5A1E79", 25 | "2 c #621F6F", 26 | "3 c #5B2363", 27 | "4 c #54266C", 28 | "5 c #672F65", 29 | "6 c #642D66", 30 | "7 c #7B2F63", 31 | "8 c #643869", 32 | "9 c #60287F", 33 | "0 c #6C2F78", 34 | "q c #693571", 35 | "w c #6B3578", 36 | "e c #754F4E", 37 | "r c #6A4950", 38 | "t c #724555", 39 | "y c #75405E", 40 | "u c #674B6C", 41 | "i c #6B4B6F", 42 | "p c #6D506F", 43 | "a c #784170", 44 | "s c #77407C", 45 | "d c #79517D", 46 | "f c #8A3E4C", 47 | "g c #80454E", 48 | "h c #855255", 49 | "j c #88605C", 50 | "k c #884F71", 51 | "l c #80427F", 52 | "z c #8E5777", 53 | "x c #975D74", 54 | "c c #876467", 55 | "v c #916679", 56 | "b c #8E7479", 57 | "n c #9F777A", 58 | "m c #6D3082", 59 | "M c #713686", 60 | "N c #7A359E", 61 | "B c #7F4083", 62 | "V c #7A4480", 63 | "C c #7F4782", 64 | "Z c #7B4B82", 65 | "A c #784F85", 66 | "S c #7F5386", 67 | "D c #775E83", 68 | "F c #803A85", 69 | "G c #824681", 70 | "H c #8B4983", 71 | "J c #92598A", 72 | "K c #8C4B93", 73 | "L c #8D4F95", 74 | "P c #955A94", 75 | "I c #965F9B", 76 | "U c #995899", 77 | "Y c #9D5C9D", 78 | "T c #83678E", 79 | "R c #88648D", 80 | "E c #857580", 81 | "W c #87778D", 82 | "Q c #89738A", 83 | "! c #8A7A8D", 84 | "~ c #947A83", 85 | "^ c #8D6390", 86 | "/ c #8F6497", 87 | "( c #8E6798", 88 | ") c #98639D", 89 | "_ c #8D7993", 90 | "` c #A77A94", 91 | "' c #A35BA5", 92 | "] c #9868B6", 93 | "[ c #A77EAE", 94 | "{ c #AB7AA8", 95 | "} c #B17EB4", 96 | "| c #C07CC5", 97 | " . c #998286", 98 | ".. c #9B888C", 99 | "X. c #A28482", 100 | "o. c #A8928E", 101 | "O. c #A78F94", 102 | "+. c #A88896", 103 | "@. c #A39497", 104 | "#. c #AE9798", 105 | "$. c #AD909C", 106 | "%. c #9F87A5", 107 | "&. c #A585AC", 108 | "*. c #AC82AF", 109 | "=. c #AD9FA3", 110 | "-. c #AC9AA5", 111 | ";. c #AF9AA6", 112 | ":. c #B09FA7", 113 | ">. c #AA93B4", 114 | ",. c #B090B7", 115 | "<. c #ADA5AD", 116 | "1. c #B7A7A7", 117 | "2. c #B3A6AA", 118 | "3. c #B9A7AD", 119 | "4. c #AFA0B1", 120 | "5. c #B9A0B3", 121 | "6. c #C0ACB0", 122 | "7. c #C0B1B6", 123 | "8. c #C1B6B6", 124 | "9. c #C0B6B8", 125 | "0. c #C6BDBB", 126 | "q. c #C4BABD", 127 | "w. c #BD8FC2", 128 | "e. c #BEA3C8", 129 | "r. c #C4A5CA", 130 | "t. c #C1B7C4", 131 | "y. c #C4B9C2", 132 | "u. c #C2BAC4", 133 | "i. c #CABFC9", 134 | "p. c #CFBFD0", 135 | "a. c #D0BAD2", 136 | "s. c #C6C3C3", 137 | "d. c #C8C0C3", 138 | "f. c #CAC1C4", 139 | "g. c #CAC2C5", 140 | "h. c #C8C1C6", 141 | "j. c #CDC2CB", 142 | "k. c #CAC4CA", 143 | "l. c #CFC7C9", 144 | "z. c #CBC0CC", 145 | "x. c #CFCCCA", 146 | "c. c #CFCDCD", 147 | "v. c #D1C8C9", 148 | "b. c #D0CACB", 149 | "n. c #D2CDCC", 150 | "m. c #D3CECF", 151 | "M. c #CFC9D0", 152 | "N. c #CFCAD0", 153 | "B. c #D8C9DD", 154 | "V. c #D5D0D1", 155 | "C. c #D5D1D2", 156 | "Z. c #D7D1D2", 157 | "A. c #D6D1D3", 158 | "S. c #D5D3D3", 159 | "D. c #D6D4D6", 160 | "F. c #D9D2D3", 161 | "G. c #DBDADC", 162 | "H. c #DDDBDC", 163 | "J. c #DFDCDD", 164 | "K. c #E0DCDE", 165 | "L. c #E1DFE3", 166 | "P. c #E2DFE2", 167 | "I. c #E3E0E1", 168 | "U. c #E7E3E6", 169 | "Y. c #E6E5E5", 170 | "T. c #E6E4E7", 171 | /* pixels */ 172 | " ..6. ", 173 | " @.% z 5. o ;.C.v. ", 174 | " K.H.& L L.H 5 G.t ", 175 | " #.+ 7 z.r.} a.' N.i.- h. ", 176 | " Y.J.k.T w.) s 5 G I | V ;.l. ", 177 | " I.k *.,.l i t.u.p 3 B L.` q. ", 178 | " ~ 4.R U u U.+.O. = P K a 8. ", 179 | " d.{ [ q N.^ $ . 3.%.C d C.j ", 180 | " $.Q Z 8 9 e.:.h.&.0 Y g o. ", 181 | " 2.p./ S 4 ] Y.B.M > x e ", 182 | " y _ w <.! # , 1 < F h n. ", 183 | " b >.m ( D.E * 2 N J 0. ", 184 | " n.8 W D A y.s.=.r h. ", 185 | " v.7.C.j.; X v F.n. ", 186 | " F.c n f O @ . n. ", 187 | " 1.X.9. C. " 188 | }; 189 | -------------------------------------------------------------------------------- /main/bitmaps/copy.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static const char *const copy_xpm[] = { 3 | /* columns rows colors chars-per-pixel */ 4 | "16 15 23 1", 5 | "+ c #769CDA", 6 | ": c #DCE6F6", 7 | "X c #3365B7", 8 | "* c #FFFFFF", 9 | "o c #9AB6E4", 10 | "< c #EAF0FA", 11 | "# c #B1C7EB", 12 | ". c #6992D7", 13 | "3 c #F7F9FD", 14 | ", c #F0F5FC", 15 | "$ c #A8C0E8", 16 | " c None", 17 | "- c #FDFEFF", 18 | "& c #C4D5F0", 19 | "1 c #E2EAF8", 20 | "O c #89A9DF", 21 | "= c #D2DFF4", 22 | "4 c #FAFCFE", 23 | "2 c #F5F8FD", 24 | "; c #DFE8F7", 25 | "% c #B8CCEC", 26 | "> c #E5EDF9", 27 | "@ c #648FD6", 28 | /* pixels */ 29 | " .....XX ", 30 | " .oO+@X#X ", 31 | " .$oO+X##X ", 32 | " .%$o........ ", 33 | " .&%$.*=&#o.-. ", 34 | " .=&%.*;=&#.--. ", 35 | " .:=&.*>;=&.... ", 36 | " .>:=.*,>;=&#o. ", 37 | " .<1:.*2,>:=&#. ", 38 | " .2<1.*32,>:=&. ", 39 | " .32<.*432,>:=. ", 40 | " .32<.*-432,>:. ", 41 | " .....**-432,>. ", 42 | " .***-432,. ", 43 | " .......... " 44 | }; 45 | -------------------------------------------------------------------------------- /main/bitmaps/cut.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static const char *const cut_xpm[] = { 3 | /* columns rows colors chars-per-pixel */ 4 | "16 15 25 1", 5 | "6 c #D8BDC0", 6 | ": c #C3C3C4", 7 | "- c #FFFFFF", 8 | ". c #6C6D70", 9 | "2 c #AD3A45", 10 | "o c #DBDBDB", 11 | "# c #939495", 12 | "< c #E42234", 13 | "& c #C3C5C8", 14 | "; c #C6CCD3", 15 | "% c #B7B7B8", 16 | " c None", 17 | "* c #DFE0E2", 18 | "5 c #B69596", 19 | "3 c #9C2A35", 20 | "1 c #CFCFD0", 21 | ", c #AB5C64", 22 | "+ c #D2D3D4", 23 | "$ c #BCBDBE", 24 | "@ c #C6C8CA", 25 | "> c #CDC0C1", 26 | "O c #826F72", 27 | "X c #979BA0", 28 | "4 c #9B8687", 29 | "= c #9FA0A0", 30 | /* pixels */ 31 | " .X .o ", 32 | " O.+ @. ", 33 | " O. .. ", 34 | " O#$ %.& ", 35 | " O.*.. ", 36 | " #%#.. ", 37 | " O=-.. ", 38 | " #%#;. ", 39 | " OO:=O ", 40 | " >,,<, ,<,,1 ", 41 | " ><23<1 1<32<1 ", 42 | " ,2 4< <5 2, ", 43 | " <, ,2 2, ,< ", 44 | " 23,<5 5<,32 ", 45 | " 6225 522> " 46 | }; 47 | -------------------------------------------------------------------------------- /main/bitmaps/gantt.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static const char *const gantt_xpm[] = { 3 | /* columns rows colors chars-per-pixel */ 4 | "16 16 4 1 ", 5 | " c None", 6 | ". c #3865AF", 7 | "X c #5584D1", 8 | "o c white", 9 | /* pixels */ 10 | "................", 11 | ".oooooooooooooo.", 12 | ".oXXXXXoXXXXXoo.", 13 | ".oXXXXXoXXXXXoo.", 14 | ".oooooooooooooo.", 15 | ".oooXXXXXXXoooo.", 16 | ".oooXXXXXXXoooo.", 17 | ".oooooooooooooo.", 18 | ".oooooXXXXXXXXo.", 19 | ".oooooXXXXXXXXo.", 20 | ".oooooooooooooo.", 21 | ".ooooooooXXXooo.", 22 | ".ooooooooXXXooo.", 23 | ".oooooooooooooo.", 24 | "................", 25 | " " 26 | }; 27 | -------------------------------------------------------------------------------- /main/bitmaps/help.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static const char *const help_xpm[] = { 3 | /* columns rows colors chars-per-pixel */ 4 | "16 15 50 1", 5 | "j c #4E7FD0", 6 | "8 c #EDF2FB", 7 | ", c #7198D9", 8 | "e c #DCE6F6", 9 | "y c #FFFFFF", 10 | "5 c #95B2E3", 11 | "$ c #9AB6E4", 12 | "g c #EAF0FA", 13 | "1 c #2D59A3", 14 | "@ c #B1C7EB", 15 | "> c #6992D7", 16 | "a c #D9E4F5", 17 | "r c #356AC1", 18 | "6 c #9BB7E5", 19 | "= c #F7F9FD", 20 | "+ c #BED0EE", 21 | "z c #F0F5FC", 22 | "f c #ADC4E9", 23 | "# c #A8C0E8", 24 | "7 c #CBD9F1", 25 | "u c #366BC2", 26 | " c None", 27 | "c c #FDFEFF", 28 | "w c #274D8D", 29 | "t c #C4D5F0", 30 | "% c #7CA0DC", 31 | "h c #E2EAF8", 32 | "p c #487BCE", 33 | "o c #4377CD", 34 | "4 c #2A549A", 35 | "< c #254A87", 36 | "O c #CCDAF2", 37 | "& c #89A9DF", 38 | "9 c #2B559B", 39 | "* c #D2DFF4", 40 | ". c #3366BB", 41 | ": c #2E5CA8", 42 | "x c #FAFCFE", 43 | "l c #F5F8FD", 44 | "2 c #799EDB", 45 | "d c #DFE8F7", 46 | "; c #A6BFE8", 47 | "3 c #638ED5", 48 | "- c #5282D0", 49 | "X c #2A5398", 50 | "0 c #B8CCEC", 51 | "s c #376EC9", 52 | "q c #2D5AA5", 53 | "i c #285092", 54 | "k c #8CACE0", 55 | /* pixels */ 56 | " .......Xo ", 57 | " .O+@#$%.&o ", 58 | " .*O+@#$.=&- ", 59 | " ;:::>#@#.==&: ", 60 | " ,<1234<>@....: ", 61 | "5 c #3366BB", 28 | "$ c #2E5CA8", 29 | "9 c #FAFCFE", 30 | "4 c #F5F8FD", 31 | "q c #638ED5", 32 | "o c #5282D0", 33 | "& c #B8CCEC", 34 | "X c #376EC9", 35 | "< c #ACE95B", 36 | /* pixels */ 37 | " .XoO+@#$. ", 38 | " .%%&*=-O;: ", 39 | " >>>>%&*=O,=o ", 40 | " ><<>%%&*O,,=o ", 41 | ">>><<>>>%&OOo+@ ", 42 | "><<<<<<>1%&*=-@ ", 43 | "><<<<<<>21%&*=@ ", 44 | ">>><<>>>321%&*+ ", 45 | " ><<>456321%&O ", 46 | " >>>>7456321%o ", 47 | " .,8974563210 ", 48 | " .,,897456320 ", 49 | " .,,,8974563q ", 50 | " .,,,,897456w ", 51 | " ............ " 52 | }; 53 | -------------------------------------------------------------------------------- /main/bitmaps/open.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static const char *const open_xpm[] = { 3 | /* columns rows colors chars-per-pixel */ 4 | "16 15 36 1", 5 | ", c #AAC1E8", 6 | "1 c #9AEA53", 7 | "q c #DCE6F6", 8 | ". c #295193", 9 | "; c #A9D066", 10 | "r c #C6D6F0", 11 | "$ c #4A7CCE", 12 | "9 c #779DDB", 13 | "8 c #EAF0FA", 14 | "O c #6E96D8", 15 | "X c #214279", 16 | "e c #BED0EE", 17 | "6 c #85A7DF", 18 | "5 c #F0F5FC", 19 | "t c #ADC4E9", 20 | ": c #3161B1", 21 | " c None", 22 | "u c #274D8B", 23 | "& c #BFDC9B", 24 | "> c #9FB9E5", 25 | "y c #5584D1", 26 | "w c #3569BF", 27 | "% c #3A70CA", 28 | "+ c #305FAC", 29 | "3 c #5D89D3", 30 | "0 c #D2DFF4", 31 | "@ c #CAE2AA", 32 | "= c #B2D58C", 33 | "2 c #FAFCFE", 34 | "# c #638ED5", 35 | "* c #CEDCF2", 36 | "4 c #90AFE2", 37 | "< c #B3C8EB", 38 | "7 c #E5EDF9", 39 | "- c #A2BCE6", 40 | "o c #DFF0D0", 41 | /* pixels */ 42 | " ", 43 | " .... ", 44 | "XXXXX .oo. ", 45 | "XOOOO+ .@o. ", 46 | "XOOOO#$%.&*XXX ", 47 | "XOOOOOOO.=*X-X ", 48 | "XOXXXX...;*XXXX:", 49 | "XOX>,<.11111*X2:", 50 | "X3X4>,<.111*X5-:", 51 | "XX#64>,,.1*X78: ", 52 | "XXO964>,,.X0q7: ", 53 | "Xw3O964>,,er0t: ", 54 | "X%y3O964>, c #FEE3D7", 7 | "O c #FFFFFF", 8 | "o c #7B767D", 9 | "% c #F79586", 10 | "& c #CAE1F3", 11 | "@ c #F08B62", 12 | "# c #FCCBB8", 13 | "- c #FDD8C9", 14 | "4 c #FFF8F4", 15 | "5 c #FFF5F0", 16 | " c None", 17 | "$ c #F8AA8F", 18 | ", c #EFF6FC", 19 | "1 c #F7FBFD", 20 | "2 c #FAFCFE", 21 | "; c #DAEAF7", 22 | ": c #E9F3FA", 23 | "6 c #FFFAF8", 24 | ". c #3C78A6", 25 | "3 c #FFF1ED", 26 | "X c #9B8687", 27 | "+ c #FBBCA4", 28 | "* c #B6D5EE", 29 | "= c #F4F9FD", 30 | /* pixels */ 31 | " ...... ", 32 | " .XoOOOOoo. ", 33 | ".+XOOOOOOX@. ", 34 | ".+XXXXXXXX@. ", 35 | ".#++$$%@..... ", 36 | ".##++$$%.&*.=. ", 37 | ".-##++$$.;&.==. ", 38 | ".--##++$.:;.... ", 39 | ".>--##++.,:;&*. ", 40 | ".<>--##+.1,:;&. ", 41 | ".<<>--##.21,:;. ", 42 | ".3<<>--#.O21=:. ", 43 | ".45<<>--....... ", 44 | ".6453<>----. ", 45 | "............ " 46 | }; 47 | -------------------------------------------------------------------------------- /main/bitmaps/preview.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static const char *const preview_xpm[] = { 3 | /* columns rows colors chars-per-pixel */ 4 | "16 15 30 1", 5 | "1 c Black", 6 | "= c #97C4E7", 7 | "< c #FFFFFF", 8 | ", c #69A1CF", 9 | ". c #5A89A6", 10 | "# c #3A749C", 11 | "+ c #538BB1", 12 | "> c #D1E5F5", 13 | "o c #6792AE", 14 | "% c #C3DDF1", 15 | "8 c #749BB5", 16 | "; c #619BC4", 17 | "X c #6B97B6", 18 | "@ c #4B82A8", 19 | " c None", 20 | "O c #5F8FB0", 21 | "q c #84A5BB", 22 | ": c #71A8D1", 23 | "- c #85BBE2", 24 | "9 c #EFF6FC", 25 | "7 c #F7FBFD", 26 | "6 c #FAFCFE", 27 | "2 c #7FA6C0", 28 | "5 c #C00000", 29 | "0 c #FDFDFE", 30 | "3 c #E2EFF8", 31 | "$ c #8EA9BC", 32 | "& c #B6D5EE", 33 | "* c #A5CCEA", 34 | "4 c #F4F9FD", 35 | /* pixels */ 36 | " ..XoO+@#$ ", 37 | " .%%&*=-;:; ", 38 | " .>>%&*=,<=X ", 39 | " $%%%1112<<=X ", 40 | " $3-1<<<1oXO+ ", 41 | " $314<<<<1=-+ ", 42 | " $31<<<<<1-=+ ", 43 | " $31<<<<<1&*O ", 44 | " $3-1<<<51>%X ", 45 | " $367111551>8 ", 46 | " $3-----95518 ", 47 | " $3<067466551 ", 48 | " $3--------551 ", 49 | " $3<<<0666<<55 ", 50 | " $$$$$$$$$$q$ " 51 | }; 52 | -------------------------------------------------------------------------------- /main/bitmaps/print.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static const char *const print_xpm[] = { 3 | /* columns rows colors chars-per-pixel */ 4 | "16 15 35 1", 5 | "y c #EDF2FB", 6 | "9 c #4E7FD0", 7 | "> c #B9CDED", 8 | "# c #3365B7", 9 | "r c #FFFFFF", 10 | "8 c #2C58A0", 11 | "X c #779DDB", 12 | "7 c #7FA2DD", 13 | "t c #3263B4", 14 | "q c #6E96D8", 15 | "= c #6992D7", 16 | "* c #D9E4F5", 17 | "0 c #356AC1", 18 | "& c #CBD9F1", 19 | "; c #97B4E3", 20 | "e c #3161B1", 21 | " c None", 22 | "1 c #B5C9EB", 23 | ", c #7CA0DC", 24 | "4 c #487BCE", 25 | "- c #4377CD", 26 | ". c #5584D1", 27 | "6 c #3A70CA", 28 | "2 c #305FAC", 29 | "< c #5685D2", 30 | "w c #4075CC", 31 | "5 c #638ED5", 32 | "3 c #3467BC", 33 | "% c #2F5DA9", 34 | "o c #ECF1FA", 35 | ": c #D6E1F4", 36 | "@ c #376EC9", 37 | "$ c #2D5AA5", 38 | "+ c #A2BCE6", 39 | "O c #CFDDF3", 40 | /* pixels */ 41 | " .XXXXXXXX ", 42 | " .oooooooX ", 43 | " .OOOOOOOX ", 44 | " .+++++++X ", 45 | " @@#$%%%%%$%@@ ", 46 | "#&*=-=;:>,<#*&# ", 47 | ".11.2345.63#11. ", 48 | "4;;;;;;;;;;;;;4 ", 49 | "677588888889776 ", 50 | "0qq60wwwwwweqq0 ", 51 | "3553rrrrrrr$553 ", 52 | "3< c #C0D1EE", 26 | /* pixels */ 27 | " .", 28 | " XoOOOOOOOOO+X .", 29 | " @oO#######O+@ .", 30 | " @oOOOOOOOOO+@ .", 31 | " @oO#######O+@ .", 32 | " @oOOOOOOOOO+@ .", 33 | " @@+++++++++@@ .", 34 | " @@@@@@@@@@@@@ .", 35 | " @@@$$$$$$$$@@ .", 36 | " @@$%%%&*=-O$@ .", 37 | " @@$%X;;*=-O$@ .", 38 | " @@$%X;;:>,O$@ .", 39 | " @@$%X;;<12O$@ .", 40 | " @@$<<2OOOOO$@ .", 41 | ". .." 42 | }; 43 | -------------------------------------------------------------------------------- /main/bitmaps/sc2_icon_protoss_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrew-j-armstrong/SCFusion/d2e248e0f21194b10aa0f0bf64b93f715675534a/main/bitmaps/sc2_icon_protoss_16.png -------------------------------------------------------------------------------- /main/bitmaps/sc2_icon_terran_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrew-j-armstrong/SCFusion/d2e248e0f21194b10aa0f0bf64b93f715675534a/main/bitmaps/sc2_icon_terran_16.png -------------------------------------------------------------------------------- /main/bitmaps/sc2_icon_zerg_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrew-j-armstrong/SCFusion/d2e248e0f21194b10aa0f0bf64b93f715675534a/main/bitmaps/sc2_icon_zerg_16.png -------------------------------------------------------------------------------- /main/bitmaps/terran_icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrew-j-armstrong/SCFusion/d2e248e0f21194b10aa0f0bf64b93f715675534a/main/bitmaps/terran_icon.jpg -------------------------------------------------------------------------------- /main/bitmaps/zerg_icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrew-j-armstrong/SCFusion/d2e248e0f21194b10aa0f0bf64b93f715675534a/main/bitmaps/zerg_icon.jpg -------------------------------------------------------------------------------- /main/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrew-j-armstrong/SCFusion/d2e248e0f21194b10aa0f0bf64b93f715675534a/main/resource.h -------------------------------------------------------------------------------- /main/stdafx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define _CRT_SECURE_NO_WARNINGS 4 | 5 | #pragma warning (disable : 4100) 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include "Core/FastRand.h" 12 | #include "Core/MemoryPool.h" 13 | 14 | template const T &mymin(const T &a, const T &b) { return (a < b) ? a : b; } 15 | template const T &mymax(const T &a, const T &b) { return (a > b) ? a : b; } 16 | 17 | WX_DECLARE_STRING_HASH_MAP(size_t, wxHashMapStringToSizeT ); 18 | 19 | #define NOOP ((void)0) -------------------------------------------------------------------------------- /wxWidgets/download.txt: -------------------------------------------------------------------------------- 1 | Download wxWidgets Windows binaries from https://www.wxwidgets.org/downloads/ 2 | - Header files 3 | - Development files 4 | - Release DLLs --------------------------------------------------------------------------------