void AggregateLibrary::addAggregate(AggregatePtr const& aggregate) { if (!aggregate) throw SYSTEM_EXCEPTION(SCIDB_SE_INTERNAL, SCIDB_LE_CANT_ADD_NULL_FACTORY); //Try to find functions with 1 argument which can match new aggregate std::vector<TypeId> inputTypes(1, aggregate->getAggregateType().typeId()); FunctionDescription functDescription; std::vector<FunctionPointer> converters; bool supportsVectorMode; bool foundScalar = false; foundScalar |= FunctionLibrary::getInstance()->findFunction( aggregate->getName(), inputTypes, functDescription, converters, supportsVectorMode, true); foundScalar |= FunctionLibrary::getInstance()->findFunction( aggregate->getName(), inputTypes, functDescription, converters, supportsVectorMode, false); if (foundScalar) { throw USER_EXCEPTION(SCIDB_SE_UDO, SCIDB_LE_CANNOT_ADD_AGGREGATE) << aggregate->getName(); } const FactoriesMap::const_iterator i = _registeredFactories.find(aggregate->getName()); if (i != _registeredFactories.end()) { const FactoriesMap::value_type::second_type::const_iterator i2 = i->second.find(aggregate->getAggregateType().typeId()); if (i2 != i->second.end()) throw SYSTEM_EXCEPTION(SCIDB_SE_INTERNAL, SCIDB_LE_DUPLICATE_AGGREGATE_FACTORY); } _registeredFactories[aggregate->getName()][aggregate->getAggregateType().typeId()] = aggregate; }
int main() { sf::RenderWindow window; sf::ContextSettings glContextSettings; glContextSettings.antialiasingLevel = 4; window.create(sf::VideoMode(800, 600), "BIDInet", sf::Style::Default, glContextSettings); window.setFramerateLimit(60); window.setVerticalSyncEnabled(true); std::mt19937 generator(time(nullptr)); /*sys::ComputeSystem cs; cs.create(sys::ComputeSystem::_gpu); sys::ComputeProgram program; program.loadFromFile("resources/bidinet.cl", cs); bidi::BIDInet bidinet; std::vector<bidi::BIDInet::InputType> inputTypes(64, bidi::BIDInet::_state); const int numStates = 3 + 3 + 2 + 2 + 1 + 2 + 2; const int numActions = 3 + 3 + 2 + 2; const int numQ = 8; for (int i = 0; i < numStates; i++) inputTypes[i] = bidi::BIDInet::_state; for (int i = 0; i < numActions; i++) inputTypes[numStates + i] = bidi::BIDInet::_action; std::vector<bidi::BIDInet::LayerDesc> layerDescs(2); layerDescs[0]._fbRadius = 16; layerDescs[1]._width = 8; layerDescs[1]._height = 8; bidinet.createRandom(cs, program, 8, 8, inputTypes, layerDescs, -0.1f, 0.1f, 0.001f, 1.0f, generator);*/ // Physics std::shared_ptr<b2World> world = std::make_shared<b2World>(b2Vec2(0.0f, -9.81f)); const float pixelsPerMeter = 256.0f; const float groundWidth = 5000.0f; const float groundHeight = 5.0f; // Create ground b2BodyDef groundBodyDef; groundBodyDef.position.Set(0.0f, 0.0f); b2Body* groundBody = world->CreateBody(&groundBodyDef); b2PolygonShape groundBox; groundBox.SetAsBox(groundWidth * 0.5f, groundHeight * 0.5f); groundBody->CreateFixture(&groundBox, 0.0f); sf::Texture skyTexture; skyTexture.loadFromFile("resources/background1.png"); skyTexture.setSmooth(true); sf::Texture floorTexture; floorTexture.loadFromFile("resources/floor1.png"); floorTexture.setRepeated(true); floorTexture.setSmooth(true); Runner runner0; runner0.createDefault(world, b2Vec2(0.0f, 2.762f), 0.0f, 1); //Runner runner1; //runner1.createDefault(world, b2Vec2(0.0f, 2.762f), 0.0f, 2); //deep::FERL ferl; const int recCount = 4; const int clockCount = 4; //ferl.createRandom(3 + 3 + 2 + 2 + 1 + 2 + 2 + recCount + clockCount, 3 + 3 + 2 + 2 + recCount, 32, 0.01f, generator); //std::vector<float> prevAction(ferl.getNumAction(), 0.0f); deep::CSRL prsdr; const int inputCount = 3 + 3 + 2 + 2 + 1 + 2 + 2 + recCount + clockCount + 1; const int outputCount = 3 + 3 + 2 + 2 + recCount; std::vector<deep::CSRL::LayerDesc> layerDescs(2); layerDescs[0]._width = 8; layerDescs[0]._height = 8; layerDescs[1]._width = 4; layerDescs[1]._height = 4; std::vector<sdr::IPRSDRRL::InputType> inputTypes(7 * 7, sdr::IPRSDRRL::_state); prsdr.createRandom(7, 7, 8, layerDescs, -0.01f, 0.01f, 0.5f, generator); //deep::SDRRL sdrrl; //sdrrl.createRandom(inputCount, outputCount, 32, -0.01f, 0.01f, 0.0f, generator); // ---------------------------- Game Loop ----------------------------- sf::View view = window.getDefaultView(); bool quit = false; sf::Clock clock; float dt = 0.017f; int steps = 0; do { clock.restart(); // ----------------------------- Input ----------------------------- sf::Event windowEvent; while (window.pollEvent(windowEvent)) { switch (windowEvent.type) { case sf::Event::Closed: quit = true; break; } } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) quit = true; //bidinet.simStep(cs, 0.0f, 0.98f, 0.001f, 0.95f, 0.01f, 0.01f, generator); const float maxRunnerBodyAngle = 0.3f; const float runnerBodyAngleStab = 10.0f; { float reward; if (sf::Keyboard::isKeyPressed(sf::Keyboard::K)) reward = -runner0._pBody->GetLinearVelocity().x; else reward = runner0._pBody->GetLinearVelocity().x; std::vector<float> state; runner0.getStateVector(state); std::vector<float> action(3 + 3 + 2 + 2 + recCount); for (int a = 0; a < recCount; a++) state.push_back(prsdr.getPrediction(inputCount + outputCount - recCount + a)); for (int a = 0; a < clockCount; a++) state.push_back(std::sin(steps / 60.0f * 2.0f * a * 2.0f * 3.141596f)); for (int i = 0; i < state.size(); i++) prsdr.setInput(i, state[i]); //sdrrl.simStep(reward, 0.1f, 0.99f, 16, 0.01f, 0.01f, 0.01f, 0.01f, 16, 0.05f, 0.98f, 0.05f, 0.01f, 0.01f, 4.0f, generator); prsdr.simStep(reward, generator); for (int i = 0; i < action.size(); i++) action[i] = prsdr.getPrediction(inputCount + i) * 0.5f + 0.5f; runner0.motorUpdate(action, 12.0f); // Keep upright if (std::abs(runner0._pBody->GetAngle()) > maxRunnerBodyAngle) runner0._pBody->SetAngularVelocity(-runnerBodyAngleStab * runner0._pBody->GetAngle()); } /*{ float reward; if (sf::Keyboard::isKeyPressed(sf::Keyboard::K)) reward = -runner1._pBody->GetLinearVelocity().x; else reward = runner1._pBody->GetLinearVelocity().x; std::vector<float> state; runner1.getStateVector(state); std::vector<float> action(3 + 3 + 2 + 2 + recCount); for (int a = 0; a < recCount; a++) state.push_back(prevAction[prevAction.size() - recCount + a]); for (int a = 0; a < clockCount; a++) state.push_back(std::sin(steps / 60.0f * 2.0f * a * 2.0f * 3.141596f)); // Bias state.push_back(1.0f); //ferl.step(state, action, reward, 0.5f, 0.99f, 0.98f, 0.05f, 16, 4, 0.05f, 0.01f, 0.05f, 600, 64, 0.01f, generator); for (int i = 0; i < action.size(); i++) action[i] = action[i] * 0.5f + 0.5f; prevAction = action; runner1.motorUpdate(action, 12.0f); // Keep upright if (std::abs(runner1._pBody->GetAngle()) > maxRunnerBodyAngle) runner1._pBody->SetAngularVelocity(-runnerBodyAngleStab * runner1._pBody->GetAngle()); }*/ int subSteps = 1; for (int ss = 0; ss < subSteps; ss++) { world->ClearForces(); world->Step(1.0f / 60.0f / subSteps, 64, 64); } if (!sf::Keyboard::isKeyPressed(sf::Keyboard::T) || steps % 200 == 1) { // ------------------------------------------------------------------- //if (!sf::Keyboard::isKeyPressed(sf::Keyboard::B)) // view.setCenter(runner1._pBody->GetPosition().x * pixelsPerMeter, -runner1._pBody->GetPosition().y * pixelsPerMeter); //else view.setCenter(runner0._pBody->GetPosition().x * pixelsPerMeter, -runner0._pBody->GetPosition().y * pixelsPerMeter); // Draw sky sf::Sprite skySprite; skySprite.setTexture(skyTexture); window.setView(window.getDefaultView()); window.draw(skySprite); window.setView(view); sf::RectangleShape floorShape; floorShape.setSize(sf::Vector2f(groundWidth * pixelsPerMeter, groundHeight * pixelsPerMeter)); floorShape.setTexture(&floorTexture); floorShape.setTextureRect(sf::IntRect(0, 0, groundWidth * pixelsPerMeter, groundHeight * pixelsPerMeter)); floorShape.setOrigin(sf::Vector2f(groundWidth * pixelsPerMeter * 0.5f, groundHeight * pixelsPerMeter * 0.5f)); window.draw(floorShape); //runner1.renderDefault(window, sf::Color::Blue, pixelsPerMeter); runner0.renderDefault(window, sf::Color::Red, pixelsPerMeter); /*sf::Image img; img.create(sdrrl.getNumCells(), 1); for (int i = 0; i < sdrrl.getNumCells(); i++) { sf::Color c = sf::Color::Black; c.r = c.g = c.b = 255.0f * (sdrrl.getCellState(i) > 0.0f ? 1.0f : 0.0f); img.setPixel(i, 0, c); } float scale = 4.0f; sf::Texture tex; tex.loadFromImage(img); sf::Sprite s; s.setTexture(tex); s.setScale(sf::Vector2f(scale, scale)); s.setPosition(sf::Vector2f(0.0f, window.getSize().y - scale * img.getSize().y)); window.setView(window.getDefaultView()); window.draw(s);*/ window.setView(view); window.display(); } else { if (steps % 100 == 0) std::cout << "Steps: " << steps << " Distance: " << runner0._pBody->GetPosition().x << std::endl; } //dt = clock.getElapsedTime().asSeconds(); steps++; } while (!quit); world->DestroyBody(groundBody); return 0; }
int main() { std::mt19937 generator(time(nullptr)); _ballPosition = sf::Vector2f(0.5f, 0.5f); _ballVelocity = sf::Vector2f(0.44f, 0.55f); _ballVelocity *= ballSpeed / std::sqrt(_ballVelocity.x * _ballVelocity.x + _ballVelocity.y * _ballVelocity.y); _paddlePosition = 0.5f; std::uniform_real_distribution<float> dist01(0.0f, 1.0f); sf::RenderWindow window; window.create(sf::VideoMode(800, 800), "BIDInet", sf::Style::Default); window.setFramerateLimit(60); window.setVerticalSyncEnabled(true); sf::RenderTexture visionRT; visionRT.create(16, 16); deep::CSRL agent; std::vector<deep::CSRL::LayerDesc> layerDescs(3); layerDescs[0]._width = 6; layerDescs[0]._height = 6; layerDescs[1]._width = 5; layerDescs[1]._height = 5; layerDescs[2]._width = 4; layerDescs[2]._height = 4; int inWidth = 16; int inHeight = 18; std::vector<deep::CSRL::InputType> inputTypes(inWidth * inHeight, deep::CSRL::_state); for (int i = 0; i < inWidth; i++) { inputTypes[i + (inHeight - 2) * inWidth] = deep::CSRL::_action; inputTypes[i + (inHeight - 1) * inWidth] = deep::CSRL::_q; } agent.createRandom(inWidth, inHeight, 8, inputTypes, layerDescs, -0.01f, 0.01f, 0.01f, 0.05f, 0.2f, generator); // ---------------------------- Game Loop ----------------------------- bool quit = false; sf::Clock clock; float dt = 0.017f; float averageReward = 0.0f; const float averageRewardDecay = 0.003f; int steps = 0; do { clock.restart(); // ----------------------------- Input ----------------------------- sf::Event windowEvent; while (window.pollEvent(windowEvent)) { switch (windowEvent.type) { case sf::Event::Closed: quit = true; break; } } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) quit = true; visionRT.clear(); renderScene(visionRT); visionRT.display(); sf::Image img = visionRT.getTexture().copyToImage(); for (int x = 0; x < img.getSize().x; x++) for (int y = 0; y < img.getSize().y; y++) { sf::Color c = img.getPixel(x, y); /*float valR = 0.0f; float valG = 0.0f; if (c.r > 0) valR = 1.0f; if (c.g > 0) valG = 1.0f; swarm.setState(x, y, 0, valR); swarm.setState(x, y, 1, valG);*/ float val = 0.0f; if (c.r > 0) val = 0.5f; if (c.g > 0) val = 1.0f; agent.setInput(x, y, val); } float reward = 0.0f; if (_ballPosition.x < 0.0f) { _ballPosition.x = 0.0f; _ballVelocity.x *= -1.0f; } if (_ballPosition.y < 0.0f) { _ballPosition.y = 0.0f; _ballVelocity.y *= -1.0f; } if (_ballPosition.x > 1.0f) { _ballPosition.x = 1.0f; _ballVelocity.x *= -1.0f; } if (_ballPosition.y > 1.0f - bottomRatio) { _ballPosition.y = 1.0f - bottomRatio; if (_ballPosition.x > _paddlePosition - paddleWidthRatio && _ballPosition.x < _paddlePosition + paddleWidthRatio) { reward += 10.0f; } else reward -= 5.0f; _ballVelocity.y *= -1.0f; } _ballPosition += _ballVelocity; averageReward = (1.0f - averageRewardDecay) * averageReward + averageRewardDecay * reward; agent.simStep(reward, generator); float act = 0.0f; for (int i = 4; i < 5; i++) { act += agent.getPrediction(i, 16); } _paddlePosition = std::min(1.0f, std::max(0.0f, _paddlePosition + 0.1f * std::min(1.0f, std::max(-1.0f, act)))); //std::cout << averageReward << std::endl; if (!sf::Keyboard::isKeyPressed(sf::Keyboard::T)) { window.clear(); renderScene(window); sf::Sprite vis; vis.setTexture(visionRT.getTexture()); vis.setScale(4.0f, 4.0f); window.draw(vis); sf::Image predImg; predImg.create(16, 17); for (int x = 0; x < 16; x++) for (int y = 0; y < 17; y++) { sf::Color c = sf::Color::White; c.r = c.g = c.b = 255.0f * std::min(1.0f, std::max(0.0f, agent.getPrediction(x, y))); predImg.setPixel(x, y, c); } sf::Texture t; t.loadFromImage(predImg); sf::Sprite s; s.setTexture(t); s.setScale(4.0f, 4.0f); s.setPosition(4.0f * 16.0f, 0.0f); window.draw(s); window.display(); } if (steps % 100 == 0) std::cout << "Steps: " << steps << " Average Reward: " << averageReward << std::endl; //dt = clock.getElapsedTime().asSeconds(); steps++; } while (!quit); return 0; }
int main() { std::mt19937 generator(time(nullptr)); sf::RenderWindow renderWindow; renderWindow.create(sf::VideoMode(1280, 720), "Reinforcement Learning", sf::Style::Default); renderWindow.setVerticalSyncEnabled(true); renderWindow.setFramerateLimit(60); // ---------------------------------- RL Init ------------------------------------ /*sc::HTSLPVLV agentBlue; sc::HTSLPVLV agentRed; std::vector<sc::HTSLPVLV::InputType> inputTypes(20); for (int i = 0; i < 12; i++) inputTypes[i] = sc::HTSLPVLV::_state; for (int i = 12; i < 14; i++) inputTypes[i] = sc::HTSLPVLV::_action; for (int i = 14; i < 16; i++) inputTypes[i] = sc::HTSLPVLV::_pv; for (int i = 16; i < 18; i++) inputTypes[i] = sc::HTSLPVLV::_lve; for (int i = 18; i < 20; i++) inputTypes[i] = sc::HTSLPVLV::_lvi; std::vector<sc::HTSL::LayerDesc> layerDescs(2); layerDescs[0]._width = 20; layerDescs[0]._height = 20; layerDescs[1]._width = 12; layerDescs[1]._height = 12; //layerDescs[2]._width = 8; //layerDescs[2]._height = 8; agentBlue.createRandom(5, 4, 8, inputTypes, layerDescs, generator); agentRed.createRandom(5, 4, 8, inputTypes, layerDescs, generator);*/ float rewardTimer = 0.0f; float rewardTime = 0.25f; float lastReward = 0.5f; //sc::HTSLSARSA agentBlue; sc::HTSLSARSA agentRed; std::vector<sc::HTSLSARSA::InputType> inputTypes(16); for (int i = 0; i < 12; i++) inputTypes[i] = sc::HTSLSARSA::_state; for (int i = 12; i < 14; i++) inputTypes[i] = sc::HTSLSARSA::_action; for (int i = 14; i < 16; i++) inputTypes[i] = sc::HTSLSARSA::_q; std::vector<sc::HTSL::LayerDesc> layerDescs(3); layerDescs[0]._width = 28; layerDescs[0]._height = 28; layerDescs[1]._width = 18; layerDescs[1]._height = 18; layerDescs[2]._width = 12; layerDescs[2]._height = 12; //agentBlue.createRandom(4, 4, 8, inputTypes, layerDescs, generator); agentRed.createRandom(4, 4, 8, inputTypes, layerDescs, generator); //deep::FERL agentBlue; //agentBlue.createRandom(12, 2, 32, 0.01f, generator); //deep::FERL agentRed; //agentRed.createRandom(12, 2, 32, 0.01f, generator); // --------------------------------- Game Init ----------------------------------- const float slimeRadius = 94.5f; const float ballRadius = 23.5f; const float wallRadius = 22.5f; const float fieldRadius = 640.0f; const float gravity = 900.0f; const float slimeBounce = 100.0f; const float wallBounceDecay = 0.8f; const float slimeJump = 500.0f; const float maxSlimeSpeed = 1000.0f; const float slimeMoveAccel = 5000.0f; const float slimeMoveDeccel = 8.0f; std::uniform_real_distribution<float> dist01(0.0f, 1.0f); sf::Vector2f fieldCenter = sf::Vector2f(renderWindow.getSize().x * 0.5f, renderWindow.getSize().y * 0.5f + 254.0f); sf::Vector2f wallCenter = fieldCenter + sf::Vector2f(0.0f, -182.0f); PhyObj blue; PhyObj red; PhyObj ball; blue._position = fieldCenter + sf::Vector2f(-200.0f, 0.0f); blue._velocity = sf::Vector2f(0.0f, 0.0f); red._position = fieldCenter + sf::Vector2f(200.0f, 0.0f); red._velocity = sf::Vector2f(0.0f, 0.0f); ball._position = fieldCenter + sf::Vector2f(2.0f, -300.0f); ball._velocity = sf::Vector2f((dist01(generator)) * 600.0f, -(dist01(generator)) * 500.0f); sf::Texture backgroundTexture; backgroundTexture.loadFromFile("resources/slimevolleyball/background.png"); sf::Texture blueSlimeTexture; blueSlimeTexture.loadFromFile("resources/slimevolleyball/slimeBodyBlue.png"); sf::Texture redSlimeTexture; redSlimeTexture.loadFromFile("resources/slimevolleyball/slimeBodyRed.png"); sf::Texture ballTexture; ballTexture.loadFromFile("resources/slimevolleyball/ball.png"); sf::Texture eyeTexture; eyeTexture.loadFromFile("resources/slimevolleyball/slimeEye.png"); eyeTexture.setSmooth(true); sf::Texture arrowTexture; arrowTexture.loadFromFile("resources/slimevolleyball/arrow.png"); sf::Font scoreFont; scoreFont.loadFromFile("resources/slimevolleyball/scoreFont.ttf"); int scoreRed = 0; int scoreBlue = 0; int prevScoreRed = 0; int prevScoreBlue = 0; float prevBallX = fieldCenter.x; // ------------------------------- Simulation Loop ------------------------------- bool noRender = false; bool prevPressK = false; bool quit = false; float dt = 0.017f; do { sf::Event event; while (renderWindow.pollEvent(event)) { switch (event.type) { case sf::Event::Closed: quit = true; break; } } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) quit = true; // ---------------------------------- Physics ---------------------------------- bool blueBounced = false; bool redBounced = false; // Ball { ball._velocity.y += gravity * dt; ball._position += ball._velocity * dt; // To floor (game restart) if (ball._position.y + ballRadius > fieldCenter.y) { if (ball._position.x < fieldCenter.x) scoreRed++; else scoreBlue++; blue._position = fieldCenter + sf::Vector2f(-200.0f, 0.0f); blue._velocity = sf::Vector2f(0.0f, 0.0f); red._position = fieldCenter + sf::Vector2f(200.0f, 0.0f); red._velocity = sf::Vector2f(0.0f, 0.0f); ball._position = fieldCenter + sf::Vector2f(2.0f, -300.0f); ball._velocity = sf::Vector2f((dist01(generator)) * 600.0f, -(dist01(generator)) * 500.0f); } // To wall if (((ball._position.x + ballRadius) > (wallCenter.x - wallRadius) && ball._position.x < wallCenter.x) || ((ball._position.x - ballRadius) < (wallCenter.x + wallRadius) && ball._position.x > wallCenter.x)) { // If above rounded part if (ball._position.y < wallCenter.y) { sf::Vector2f delta = ball._position - wallCenter; float dist = std::sqrt(delta.x * delta.x + delta.y * delta.y); if (dist < wallRadius + ballRadius) { sf::Vector2f normal = delta / dist; // Reflect velocity sf::Vector2f reflectedVelocity = ball._velocity - 2.0f * (ball._velocity.x * normal.x + ball._velocity.y * normal.y) * normal; ball._velocity = reflectedVelocity * wallBounceDecay; ball._position = wallCenter + normal * (wallRadius + ballRadius); } } else { // If on left side if (ball._position.x < wallCenter.x) { ball._velocity.x = wallBounceDecay * -ball._velocity.x; ball._position.x = wallCenter.x - wallRadius - ballRadius; } else { ball._velocity.x = wallBounceDecay * -ball._velocity.x; ball._position.x = wallCenter.x + wallRadius + ballRadius; } } } // To blue slime { sf::Vector2f delta = ball._position - blue._position; float dist = std::sqrt(delta.x * delta.x + delta.y * delta.y); if (dist < slimeRadius + ballRadius) { sf::Vector2f normal = delta / dist; // Reflect velocity sf::Vector2f reflectedVelocity = ball._velocity - 2.0f * (ball._velocity.x * normal.x + ball._velocity.y * normal.y) * normal; float magnitude = std::sqrt(reflectedVelocity.x * reflectedVelocity.x + reflectedVelocity.y * reflectedVelocity.y); sf::Vector2f normalizedReflected = reflectedVelocity / magnitude; ball._velocity = blue._velocity + (magnitude > slimeBounce ? reflectedVelocity : normalizedReflected * slimeBounce); ball._position = blue._position + normal * (wallRadius + slimeRadius); blueBounced = true; } } // To red slime { sf::Vector2f delta = ball._position - red._position; float dist = std::sqrt(delta.x * delta.x + delta.y * delta.y); if (dist < slimeRadius + ballRadius) { sf::Vector2f normal = delta / dist; // Reflect velocity sf::Vector2f reflectedVelocity = ball._velocity - 2.0f * (ball._velocity.x * normal.x + ball._velocity.y * normal.y) * normal; float magnitude = std::sqrt(reflectedVelocity.x * reflectedVelocity.x + reflectedVelocity.y * reflectedVelocity.y); sf::Vector2f normalizedReflected = reflectedVelocity / magnitude; ball._velocity = red._velocity + (magnitude > slimeBounce ? reflectedVelocity : normalizedReflected * slimeBounce); ball._position = red._position + normal * (wallRadius + slimeRadius); redBounced = true; } } // Out of field, left and right { if (ball._position.x - ballRadius < fieldCenter.x - fieldRadius) { ball._velocity.x = wallBounceDecay * -ball._velocity.x; ball._position.x = fieldCenter.x - fieldRadius + ballRadius; } else if (ball._position.x + ballRadius > fieldCenter.x + fieldRadius) { ball._velocity.x = wallBounceDecay * -ball._velocity.x; ball._position.x = fieldCenter.x + fieldRadius - ballRadius; } } } // Blue slime { blue._velocity.y += gravity * dt; blue._velocity.x += -slimeMoveDeccel * blue._velocity.x * dt; blue._position += blue._velocity * dt; if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { blue._velocity.x += -slimeMoveAccel * dt; if (blue._velocity.x < -maxSlimeSpeed) blue._velocity.x = -maxSlimeSpeed; } else if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { blue._velocity.x += slimeMoveAccel * dt; if (blue._velocity.x > maxSlimeSpeed) blue._velocity.x = maxSlimeSpeed; } if (blue._position.y > fieldCenter.y) { blue._velocity.y = 0.0f; blue._position.y = fieldCenter.y; if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) blue._velocity.y -= slimeJump; } if (blue._position.x - slimeRadius < fieldCenter.x - fieldRadius) { blue._velocity.x = 0.0f; blue._position.x = fieldCenter.x - fieldRadius + slimeRadius; } if (blue._position.x + slimeRadius > wallCenter.x - wallRadius) { blue._velocity.x = 0.0f; blue._position.x = wallCenter.x - wallRadius - slimeRadius; } } // Blue slime /*{ const float scalar = 0.001f; // Percepts std::vector<float> inputs(12); int index = 0; inputs[index++] = (ball._position.x - blue._position.x) * scalar; inputs[index++] = (ball._position.y - blue._position.y) * scalar; inputs[index++] = ball._velocity.x * scalar; inputs[index++] = ball._velocity.y * scalar; inputs[index++] = (red._position.x - blue._position.x) * scalar; inputs[index++] = (red._position.y - blue._position.y) * scalar; inputs[index++] = red._velocity.x * scalar; inputs[index++] = red._velocity.y * scalar; inputs[index++] = blue._position.x * scalar; inputs[index++] = blue._position.y * scalar; inputs[index++] = blue._velocity.x * scalar; inputs[index++] = blue._velocity.y * scalar; std::vector<float> outputs(2); // Actions for (int i = 0; i < 12; i++) agentBlue.setState(i, inputs[i]); float reward = (ball._position.x > fieldCenter.x && prevBallX < fieldCenter.x ? 1.0f : 0.5f) * 0.5f + (scoreRed > prevScoreRed ? 0.0f : 0.5f) * 0.5f; if (reward != 0.5f) { lastReward = reward = reward > 0.5f ? 1.0f : 0.0f; rewardTimer = 0.0f; } else if (rewardTimer < rewardTime) { reward = lastReward; rewardTimer += dt; } if (blueBounced) reward = std::max(reward, 0.55f); reward = (reward * 2.0f - 1.0f) * 0.01f - std::abs(ball._position.x - blue._position.x) * 0.001f; //reward = (scoreBlue - prevScoreBlue) - (scoreRed - prevScoreRed) - std::abs(ball._position.x - blue._position.x) * 0.001f; agentBlue.update(reward, generator); float move = agentBlue.getActionFromNodeIndex(0) * 2.0f - 1.0f; bool jump = agentBlue.getActionFromNodeIndex(1) > 0.5f; //std::vector<float> action(2); //agentBlue.step(inputs, action, reward, 0.01f, 0.995f, 0.99f, 10.0f, 64, 3, 0.02f, 0.04f, 0.04f, 800, 200, 0.003f, 0.0f, generator); //float move = action[0]; //bool jump = action[1] > 0.0f; blue._velocity.y += gravity * dt; blue._velocity.x += -slimeMoveDeccel * blue._velocity.x * dt; blue._position += blue._velocity * dt; { blue._velocity.x += move * slimeMoveAccel * dt; if (blue._velocity.x < -maxSlimeSpeed) blue._velocity.x = -maxSlimeSpeed; else if (blue._velocity.x > maxSlimeSpeed) blue._velocity.x = maxSlimeSpeed; } if (blue._position.y > fieldCenter.y) { blue._velocity.y = 0.0f; blue._position.y = fieldCenter.y; if (jump) blue._velocity.y -= slimeJump; } if (blue._position.x - slimeRadius < fieldCenter.x - fieldRadius) { blue._velocity.x = 0.0f; blue._position.x = fieldCenter.x - fieldRadius + slimeRadius; } if (blue._position.x + slimeRadius > wallCenter.x - wallRadius) { blue._velocity.x = 0.0f; blue._position.x = wallCenter.x - wallRadius - slimeRadius; } }*/ // Red slime { const float scalar = 0.001f; // Percepts std::vector<float> inputs(12); int index = 0; inputs[index++] = (ball._position.x - red._position.x) * scalar; inputs[index++] = (ball._position.y - red._position.y) * scalar; inputs[index++] = ball._velocity.x * scalar; inputs[index++] = ball._velocity.y * scalar; inputs[index++] = (blue._position.x - red._position.x) * scalar; inputs[index++] = (blue._position.y - red._position.y) * scalar; inputs[index++] = red._velocity.x * scalar; inputs[index++] = red._velocity.y * scalar; inputs[index++] = blue._position.x * scalar; inputs[index++] = blue._position.y * scalar; inputs[index++] = blue._velocity.x * scalar; inputs[index++] = blue._velocity.y * scalar; //std::vector<float> outputs(2); // Actions for (int i = 0; i < 12; i++) agentRed.setState(i, inputs[i]); float reward = (ball._position.x < fieldCenter.x && prevBallX >= fieldCenter.x ? 1.0f : 0.5f); if (reward != 0.5f) { lastReward = reward = reward > 0.5f ? 1.0f : 0.0f; rewardTimer = 0.0f; } else if (rewardTimer < rewardTime) { reward = lastReward; rewardTimer += dt; } if (redBounced) reward = std::max(reward, 0.55f); reward = (reward * 2.0f - 1.0f) * 0.1f - std::abs(ball._position.x - red._position.x) * 0.008f; //reward *= 0.05f; //reward = (scoreRed - prevScoreRed) - (scoreBlue - prevScoreBlue) - std::abs(ball._position.x - red._position.x) * 0.001f; //std::cout << "Reward: " << reward << std::endl; //agentRed.update(reward, generator); agentRed.update(reward, generator); //std::vector<float> action(2); //agentRed.step(inputs, action, reward, 0.01f, 0.995f, 0.99f, 10.0f, 32, 6, 0.05f, 0.04f, 0.04f, 800, 200, 0.003f, 0.0f, generator); //float move = action[0]; //bool jump = action[1] > 0.0f; float move = agentRed.getActionFromNodeIndex(0) * 2.0f - 1.0f; bool jump = agentRed.getActionFromNodeIndex(1) > 0.5f; red._velocity.y += gravity * dt; red._velocity.x += -slimeMoveDeccel * red._velocity.x * dt; red._position += red._velocity * dt; { red._velocity.x += move * slimeMoveAccel * dt; if (red._velocity.x < -maxSlimeSpeed) red._velocity.x = -maxSlimeSpeed; else if (red._velocity.x > maxSlimeSpeed) red._velocity.x = maxSlimeSpeed; } if (red._position.y > fieldCenter.y) { red._velocity.y = 0.0f; red._position.y = fieldCenter.y; if (jump) red._velocity.y -= slimeJump; } if (red._position.x + slimeRadius > fieldCenter.x + fieldRadius) { red._velocity.x = 0.0f; red._position.x = fieldCenter.x + fieldRadius - slimeRadius; } if (red._position.x - slimeRadius < wallCenter.x + wallRadius) { red._velocity.x = 0.0f; red._position.x = wallCenter.x + wallRadius + slimeRadius; } } prevScoreRed = scoreRed; prevScoreBlue = scoreBlue; prevBallX = ball._position.x; if (sf::Keyboard::isKeyPressed(sf::Keyboard::K) && !prevPressK) { noRender = !noRender; } prevPressK = sf::Keyboard::isKeyPressed(sf::Keyboard::K); if (noRender) continue; // --------------------------------- Rendering --------------------------------- renderWindow.clear(); { sf::Sprite s; s.setTexture(backgroundTexture); s.setOrigin(backgroundTexture.getSize().x * 0.5f, backgroundTexture.getSize().y * 0.5f); s.setPosition(renderWindow.getSize().x * 0.5f, renderWindow.getSize().y * 0.5f); renderWindow.draw(s); } { sf::Sprite s; s.setTexture(blueSlimeTexture); s.setOrigin(blueSlimeTexture.getSize().x * 0.5f, blueSlimeTexture.getSize().y); s.setPosition(blue._position); renderWindow.draw(s); } { sf::Sprite s; s.setTexture(eyeTexture); s.setOrigin(eyeTexture.getSize().x * 0.5f, eyeTexture.getSize().y * 0.5f); s.setPosition(blue._position + sf::Vector2f(50.0f, -28.0f)); sf::Vector2f delta = ball._position - s.getPosition(); float angle = std::atan2(delta.y, delta.x); s.setRotation(angle * 180.0f / 3.141596f); renderWindow.draw(s); } { sf::Sprite s; s.setTexture(redSlimeTexture); s.setOrigin(redSlimeTexture.getSize().x * 0.5f, redSlimeTexture.getSize().y); s.setPosition(red._position); renderWindow.draw(s); } { sf::Sprite s; s.setTexture(eyeTexture); s.setOrigin(eyeTexture.getSize().x * 0.5f, eyeTexture.getSize().y * 0.5f); s.setPosition(red._position + sf::Vector2f(-50.0f, -28.0f)); sf::Vector2f delta = ball._position - s.getPosition(); float angle = std::atan2(delta.y, delta.x); s.setRotation(angle * 180.0f / 3.141596f); renderWindow.draw(s); } { sf::Sprite s; s.setTexture(ballTexture); s.setOrigin(ballTexture.getSize().x * 0.5f, ballTexture.getSize().y * 0.5f); s.setPosition(ball._position); renderWindow.draw(s); } if (ball._position.y + ballRadius < 0.0f) { sf::Sprite s; s.setTexture(arrowTexture); s.setOrigin(arrowTexture.getSize().x * 0.5f, 0.0f); s.setPosition(ball._position.x, 0.0f); renderWindow.draw(s); } { sf::Text scoreText; scoreText.setFont(scoreFont); scoreText.setString(std::to_string(scoreBlue)); scoreText.setCharacterSize(100); float width = scoreText.getLocalBounds().width; scoreText.setPosition(fieldCenter.x - width * 0.5f - 100.0f, 10.0f); scoreText.setColor(sf::Color(100, 133, 255)); renderWindow.draw(scoreText); } { sf::Text scoreText; scoreText.setFont(scoreFont); scoreText.setString(std::to_string(scoreRed)); scoreText.setCharacterSize(100); float width = scoreText.getLocalBounds().width; scoreText.setPosition(fieldCenter.x - width * 0.5f + 100.0f, 10.0f); scoreText.setColor(sf::Color(255, 100, 100)); renderWindow.draw(scoreText); } if (sf::Keyboard::isKeyPressed(sf::Keyboard::P)) { float scale = 4.0f; float alignment = 0.0f; /*for (int l = 0; l < agentBlue.getHTSL().getLayers().size(); l++) { sf::Image sdr; sdr.create(agentBlue.getHTSL().getLayerDescs()[l]._width, agentBlue.getHTSL().getLayerDescs()[l]._height); for (int x = 0; x < agentBlue.getHTSL().getLayerDescs()[l]._width; x++) for (int y = 0; y < agentBlue.getHTSL().getLayerDescs()[l]._height; y++) { sf::Color c; c.r = c.g = c.b = agentBlue.getHTSL().getLayers()[l]._rsc.getHiddenState(x, y) * 255.0f; sdr.setPixel(x, y, c); } sf::Texture sdrt; sdrt.loadFromImage(sdr); sf::Sprite sdrs; sdrs.setTexture(sdrt); sdrs.setPosition(alignment, renderWindow.getSize().y - sdr.getSize().y * scale); sdrs.setScale(scale, scale); renderWindow.draw(sdrs); alignment += scale * sdr.getSize().x; }*/ alignment = 0.0f; for (int l = 0; l < agentRed.getHTSL().getLayers().size(); l++) { sf::Image sdr; sdr.create(agentRed.getHTSL().getLayerDescs()[l]._width, agentRed.getHTSL().getLayerDescs()[l]._height); for (int x = 0; x < agentRed.getHTSL().getLayerDescs()[l]._width; x++) for (int y = 0; y < agentRed.getHTSL().getLayerDescs()[l]._height; y++) { sf::Color c; c.r = c.g = c.b = agentRed.getHTSL().getLayers()[l]._rsc.getHiddenState(x, y) * 255.0f; sdr.setPixel(x, y, c); } sf::Texture sdrt; sdrt.loadFromImage(sdr); alignment += scale * sdr.getSize().x; sf::Sprite sdrs; sdrs.setTexture(sdrt); sdrs.setPosition(renderWindow.getSize().x - alignment, renderWindow.getSize().y - sdr.getSize().y * scale); sdrs.setScale(scale, scale); renderWindow.draw(sdrs); } } if (sf::Keyboard::isKeyPressed(sf::Keyboard::T)) { sf::Vector2f position; const float scalar = 1.0f / 0.001f; position.x = red._position.x + scalar * agentRed.getHTSL().getPrediction(0); position.y = red._position.y + scalar * agentRed.getHTSL().getPrediction(1); sf::Sprite s; s.setTexture(ballTexture); s.setOrigin(ballTexture.getSize().x * 0.5f, ballTexture.getSize().y * 0.5f); s.setPosition(position); renderWindow.draw(s); } if (sf::Keyboard::isKeyPressed(sf::Keyboard::F)) { for (int i = 0; i < 16; i++) std::cout << agentRed.getHTSL().getPrediction(i) << std::endl; std::cout << std::endl; } renderWindow.display(); } while (!quit); return 0; }