<commit_before>#include "Room.hpp"
#include "Player.hpp"
#include "Patron.hpp"

#include "../Application.hpp"

#include <SFML/Graphics/RenderTarget.hpp>
#include <SFML/Graphics/CircleShape.hpp>
#include <SFML/Graphics/RectangleShape.hpp>
#include <SFML/Graphics/Text.hpp>

#include <algorithm>
#include <random>

using namespace Game;

namespace
{
	static std::unordered_map<uint8_t, sf::Color> TileColors = {
		{ Room::Tile_Floor, sf::Color(0,0,0,0) },

		{ Room::Tile_Bar, sf::Color(110, 107, 23) },
		{ Room::Tile_Taps, sf::Color(110, 107, 23) },
		{ Room::Tile_Sink, sf::Color(110, 107, 23) },
		{ Room::Tile_Bottles, sf::Color(110, 107, 23) },
		{ Room::Tile_Seat, sf::Color(171, 89, 16) },
		{ Room::Tile_Stool, sf::Color(171, 89, 16) },
		{ Room::Tile_Table, sf::Color(110, 107, 23) }
	};

	template<typename T, typename U>
	float distance(const sf::Vector2<T>& a, const sf::Vector2<U>& b)
	{
		const float dX = b.x - a.x;
		const float dY = b.y - a.y;

		const float dDot = dX * dX + dY * dY;
		return sqrt(dDot);
	}
}

Room::Room()
{
	auto* ply = addObject<Player>();
	ply->setPosition(0, 1);

	setScale(10);
}

const sf::Vector2u& Room::getSize() const
{
	return mSize;
}
void Room::setSize(const sf::Vector2u& size)
{
	mSize = size;
	mTiles.resize(size.x * size.y);
	setOrigin(size.x / 2, size.y / 2);
}
Player* Room::getPlayer() const
{
	for (auto& obj : mObjects)
	{
		auto* ply = dynamic_cast<Player*>(obj.get());
		if (ply)
			return ply;
	}
	return nullptr;
}
Object* Room::getObject(const sf::Vector2u& pos) const
{
	for (auto& obj : mObjects)
		if (distance(pos, obj->getPosition()) <= 0.5)
			return obj.get();

	return nullptr;
}
Room::TileType Room::getTile(const sf::Vector2u& pos) const
{
	if (pos.x < mSize.x && pos.y < mSize.y)
	{
		uint32_t i = pos.y * mSize.x + pos.x;
		
		return mTiles[i];
	}

	return Tile_Floor;
}
void Room::setTile(const sf::Vector2u& pos, TileType type)
{
	if (pos.x < mSize.x && pos.y < mSize.y)
	{
		uint32_t i = pos.y * mSize.x + pos.x;

		mTiles[i] = type;
	}
}

void Room::repopulate()
{
	auto it = std::remove_if(mObjects.begin(), mObjects.end(), [](auto& obj) { return dynamic_cast<Patron*>(obj.get()); });
	if (it != mObjects.end())
		mObjects.erase(it, mObjects.end());

	auto seats = std::count_if(mTiles.begin(), mTiles.end(), [](auto t) { return t == Tile_Seat || t == Tile_Stool; });
	auto toFill = std::uniform_int_distribution<int>(1, seats)(std::random_device());

	auto xDist = std::uniform_int_distribution<int>(0, mSize.x);
	auto yDist = std::uniform_int_distribution<int>(0, mSize.y);

	for (int i = 0; i < toFill; ++i)
	{
		sf::Vector2u pos;
		do
		{
			pos = sf::Vector2u(xDist(std::random_device()), yDist(std::random_device()));
		} while (getTile(pos) != Tile_Seat && getTile(pos) != Tile_Stool && !getObject(pos));

		auto* patron = addObject<Patron>();
		patron->setPosition(sf::Vector2f(pos));
	}
}

float Room::getScale() const
{
	return sf::Transformable::getScale().x;
}<commit_msg>Better repopulation<commit_after>#include "Room.hpp"
#include "Player.hpp"
#include "Patron.hpp"

#include "../Application.hpp"

#include <SFML/Graphics/RenderTarget.hpp>
#include <SFML/Graphics/CircleShape.hpp>
#include <SFML/Graphics/RectangleShape.hpp>
#include <SFML/Graphics/Text.hpp>

#include <algorithm>
#include <random>

using namespace Game;

namespace
{
	static std::unordered_map<uint8_t, sf::Color> TileColors = {
		{ Room::Tile_Floor, sf::Color(0,0,0,0) },

		{ Room::Tile_Bar, sf::Color(110, 107, 23) },
		{ Room::Tile_Taps, sf::Color(110, 107, 23) },
		{ Room::Tile_Sink, sf::Color(110, 107, 23) },
		{ Room::Tile_Bottles, sf::Color(110, 107, 23) },
		{ Room::Tile_Seat, sf::Color(171, 89, 16) },
		{ Room::Tile_Stool, sf::Color(171, 89, 16) },
		{ Room::Tile_Table, sf::Color(110, 107, 23) }
	};

	template<typename T, typename U>
	float distance(const sf::Vector2<T>& a, const sf::Vector2<U>& b)
	{
		const float dX = b.x - a.x;
		const float dY = b.y - a.y;

		const float dDot = dX * dX + dY * dY;
		return sqrt(dDot);
	}
}

Room::Room()
{
	auto* ply = addObject<Player>();
	ply->setPosition(0, 1);

	setScale(10);
}

const sf::Vector2u& Room::getSize() const
{
	return mSize;
}
void Room::setSize(const sf::Vector2u& size)
{
	mSize = size;
	mTiles.resize(size.x * size.y);
	setOrigin(size.x / 2, size.y / 2);
}
Player* Room::getPlayer() const
{
	for (auto& obj : mObjects)
	{
		auto* ply = dynamic_cast<Player*>(obj.get());
		if (ply)
			return ply;
	}
	return nullptr;
}
Object* Room::getObject(const sf::Vector2u& pos) const
{
	for (auto& obj : mObjects)
		if (distance(pos, obj->getPosition()) <= 0.5)
			return obj.get();

	return nullptr;
}
Room::TileType Room::getTile(const sf::Vector2u& pos) const
{
	if (pos.x < mSize.x && pos.y < mSize.y)
	{
		uint32_t i = pos.y * mSize.x + pos.x;
		
		return mTiles[i];
	}

	return Tile_Floor;
}
void Room::setTile(const sf::Vector2u& pos, TileType type)
{
	if (pos.x < mSize.x && pos.y < mSize.y)
	{
		uint32_t i = pos.y * mSize.x + pos.x;

		mTiles[i] = type;
	}
}

void Room::repopulate()
{
	auto it = std::remove_if(mObjects.begin(), mObjects.end(), [](auto& obj) { return dynamic_cast<Patron*>(obj.get()); });
	if (it != mObjects.end())
		mObjects.erase(it, mObjects.end());

	const auto seats = std::count_if(mTiles.begin(), mTiles.end(), [](auto t) { return t == Tile_Seat || t == Tile_Stool; });
	const auto maxSeats = 3 * (seats / 4);

	auto toFill = std::uniform_int_distribution<int>(1, maxSeats)(std::random_device());

	auto xDist = std::uniform_int_distribution<int>(0, mSize.x);
	auto yDist = std::uniform_int_distribution<int>(0, mSize.y);

	for (int i = 0; i < toFill; ++i)
	{
		sf::Vector2u pos;
		do
		{
			pos = sf::Vector2u(xDist(std::random_device()), yDist(std::random_device()));
			const auto tile = getTile(pos);
			if ((tile == Tile_Seat || tile == Tile_Stool) && !getObject(pos))
				break;
		} while (true);

		auto* patron = addObject<Patron>();
		patron->setPosition(sf::Vector2f(pos));

		const auto tileTop = getTile(pos - sf::Vector2u{ 0, 1 }),
		           tileLeft = getTile(pos - sf::Vector2u{ 1, 0 }),
		           tileBottom = getTile(pos + sf::Vector2u{ 0, 1 }),
		           tileRight = getTile(pos + sf::Vector2u{ 1, 0 });

		if (tileTop == Tile_Table || tileTop == Tile_Bar)
			patron->setRotation(-90);
		else if (tileLeft == Tile_Table || tileLeft == Tile_Bar)
			patron->setRotation(180);
		else if (tileBottom == Tile_Table || tileBottom == Tile_Bar)
			patron->setRotation(90);
	}
}

float Room::getScale() const
{
	return sf::Transformable::getScale().x;
}
{'fraction_non_alphanumeric': 0.19051262433052793, 'fraction_numerical': 0.029227237949502678, 'mean_word_length': 4.33115823817292, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7513336', 'n_tokens_mistral': 2862, 'n_tokens_neox': 2610, 'n_words': 555}