Skip to content

Instantly share code, notes, and snippets.

@iondune
Last active March 1, 2017 23:45
Show Gist options
  • Save iondune/5407ff41e7870bf7bb8fa4dc56d9525d to your computer and use it in GitHub Desktop.
Save iondune/5407ff41e7870bf7bb8fa4dc56d9525d to your computer and use it in GitHub Desktop.
Paint filling algorithm implemented in OO style!
#pragma once
#include <glm/glm.hpp>
namespace Relic
{
class CPaintFiller
{
public:
// Implement these two pure virtuals in a subclass!
// Return true if the pixel is part of the group you are trying to "fill"
// In the paint example, this would be true if the pixel is the same color as the pixel you clicked
virtual bool IsPixelInGroup(int x, int y) = 0;
// This function is called by this class when it finds a pixel that is "in the group"
// In the paint example, this would be where you change the color of the pixel to the "fill" color
// NOTE: My code expects that you make this change here!
// Otherwise it would keep looping around the same area in an infinite loop
// You need to modify the pixel so that IsPixelInGroup(...) is no longer true
virtual void SuccessCallback(int x, int y) = 0;
// Change this as appropriate
glm::ivec2 MapSize = glm::ivec2(640, 480);
int Run(int const StartX, int const StartY)
{
int NumberFilled = 0;
if (Check(StartX, StartY))
{
NumberFilled = 1;
while (! Queue.empty())
{
glm::ivec2 const Current = Queue.back();
Queue.pop_back();
int const u = Current.x;
int const v = Current.y;
NumberFilled += Check(u + 1, v);
NumberFilled += Check(u - 1, v);
NumberFilled += Check(u, v + 1);
NumberFilled += Check(u, v - 1);
}
}
return NumberFilled;
}
protected:
int Check(int const u, int const v)
{
if (u >= 0 && v >= 0 && u < MapSize.x && v < MapSize.y)
{
if (IsPixelInGroup(u, v))
{
SuccessCallback(u, v);
Queue.push_back(glm::ivec2(u, v));
return 1;
}
}
return 0;
}
vector<glm::ivec2> Queue;
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment