#include
#include "sweeper.h"
#define NODE_SIZE 30
#define NODE_MARGIN_Y 40
#define NODE_MARGIN_X 20
#define NODE_OFFSET 4
#define INF 100000
sf::RenderWindow* window;
Game* game = new Game;
sf::Font bit8;
sf::Texture flagIcon;
sf::Texture mineIcon;
sf::Texture crossIcon;
sf::Color numColors[9] = {
sf::Color(200, 200, 200), // Background (0) - No Number
sf::Color(0, 0, 255), // 1
sf::Color(0, 130, 0), // 2
sf::Color(245, 0, 0), // 3
sf::Color(0, 0, 130), // 4
sf::Color(130, 0, 0), // 5
sf::Color(0, 130, 130), // 6
sf::Color(0, 0, 0), // 7
sf::Color(130, 130, 130) // 8
};
sf::Vector2f centerText(int x, int y, sf::Text txt)
{
sf::FloatRect bounds = txt.getLocalBounds();
float bX = bounds.width;
float bY = bounds.height;
return sf::Vector2f (
x - bX/2,
y - bY/2
);
}
sf::Text getText(int size, std::string str, sf::Color col, sf::Text::Style* style)
{
sf::Text txt;
txt.setFont(bit8);
txt.setCharacterSize(size);
txt.setString(str);
txt.setFillColor(col);
if (style) txt.setStyle(*style);
return txt;
}
sf::RectangleShape getRect(sf::Vector2f size, sf::Vector2f pos, sf::Color col, int ot, sf::Color otcol)
{
sf::RectangleShape rect;
rect.setSize(size);
rect.setPosition(pos);
rect.setFillColor(col);
rect.setOutlineThickness(ot);
rect.setOutlineColor(otcol);
return rect;
}
sf::Sprite getSprite(sf::Texture* img, sf::Vector2f pos)
{
sf::Sprite sprite;
sprite.setTexture(*img);
sprite.setPosition(pos);
return sprite;
}
int closestFloor(int n, int m)
{
return floor((float) n/m)*m;
}
Cell* toGrid(int x, int y)
{
int relx = x - NODE_MARGIN_X;
int rely = y - NODE_MARGIN_Y;
relx = closestFloor(relx, NODE_SIZE+NODE_OFFSET)/(NODE_SIZE+NODE_OFFSET);
rely = closestFloor(rely, NODE_SIZE+NODE_OFFSET)/(NODE_SIZE+NODE_OFFSET);
if (relx >= 0 && relx < game->GRID_WIDTH && rely >= 0 && rely < game->GRID_HEIGHT)
{
return game->grid->at(relx)->at(rely);
}
return NULL;
}
bool started = false;
void revealAtMouse()
{
if (game->state == GameState::Won || game->state == GameState::Lost) return;
sf::Vector2i pos = sf::Mouse::getPosition(*window);
Cell* clicked = toGrid(pos.x, pos.y);
if (!clicked || clicked->isFlagged) return;
if (!started)
{
started = true;
game->populateGrid(clicked);
}
if (clicked->isRevealed && clicked->num > 0 && !clicked->isMine)
{
CellList* adjs = game->getAdjacentCells(clicked);
int f = 0;
for(auto it = adjs->begin(); it != adjs->end(); it++)
if ((*it)->isFlagged) f++;
if (f == clicked->num) // If we flagged the correct number of mines, reveal the adjacent squares
{
for(auto it = adjs->begin(); it != adjs->end(); it++)
game->revealCell(*it);
}
}
game->revealCell(clicked);
}
void flagAtMouse()
{
if (game->state == GameState::Won || game->state == GameState::Lost) return;
sf::Vector2i pos = sf::Mouse::getPosition(*window);
Cell* clicked = toGrid(pos.x, pos.y);
if (!clicked) return;
game->flagCell(clicked);
}
void printUsage()
{
std::cout draw(getSprite(&mineIcon, rectPos));
} else {
window->draw(getRect(rectSize, rectPos, sf::Color(200, 200, 200), 2, sf::Color(100, 100, 100)));
window->draw(getSprite(&mineIcon, rectPos));
}
} else if (cell->isFlagged) {
window->draw(getRect(rectSize, rectPos, sf::Color(200, 200, 200), 2, sf::Color(100, 100, 100)));
window->draw(getSprite(&crossIcon, rectPos));
} else {
window->draw(getRect(rectSize, rectPos, sf::Color(200, 200, 200), 2, sf::Color(100, 100, 100)));
auto style = sf::Text::Bold;
sf::Text txt = getText(
NODE_SIZE - 8,
num,
numColors[n],
&style
);
txt.setPosition(centerText(
rectPos.x + NODE_SIZE/2,
rectPos.y + NODE_SIZE/2,
txt
));
window->draw(txt);
}
} else {
// Cover
window->draw(getRect(rectSize, rectPos, sf::Color(200, 200, 200), 2, sf::Color(255, 255, 255)));
if (cell->isFlagged)
{
window->draw(getSprite(&flagIcon, rectPos));
}
}
}
}
// HUD
sf::Text flagsleft = getText(14, "Flags left: " + std::to_string(game->FLAGS_LEFT), sf::Color(255, 255, 255), NULL);
flagsleft.setPosition(sf::Vector2f(20, 13));
window->draw(flagsleft);
//
// End of game
if (game->checkWin()) game->state = GameState::Won;
if (game->state == GameState::Won || game->state == GameState::Lost)
{
sf::Text txt = getText(
14,
(game->state == GameState::Won) ? "You Win!" : "You Lose :(",
(game->state == GameState::Won) ? sf::Color(255, 220, 0) : sf::Color(255, 0, 0),
NULL
);
txt.setPosition(centerText(windowWidth/2, 20, txt));
window->draw(txt);
game->revealAll();
}
window->display();
}
return EXIT_SUCCESS;
}