Skip to content

Instantly share code, notes, and snippets.

@hota1024
Created August 24, 2018 09:08
Show Gist options
  • Save hota1024/d2469373b0046963e8f16ab452d3cead to your computer and use it in GitHub Desktop.
Save hota1024/d2469373b0046963e8f16ab452d3cead to your computer and use it in GitHub Desktop.
PhofifPuzzle
# include <Siv3D.hpp> // OpenSiv3D v0.2.8
const uint Width = 4;
const uint Height = 4;
const uint Area = Width * Height;
const uint TileSize = 64;
size_t GetIndex(int x, int y)
{
return y * Width + x;
}
Vec2 GetPoint(size_t i)
{
for (size_t x = 0; x < Width; ++x)
{
for (size_t y = 0; y < Height; ++y)
{
if (GetIndex(x, y) == i)
{
return Vec2(x, y);
}
}
}
return Vec2::Zero();
}
TextureRegion GetTexturePart(const DynamicTexture& texture, size_t i)
{
Vec2 pos = GetPoint(i) * TileSize;
return texture(pos.x + 200, pos.y + 64, TileSize, TileSize);
}
bool Swappable(int32 a, int32 b)
{
return (a / 4 == b / 4 && Abs(a - b) == 1) || (a % 4 == b % 4 && Abs(a - b) == 4);
}
size_t GetBlankIndex(const Array<int32>& tiles)
{
for (auto i : step(16))
{
if (tiles[i] == 15)
{
return i;
}
}
return 0;
}
void Main()
{
Webcam webcam(0);
webcam.setResolution(640, 480);
webcam.start();
Array<int32> tiles = Range(0, 15);
Optional<int32> grabbed;
{
int32 pos15 = 15;
for (int32 i = 0; i < 1000; ++i)
{
const int32 to = pos15 + RandomSelect({ -4, -1, 1, 4 });
if (InRange(to, 0, 15) && Swappable(pos15, to))
{
std::swap(tiles[pos15], tiles[to]);
pos15 = to;
}
}
}
DynamicTexture texture;
while (System::Update())
{
auto blankIndex = GetBlankIndex(tiles);
if (webcam.hasNewFrame())
{
webcam.getFrame(texture);
}
if (!MouseL.pressed())
{
grabbed = none;
}
for (auto i : step(16))
{
auto part = GetTexturePart(texture, tiles[i]);
auto rect = part.region(GetPoint(i) * TileSize).moveBy(64, 64);
if (tiles[i] == 15)
{
if (grabbed && rect.mouseOver() && Swappable(i, grabbed.value()))
{
std::swap(tiles[i], tiles[grabbed.value()]);
grabbed = i;
}
continue;
}
if (rect.leftClicked())
{
grabbed = i;
}
if (grabbed == i)
{
rect.draw(ColorF(1.0, 1.0, 1.0, 0.5));
}
if (rect.mouseOver())
{
Cursor::RequestStyle(CursorStyle::Hand);
}
rect.draw(Palette::White);
part.scaled(0.98).draw((GetPoint(i) * TileSize).movedBy(64, 64));
}
for (auto i : step(16))
{
auto part = GetTexturePart(texture, i);
part.draw((GetPoint(i) * TileSize).movedBy(64 + Width * TileSize, 64));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment