Browse Source

tried to fix most vexing problem

meemknight 2 years ago
parent
commit
03b4018f95

+ 24 - 23
Pika/CMakeLists.txt

@@ -21,7 +21,7 @@ set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) #under no circumstance we want th
 #declare projects
 project(pikaCore)
 project(pikaGameplay)
-project(pikaProduction)
+#project(pikaProduction)
 
 
 #add third party libraries
@@ -97,27 +97,28 @@ target_link_libraries(pikaGameplay PRIVATE glad glfw gl2d gl3d glui glm stb_imag
 #################^^^^^^^^^^^^^^############################
 
 
-
-#pikaProduction ###########################################
-add_executable(pikaProduction)
-
-target_compile_definitions(pikaProduction PUBLIC PIKA_PRODUCTION)
-set_property(TARGET pikaProduction PROPERTY CXX_STANDARD 17)
-
-target_sources(pikaProduction PRIVATE 
-	"${PIKA_SOURCES_CORE_CONFIG}" "${PIKA_SOURCES_CORE_EDITOR}" "${PIKA_SOURCES_PLUGGINS}"
-	"${PIKA_SOURCES_CORE_RUNTIME}" "${PIKA_SOURCES_CORE_STD}" "${PIKA_SOURCES_GAMEPLAY}" "${PIKA_SOURCES_CORE_SHARED_RUNTIME}")
-target_include_directories(pikaProduction PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/core/coreConfig/")
-target_include_directories(pikaProduction PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/core/pikaEditor/")
-target_include_directories(pikaProduction PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/core/pikaRuntime/")
-target_include_directories(pikaProduction PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/core/pikaSTD/")
-target_include_directories(pikaProduction PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/gameplay/")
-target_include_directories(pikaProduction PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/core/sharedRuntime/")
-target_include_directories(pikaProduction PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/pluggins/")
-
-target_link_libraries(pikaProduction PRIVATE glad glfw gl2d gl3d glui glm stb_image stb_truetype imgui safeSave profilerLib)
-
-
+#
+#
+##pikaProduction ###########################################
+#add_executable(pikaProduction)
+#
+#target_compile_definitions(pikaProduction PUBLIC PIKA_PRODUCTION)
+#set_property(TARGET pikaProduction PROPERTY CXX_STANDARD 17)
+#
+#target_sources(pikaProduction PRIVATE 
+#	"${PIKA_SOURCES_CORE_CONFIG}" "${PIKA_SOURCES_CORE_EDITOR}" "${PIKA_SOURCES_PLUGGINS}"
+#	"${PIKA_SOURCES_CORE_RUNTIME}" "${PIKA_SOURCES_CORE_STD}" "${PIKA_SOURCES_GAMEPLAY}" "${PIKA_SOURCES_CORE_SHARED_RUNTIME}")
+#target_include_directories(pikaProduction PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/core/coreConfig/")
+#target_include_directories(pikaProduction PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/core/pikaEditor/")
+#target_include_directories(pikaProduction PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/core/pikaRuntime/")
+#target_include_directories(pikaProduction PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/core/pikaSTD/")
+#target_include_directories(pikaProduction PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/gameplay/")
+#target_include_directories(pikaProduction PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/core/sharedRuntime/")
+#target_include_directories(pikaProduction PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/pluggins/")
+#
+#target_link_libraries(pikaProduction PRIVATE glad glfw gl2d gl3d glui glm stb_image stb_truetype imgui safeSave profilerLib)
+#
+#
 
 #################^^^^^^^^^^^^^^############################
 
@@ -125,7 +126,7 @@ target_link_libraries(pikaProduction PRIVATE glad glfw gl2d gl3d glui glm stb_im
 #set exe type to be windowed
 if(MSVC)
 	
-	 set_target_properties(pikaProduction PROPERTIES LINK_FLAGS "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
+	 #set_target_properties(pikaProduction PROPERTIES LINK_FLAGS "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
 	 set_target_properties(pikaCore PROPERTIES LINK_FLAGS "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
 
 endif()

+ 65 - 17
Pika/core/pikaRuntime/containerManager/containerManager.cpp

@@ -618,20 +618,6 @@ void pika::ContainerManager::reloadDll(pika::LoadedDll &loadedDll, pika::PikaWin
 		//to get hold onto the dll 
 
 
-	//pika::LoadedDll newDll;
-	//if (!newDll.tryToloadDllUntillPossible(loadedDll.id + 1, logs, std::chrono::seconds(1)))
-	//{
-	//	logs.log("Dll reload attemp failed", pika::logWarning);
-	//	newDll.unloadDll();
-	//	return;
-	//}
-	//else
-	//{
-	//	newDll.unloadDll();
-	//}
-	//std::this_thread::sleep_for(std::chrono::milliseconds(10)); // make sure that the dll is unloaded
-
-
 	auto oldContainerInfo = loadedDll.containerInfo;
 
 	if (!loadedDll.tryToloadDllUntillPossible(loadedDll.id, logs, std::chrono::seconds(5)))
@@ -639,7 +625,7 @@ void pika::ContainerManager::reloadDll(pika::LoadedDll &loadedDll, pika::PikaWin
 		logs.log("Couldn't reloaded dll", pika::logWarning);
 		return;
 	}
-	//todo pospone dll reloading
+	//todo pospone dll reloading and make this timer shorter
 
 	std::unordered_map<std::string, pika::ContainerInformation> containerNames;
 	for (auto &c : loadedDll.containerInfo)
@@ -655,8 +641,6 @@ void pika::ContainerManager::reloadDll(pika::LoadedDll &loadedDll, pika::PikaWin
 
 	//clear containers that dissapeared
 	{
-
-
 		std::vector<pika::containerId_t> containersToClean;
 		for (auto &i : runningContainers)
 		{
@@ -707,6 +691,70 @@ void pika::ContainerManager::reloadDll(pika::LoadedDll &loadedDll, pika::PikaWin
 
 	}
 
+
+	//realocate pointers
+	{
+		std::unordered_map<std::string, size_t> vtable;
+
+		for (auto &i : runningContainers)
+		{
+			auto pos = vtable.find(i.second.baseContainerName);
+			if (pos == vtable.end())
+			{
+				pika::RuntimeContainer container = {};
+				pika::strlcpy(container.baseContainerName, i.second.baseContainerName,
+					sizeof(container.baseContainerName));
+
+				pika::ContainerInformation info;
+				for (auto &l : loadedDll.containerInfo)
+				{
+					if (l.containerName == i.second.baseContainerName)
+					{
+						info = l;
+					}
+				}
+
+				if (!allocateContainerMemory(container, info, 0))
+				{
+					logs.log("Internal error 1", pika::logError);
+				}
+				else
+				{
+					loadedDll.bindAllocatorDllRealm(&container.allocator);
+
+					//this calls the constructors (from the dll realm)
+					if (!loadedDll.constructRuntimeContainer(container, i.second.baseContainerName))
+					{
+						loadedDll.resetAllocatorDllRealm();
+						logs.log("Internal error 2", pika::logError);
+						freeContainerStuff(container);
+						loadedDll.resetAllocatorDllRealm();
+					}
+					else
+					{
+						
+						size_t id = *(size_t *)container.pointer;
+
+						freeContainerStuff(container);
+						loadedDll.resetAllocatorDllRealm();
+
+						vtable[i.second.baseContainerName] = id;
+					}
+
+				
+				}
+			}
+			
+			pos = vtable.find(i.second.baseContainerName);
+			if (pos != vtable.end())
+			{
+				memcpy(i.second.pointer, (void*)&pos->second, sizeof(size_t));
+			}
+		}
+	}
+
+
+
 	loadedDll.gameplayReload_(window.context);
 	
 

+ 1 - 1
Pika/core/pikaRuntime/dllLoader/dllLoader.cpp

@@ -62,7 +62,7 @@ void pika::LoadedDll::reloadContainerExtensionsSupport()
 bool pika::LoadedDll::constructRuntimeContainer(RuntimeContainer &c, const char *name)
 {
 	PIKA_DEVELOPMENT_ONLY_ASSERT(constructContainer_ != nullptr, "dll not loaded");
-	return constructContainer_(&c.pointer, &c.arena, name);
+	return constructContainer_(&c.pointer, &c.arena, name); //todo c.baseContainerName instead of name param
 }
 
 

+ 9 - 3
Pika/gameplay/containers/mario/mario.cpp

@@ -383,17 +383,18 @@ void getVision(char vision[visionSizeX * visionSizeY], mario::GameplaySimulation
 bool performNeuralSimulation(PlayerSimulation &p, float deltaTime, mario::GameplaySimulation &simulator, mario::NeuralNetork
 	&network)
 {
-	if (p.p.position.position.x > p.maxFit)
+	if (p.p.position.position.x - p.maxFit > 0.2)
 	{
+
 		p.maxFit = p.p.position.position.x;
 		p.killTimer = 0;
 	}
 	else
 	{
 		p.killTimer += deltaTime;
-		if (p.killTimer > 3)
+		if (p.killTimer > 4)
 		{
-			//	return 0;
+				return 0;
 		}
 	}
 
@@ -405,6 +406,11 @@ bool performNeuralSimulation(PlayerSimulation &p, float deltaTime, mario::Gamepl
 	//input
 	network.compute(simulator.moveDelta, simulator.jump, vision);
 
+	if (simulator.jump && p.p.grounded)
+	{
+		p.jumpCount++;
+	}
+
 	if (!simulator.updateFrame(deltaTime, p.p))
 	{
 		return 0;

+ 114 - 13
Pika/gameplay/containers/mario/marioCommon.h

@@ -12,7 +12,7 @@ constexpr const char *collisionMap =
 "--------"
 "-XX--X--"
 "-XX-----"
-"-XX-XXXX"
+"-XX-XXX-"
 "--X-XXX-"
 "XX------"
 "XX--XX--"
@@ -299,6 +299,33 @@ static constexpr int visionSizeY = 9;
 
 static constexpr int visionTotal = visionSizeX * visionSizeY;
 
+inline float getRandomFloat(std::mt19937 &rng, float min, float max)
+{
+	std::uniform_real_distribution<float> dist(min, max);
+	return dist(rng);
+}
+
+inline int getRandomInt(std::mt19937 &rng, int min, int max)
+{
+	std::uniform_int_distribution<int> dist(min, max);
+	return dist(rng);
+}
+
+inline bool getRandomChance(std::mt19937 &rng, float chance)
+{
+	int chanceI = glm::clamp(chance, 0.f, 1.f) * 100000;
+	int pick = getRandomInt(rng, 0, 100000);
+
+	if (pick > chanceI)
+	{
+		return 0;
+	}
+	else
+	{
+		return 1;
+	}
+}
+
 struct NeuralNetork
 {
 	float weights[3][visionTotal] = {};
@@ -310,12 +337,19 @@ struct NeuralNetork
 		{
 			for (int j = 0; j < visionTotal; j++)
 			{
-				rezult[i] += input[j] * weights[i][j];
+				if (input[j])
+				{
+					rezult[i] += weights[i][j];
+				}
+				else
+				{
+					rezult[i] -= weights[i][j];
+				}
 			}
 		}
 
 		float dir = rezult[2] - rezult[1];
-		if (std::abs(dir) < 1) { moveDirection = 0; }
+		if (std::abs(dir) < 0.2) { moveDirection = 0; }
 		else if(dir > 0)
 		{
 			moveDirection = 1;
@@ -336,26 +370,54 @@ struct NeuralNetork
 
 	}
 
-	float getRandomFloat(std::mt19937 &rng, float min, float max)
+	void addRandomNeuron(std::mt19937 &rng)
 	{
-		std::uniform_real_distribution<float> dist(min, max);
-		return dist(rng);
-	}
+		std::vector<glm::ivec2> positions;
+		positions.reserve(visionTotal*3);
+		for (int i = 0; i < 3; i++)
+			for (int j = 0; j < visionTotal; j++)
+			{
+				if (weights[i][j] == 0)
+				{
+					positions.push_back({i,j});
+				}
+			}
 
-	int getRandomInt(std::mt19937 &rng, int min, int max)
+		if (!positions.empty())
+		{
+			auto index = getRandomInt(rng, 0, positions.size() - 1);
+			weights[positions[index].x][positions[index].y] = getRandomFloat(rng, -1.5, 1.5);
+		}
+	}
+	
+	void removeRandomNeuron(std::mt19937 &rng)
 	{
-		std::uniform_int_distribution<int> dist(min, max);
-		return dist(rng);
+		std::vector<glm::ivec2> positions;
+		positions.reserve(visionTotal * 3);
+		for (int i = 0; i < 3; i++)
+			for (int j = 0; j < visionTotal; j++)
+			{
+				if (weights[i][j] != 0)
+				{
+					positions.push_back({i,j});
+				}
+			}
+
+		if (!positions.empty())
+		{
+			auto index = getRandomInt(rng, 0, positions.size() - 1);
+			weights[positions[index].x][positions[index].y] = 0;
+		}
 	}
 
-	void addRandomNeuron(std::mt19937 &rng)
+	void changeRandomNeuron(std::mt19937 &rng)
 	{
 		std::vector<glm::ivec2> positions;
-		positions.reserve(visionTotal*3);
+		positions.reserve(visionTotal * 3);
 		for (int i = 0; i < 3; i++)
 			for (int j = 0; j < visionTotal; j++)
 			{
-				if (weights[i][j] == 0)
+				if (weights[i][j] != 0)
 				{
 					positions.push_back({i,j});
 				}
@@ -366,7 +428,45 @@ struct NeuralNetork
 			auto index = getRandomInt(rng, 0, positions.size() - 1);
 			weights[positions[index].x][positions[index].y] = getRandomFloat(rng, -1.5, 1.5);
 		}
+	}
 
+	void combine(std::mt19937 &rng, NeuralNetork &other)
+	{
+		std::vector<glm::ivec2> positions;
+		for (int i = 0; i < 3; i++)
+			for (int j = 0; j < visionTotal; j++)
+			{
+				if (weights[i][j] != other.weights[i][j])
+				{
+					positions.push_back({i,j});
+				}
+			}
+		
+		float chance = getRandomFloat(rng, 0, 1);
+
+		for (auto p : positions)
+		{
+			bool combine = getRandomInt(rng, 0, 5) == 1;
+			int i = p.x;
+			int j = p.y;
+
+			if (combine)
+			{
+				weights[i][j] = (weights[i][j] + other.weights[i][j]) / 2.f;
+			}
+			else
+			{
+				bool keeper = getRandomChance(rng, chance);
+				if (keeper)
+				{
+					weights[i][j] = other.weights[i][j];
+				}
+				else
+				{
+					//keep
+				}
+			}
+		}
 	}
 
 };
@@ -376,6 +476,7 @@ struct PlayerSimulation
 	mario::Player p;
 	float maxFit = 0;
 	float killTimer = 0;
+	int jumpCount = 0;
 };
 
 bool performNeuralSimulation(PlayerSimulation &p, float deltaTime, mario::GameplaySimulation &simulator, mario::NeuralNetork

+ 140 - 29
Pika/gameplay/containers/mario/marioNeuralTrainer.h

@@ -17,6 +17,7 @@ struct MarioNeuralTrainer: public Container
 	mario::GameplayRenderer renderer;
 	mario::GameplaySimulation simulator;
 	pika::pikaImgui::FileSelector currentMap;
+	pika::pikaImgui::FileSelector rezFile;
 
 	//todo user can request imgui ids; shortcut manager context; allocators
 	static ContainerStaticInfo containerInfo()
@@ -39,14 +40,104 @@ struct MarioNeuralTrainer: public Container
 	};
 
 	std::vector<SimulationNetwork> simulations;
+	std::vector<SimulationNetwork> deadSimulations;
+
+	std::mt19937 rng = std::mt19937(std::random_device{}());
+
+	int generation = 1;
+
+	bool preview = 1;
+	bool fast = 0;
+	bool save = 0;
+
+	void recreateGenerations(RequestedContainerInfo &requestedInfo)
+	{
+		simulations.clear();
+		std::sort(deadSimulations.begin(), deadSimulations.end(), [&](SimulationNetwork &a, SimulationNetwork &b) 
+		{
+			return 	a.player.maxFit > b.player.maxFit;
+		});
+
+
+		if (rezFile.file[0] != '\0' && save)
+		{
+			requestedInfo.writeEntireFileBinary(rezFile.file, &deadSimulations[0].network, sizeof(deadSimulations[0].network));
+		}
+
+		std::vector<SimulationNetwork> fittest;
+		fittest.push_back(deadSimulations[0]);
+		fittest.push_back(deadSimulations[1]);
+		fittest.push_back(deadSimulations[2]);
+		fittest.push_back(deadSimulations[3]);
+		fittest.push_back(deadSimulations[4]);
+
+		for (auto &i : fittest) 
+		{ 
+			i.player = {};
+			i.player.p.position.position = {1,1};
+			i.player.p.lastPos = {1,1};
+			simulations.push_back(i); 
+		}
+
+		while (simulations.size() < 1000)
+		{
+			int a = mario::getRandomInt(rng, 0, 4);
+			int b = mario::getRandomInt(rng, 0, 4);
+
+			SimulationNetwork newNetwork = fittest[a];
+			newNetwork.network.combine(rng, fittest[b].network);
+			
+			newNetwork.player = {};
+			newNetwork.player.p.position.position = {1,1};
+			newNetwork.player.p.lastPos = {1,1};
+
+
+			if (mario::getRandomChance(rng, 0.25))
+			{
+				int type = mario::getRandomInt(rng, 0, 100);
+
+				if (type < 10)
+				{
+					newNetwork.network.removeRandomNeuron(rng);
+					newNetwork.network.removeRandomNeuron(rng);
+					newNetwork.network.removeRandomNeuron(rng);
+				}
+				if (type < 25)
+				{
+					newNetwork.network.removeRandomNeuron(rng);
+				}
+				else if (type < 50)
+				{
+					newNetwork.network.addRandomNeuron(rng);
+				}
+				else if (type < 75)
+				{
+					newNetwork.network.addRandomNeuron(rng);
+					newNetwork.network.addRandomNeuron(rng);
+				}
+				else if (type < 100)
+				{
+					newNetwork.network.changeRandomNeuron(rng);
+				}
+
+			}
+			simulations.push_back(newNetwork);
+		}
+
+		generation++;
+		deadSimulations.clear();
+	}
 
 	bool create(RequestedContainerInfo &requestedInfo, pika::StaticString<256> commandLineArgument)
 	{
 		currentMap.setInfo("Training map", PIKA_RESOURCES_PATH "/mario", {".mario"});
 
+		rezFile.setInfo("Neural network file", PIKA_RESOURCES_PATH "/mario", {".neural"});
+
+
 		if (commandLineArgument.size() != 0)
 		{
-			pika::strlcpy(currentMap.file, commandLineArgument.data(), sizeof(currentMap.file));
+			pika::strlcpy(currentMap.file, commandLineArgument.to_string(), sizeof(currentMap.file));
 		}
 		else
 		{
@@ -59,22 +150,13 @@ struct MarioNeuralTrainer: public Container
 
 		std::mt19937 rng(std::random_device{}());
 
-		simulations.reserve(200);
-		for (int i = 0; i < 200; i++)
+		simulations.reserve(100);
+		for (int i = 0; i < 100; i++)
 		{
 			SimulationNetwork s;
 			s.network.addRandomNeuron(rng);
 			s.network.addRandomNeuron(rng);
 			s.network.addRandomNeuron(rng);
-			s.network.addRandomNeuron(rng);
-			s.network.addRandomNeuron(rng);
-			s.network.addRandomNeuron(rng);
-			s.network.addRandomNeuron(rng);
-			s.network.addRandomNeuron(rng);
-			s.network.addRandomNeuron(rng);
-			s.network.addRandomNeuron(rng);
-			s.network.addRandomNeuron(rng);
-			s.network.addRandomNeuron(rng);
 			s.player.p.position.position = {1,1};
 			s.player.p.lastPos = {1,1};
 			simulations.push_back(s);
@@ -100,31 +182,45 @@ struct MarioNeuralTrainer: public Container
 		float maxFit = 0;
 		for (int i = 0; i < simulations.size(); i++)
 		{
-			if (simulations[i].player.p.position.position.x > maxFit)
+			if (simulations[i].player.p.position.position.x - simulations[i].player.jumpCount / 10.f > maxFit)
 			{
-				maxFit = simulations[i].player.p.position.position.x;
+				maxFit = simulations[i].player.p.position.position.x - simulations[i].player.jumpCount/10.f;
 				maxIndex = i;
 			}
 		}
 
-		renderer.update(input, windowState, simulator);
-		renderer.followPlayer(simulations[maxIndex].player.p, input, windowState);
+		if (preview)
+		{
+			renderer.update(input, windowState, simulator);
 
-		for (int i = 0; i < simulations.size(); i++)
-		renderer.drawPlayer(simulations[i].player.p);
+			for (int i = 0; i < simulations.size(); i++)
+			renderer.drawPlayer(simulations[i].player.p);
+
+			renderer.followPlayer(simulations[maxIndex].player.p, input, windowState);
+
+			{
+				char vision[mario::visionSizeX * mario::visionSizeY] = {};
+				getVision(vision, simulator, simulations[maxIndex].player);
+				mario::renderNeuralNetwork(renderer.renderer, vision, 20, simulations[maxIndex].network);
+			}
+		}
 
+
+
+		float newDelta = input.deltaTime;
+
+		if (fast)
 		{
-			char vision[mario::visionSizeX * mario::visionSizeY] = {};
-			getVision(vision, simulator, simulations[maxIndex].player);
-			mario::renderNeuralNetwork(renderer.renderer, vision, 20, simulations[maxIndex].network);
+			newDelta = 1.f / 50.f;
 		}
 
 		for (int i = 0; i < simulations.size(); i++)
 		{
 
 			if (!mario::performNeuralSimulation(simulations[i].player, 
-				input.deltaTime, simulator, simulations[i].network))
+				newDelta, simulator, simulations[i].network))
 			{
+				deadSimulations.push_back(simulations[i]);
 				simulations.erase(simulations.begin() + i);
 				i--;
 				continue;
@@ -133,15 +229,23 @@ struct MarioNeuralTrainer: public Container
 
 		}
 
-		if (simulations.empty()) { return 0; }
+		if (simulations.empty()) 
+		{
+			recreateGenerations(requestedInfo);
+		}
 
 		
-		//simulator.simulator.player.position.position.x;
-
+		if (preview)
+		{
+			glBindFramebuffer(GL_FRAMEBUFFER, requestedInfo.requestedFBO.fbo);
+			renderer.render();
+		}
+		else
+		{
+			renderer.renderer.clearDrawData();
+		}
 
 
-		glBindFramebuffer(GL_FRAMEBUFFER, requestedInfo.requestedFBO.fbo);
-		renderer.render();
 
 		ImGui::Begin("Neural trainer");
 		{
@@ -149,8 +253,15 @@ struct MarioNeuralTrainer: public Container
 			ImGui::Separator();
 			currentMap.run(1);
 			ImGui::Separator();
-
-
+			ImGui::Text("Generation: %d", generation);
+			ImGui::Text("Current individuals alieve: %d", (int)simulations.size());
+			ImGui::Text("Float fittest dist: %f", maxFit);
+			ImGui::Checkbox("preview", &preview);
+			ImGui::Checkbox("fixed framerate", &fast);
+
+			rezFile.run(2);
+			ImGui::SameLine();
+			ImGui::Checkbox("save", &save);
 
 		}
 		ImGui::End();

+ 31 - 3
Pika/gameplay/containers/mario/marioNeuralVizualizer.h

@@ -17,6 +17,10 @@ struct MarioNeuralVizualizer: public Container
 	mario::GameplaySimulation simulator;
 	mario::PlayerSimulation player;
 
+	pika::pikaImgui::FileSelector rezFile;
+
+	bool fixedFramerate = 0;
+
 	//todo user can request imgui ids; shortcut manager context; allocators
 	static ContainerStaticInfo containerInfo()
 	{
@@ -36,6 +40,8 @@ struct MarioNeuralVizualizer: public Container
 
 	bool create(RequestedContainerInfo &requestedInfo, pika::StaticString<256> commandLineArgument)
 	{
+		rezFile.setInfo("Neural network file", PIKA_RESOURCES_PATH "/mario", {".neural"});
+
 		if (commandLineArgument.size() != 0)
 		{
 			mapFile = commandLineArgument.to_string();
@@ -75,22 +81,44 @@ struct MarioNeuralVizualizer: public Container
 		renderer.followPlayer(player.p, input, windowState);
 		renderer.drawPlayer(player.p);
 
-		if (!mario::performNeuralSimulation(player, input.deltaTime, simulator, network))
+		float deltaTime = input.deltaTime;
+
+		if (fixedFramerate)
+		{
+			deltaTime = 1.f / 50.f;
+		}
+
+		if (!mario::performNeuralSimulation(player, deltaTime, simulator, network))
 		{
-			return 0;
+			player = {};
+			player.p.position.position = {1,1};
+			player.p.lastPos = {1,1};
 		}
 
 		char vision[mario::visionSizeX * mario::visionSizeY] = {};
 		mario::getVision(vision, simulator, player);
 		mario::renderNeuralNetwork(renderer.renderer, vision, 20, network);
 		
-		//simulator.simulator.player.position.position.x;
+
 	
 
 
 		glBindFramebuffer(GL_FRAMEBUFFER, requestedInfo.requestedFBO.fbo);
 		renderer.render();
 
+		ImGui::Begin("Neural trainer");
+		{
+		
+			if (rezFile.run(2))
+			{
+				requestedInfo.readEntireFileBinary(rezFile.file, &network, sizeof(network));
+			}
+
+			ImGui::Checkbox("Fixed framerate", &fixedFramerate);
+
+		}
+		ImGui::End();
+
 
 		return true;
 	}

+ 1 - 2
Pika/resources/logs.txt

@@ -1,2 +1 @@
-#2023-04-26 00:23:42: Created container: MarioNeuralTrainer
-#2023-04-26 00:24:26: Destroyed continer: MarioNeuralTrainer #1
+#2023-04-27 18:19:59: Reloaded dll

BIN
Pika/resources/mario/Dpad_Left.png


BIN
Pika/resources/mario/Dpad_Right.png


BIN
Pika/resources/mario/Dpad_Up.png


BIN
Pika/resources/mario/rez.neural


BIN
Pika/resources/mario/test1.mario