This repository has been archived on 2023-10-10. You can view files and clone it, but cannot push or open issues/pull-requests.
Explode/map.cpp

326 lines
6.0 KiB
C++

#include "map.h"
#include "general.h"
#include "tile.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
Map::Map(int sizeX, int sizeY, int numBombs)
{
srand((unsigned int)time(NULL));
m_SizeX = sizeX;
m_SizeY = sizeY;
m_numOfBombs = numBombs;
m_PlacesLeft = m_SizeX * m_SizeY - m_numOfBombs;
m_MapDone = false;
m_Layout = NULL;
Generate();
}
Map::~Map()
{
delete[] m_Layout;
}
void Map::GenerateFrom(int fromX, int fromY)
{
if (m_Layout != NULL)
{
delete[] m_Layout;
m_Layout = NULL;
}
m_PlacesLeft = m_SizeX * m_SizeY - m_numOfBombs;
m_Layout = new Tile[m_SizeX * m_SizeY];
for (int x = 0; x < m_SizeX; x++)
{
for (int y = 0; y < m_SizeY; y++)
{
m_Layout[x+y*m_SizeX].SetType(0);
}
}
int bombCount = m_numOfBombs;
while (bombCount != 0)
{
int posX = rand() % m_SizeX;
int posY = rand() % m_SizeY;
if ( posX > fromX + 1 || posX < fromX -1 || posY > fromY + 1 || posY < fromY - 1)
{
if (m_Layout[posX+posY*m_SizeX].GetType() == 0)
{
m_Layout[posX+posY*m_SizeX].SetType(BOMB);
bombCount--;
}
}
}
for (int x = 0; x < m_SizeX; x++)
{
for (int y = 0; y < m_SizeY; y++)
{
if (m_Layout[x+y*m_SizeX].GetType() != 9)
{
int bombInNeighbours = 0;
// CHECK LEFT THREE NEIGHBOURS
if (x > 0)
{
if (y > 0)
{
if (m_Layout[x-1+(y-1)*m_SizeX].GetType() == 9)
{
bombInNeighbours++;
}
}
if (y < m_SizeY - 1)
{
if (m_Layout[x-1+(y+1)*m_SizeX].GetType() == 9)
{
bombInNeighbours++;
}
}
if (m_Layout[x-1+y*m_SizeX].GetType() == 9)
{
bombInNeighbours++;
}
}
// CHECK RIGHT THREE NEIGHBOURS
if (x < m_SizeX - 1)
{
if (y > 0)
{
if (m_Layout[x+1+(y-1)*m_SizeX].GetType() == 9)
{
bombInNeighbours++;
}
}
if (y < m_SizeY - 1)
{
if (m_Layout[x+1+(y+1)*m_SizeX].GetType() == 9)
{
bombInNeighbours++;
}
}
if (m_Layout[x+1+y*m_SizeX].GetType() == 9)
{
bombInNeighbours++;
}
}
// CHECK MIDDLE TWO NEIGHBOURS
if (y > 0)
{
if (m_Layout[x+(y-1)*m_SizeX].GetType() == 9)
{
bombInNeighbours++;
}
}
if (y < m_SizeY - 1)
{
if (m_Layout[x+(y+1)*m_SizeX].GetType() == 9)
{
bombInNeighbours++;
}
}
m_Layout[x+y*m_SizeX].SetType(bombInNeighbours);
}
//m_Layout[x+y*m_SizeX].SetSprite();
m_Layout[x+y*m_SizeX].SetSpritePosition(x*TILE_SIZE_X, y*TILE_SIZE_Y);
}
}
}
void Map::Generate()
{
m_MapDone = false;
GenerateFrom(rand() % m_SizeX, rand() % m_SizeY);
}
bool Map::GenerateFromClick(int mouseX, int mouseY)
{
bool found = false;
int currentX = 0;
int currentY = 0;
m_MapDone = false;
for (int x = 0; x < m_SizeX; x++)
{
for (int y = 0; y < m_SizeY; y++)
{
bool revealed = m_Layout[x+y*m_SizeX].TestPosition(mouseX, mouseY);
if (revealed)
{
currentX = x;
currentY = y;
found = true;
DecrementFreePlaces();
}
}
}
GenerateFrom(currentX, currentY);
return found;
}
void Map::Render()
{
for (int x = 0; x < m_SizeX; x++)
{
for (int y = 0; y < m_SizeY; y++)
{
m_Layout[x+y*m_SizeX].Render();
}
}
}
void Map::ClickAt(int mouseX, int mouseY)
{
for (int x = 0; x < m_SizeX; x++)
{
for (int y = 0; y < m_SizeY; y++)
{
bool revealed = m_Layout[x+y*m_SizeX].TestClick(mouseX, mouseY);
if (revealed)
{
if (m_Layout[x+y*m_SizeX].GetType() == 0)
{
Reveal(x, y);
}
else
{
DecrementFreePlaces();
if (m_Layout[x+y*m_SizeX].GetType() == 9)
{
m_MapDone = true;
}
}
}
}
}
}
void Map::RightClickAt(int mouseX, int mouseY)
{
for (int x = 0; x < m_SizeX; x++)
{
for (int y = 0; y < m_SizeY; y++)
{
bool revealed = m_Layout[x+y*m_SizeX].TestRightClick(mouseX, mouseY);
if (revealed)
{
}
}
}
}
void Map::Reveal(int indexX, int indexY)
{
m_Layout[indexX+indexY*m_SizeX].Reveal();
DecrementFreePlaces();
if (m_Layout[indexX+indexY*m_SizeX].GetType() == 0)
{
if (indexX > 0)
{
if (indexY > 0)
{
if(m_Layout[indexX - 1 + (indexY - 1) * m_SizeX].IsRevealed() != true)
{
Reveal(indexX - 1, indexY - 1);
}
}
if (indexY < m_SizeY - 1)
{
if(m_Layout[indexX - 1 + (indexY + 1) * m_SizeX].IsRevealed() != true)
{
Reveal(indexX - 1, indexY + 1);
}
}
if(m_Layout[indexX - 1 + indexY * m_SizeX].IsRevealed() != true)
{
Reveal(indexX - 1, indexY);
}
}
if (indexX < m_SizeX - 1)
{
if (indexY > 0)
{
if(m_Layout[indexX + 1 + (indexY - 1) * m_SizeX].IsRevealed() != true)
{
Reveal(indexX + 1, indexY - 1);
}
}
if (indexY < m_SizeY - 1)
{
if(m_Layout[indexX + 1 + (indexY + 1) * m_SizeX].IsRevealed() != true)
{
Reveal(indexX + 1, indexY + 1);
}
}
if(m_Layout[indexX + 1 + indexY * m_SizeX].IsRevealed() != true)
{
Reveal(indexX + 1, indexY);
}
}
if (indexY > 0)
{
if(m_Layout[indexX + (indexY - 1) * m_SizeX].IsRevealed() != true)
{
Reveal(indexX, indexY - 1);
}
}
if (indexY < m_SizeY - 1)
{
if(m_Layout[indexX + (indexY + 1) * m_SizeX].IsRevealed() != true)
{
Reveal(indexX, indexY + 1);
}
}
}
}
void Map::DecrementFreePlaces()
{
m_PlacesLeft--;
if (m_PlacesLeft == 0)
{
m_MapDone = true;
}
}
void Map::WinMap()
{
for (int x = 0; x < m_SizeX; x++)
{
for (int y = 0; y < m_SizeY; y++)
{
m_Layout[x+y*m_SizeX].SetType(10);
m_Layout[x+y*m_SizeX].SetSpritePosition(x*TILE_SIZE_X, y*TILE_SIZE_Y);
m_Layout[x+y*m_SizeX].Finish();
}
}
}
void Map::LoseMap()
{
for (int x = 0; x < m_SizeX; x++)
{
for (int y = 0; y < m_SizeY; y++)
{
m_Layout[x+y*m_SizeX].Finish();
}
}
}