416 lines
9.0 KiB
C++
416 lines
9.0 KiB
C++
#include "map.h"
|
|
|
|
Map::Map(QByteArray data, QSize size, QString name, int maxPlayers, int image, QObject *parent) :
|
|
QObject(parent)
|
|
{
|
|
QByteArray ba = QByteArray::fromBase64(data);
|
|
ba = qUncompress(ba);
|
|
QDataStream s(ba);
|
|
mapName = name;
|
|
s >> Cells;
|
|
int chei;
|
|
if (Cells.size() <= 0)
|
|
qFatal("Map has invalid width");
|
|
if (Cells.size() != size.width())
|
|
qCritical("Map has wrong width");
|
|
mapSize.setWidth(Cells.size());
|
|
chei = Cells.at(0).size();
|
|
for (int i=0; i<Cells.size(); i++)
|
|
{
|
|
if (Cells[i].size() <= 0)
|
|
qFatal("Map has invalid height");
|
|
if (Cells[i].size() != size.height())
|
|
{
|
|
qCritical("Map has wrong height");
|
|
if (Cells[i].size() != chei)
|
|
qFatal("Corrupted map data");
|
|
}
|
|
for (int j=0; j<Cells[i].size(); j++)
|
|
{
|
|
if (Cells[i][j]==Start) starts.push_back(QPoint(i,j));
|
|
if (Cells[i][j]==Finish) finishs.push_back(QPoint(i,j));
|
|
}
|
|
}
|
|
if (starts.isEmpty() || finishs.isEmpty()) qFatal("invalid map, not found start/finish");
|
|
// TODO: check for maxPlayers
|
|
players = maxPlayers;
|
|
imageType = image;
|
|
}
|
|
|
|
|
|
//void Map::ReadSettings()
|
|
//{
|
|
// QString str;
|
|
// SettingsReader * sreader = new SettingsReader("map.conf");
|
|
// str = sreader->getValue("cells path");
|
|
// maxPlayers = sreader->getValue("max players","1").toInt();
|
|
// QFile * f = new QFile(str);
|
|
// f->open(QIODevice::ReadOnly);
|
|
// QDataStream s(f);
|
|
// s >> Cells;
|
|
// if (Cells.size()>0)
|
|
// {
|
|
// mapsize.setWidth(Cells.size());
|
|
// mapsize.setHeight(Cells[0].size());
|
|
// //qDebug() << "Map size" << mapsize;
|
|
// //printMap();
|
|
// } else qDebug("invalid size");
|
|
// delete f;
|
|
// delete sreader;
|
|
//}
|
|
|
|
|
|
void Map::printMap()
|
|
{
|
|
for (int i=0; i<Cells.size(); i++) qDebug()<<Cells.at(i);
|
|
}
|
|
|
|
|
|
void Map::removeAliensPath()
|
|
{
|
|
for (int i=0; i<Cells.size(); i++)
|
|
{
|
|
for (int j=0; j<Cells[i].size(); j++)
|
|
{
|
|
if (Cells[i][j] > 1000 && Cells[i][j] < 2000) Cells[i][j]=Cells[i][j]-1000;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool Map::addTowerOnMap(int playerId, QPoint pos)
|
|
{
|
|
if (playerId < 0 || playerId > players) return false;
|
|
QRect r(QPoint(),mapSize);
|
|
if (!r.contains(pos)) return false;
|
|
if (Cells[pos.x()][pos.y()]==Player+playerId)
|
|
{
|
|
Cells[pos.x()][pos.y()]=PlayerTower-playerId;
|
|
return true;
|
|
}
|
|
if (Cells[pos.x()][pos.y()]==PlayerAlien+playerId)
|
|
{
|
|
Cells[pos.x()][pos.y()]=PlayerTower-playerId;
|
|
bool ok=true;
|
|
for (int i=0; i<starts.size(); i++)
|
|
for (int j=0; j<finishs.size(); j++)
|
|
if (WaveTrace(starts.at(i),finishs.at(j))<0) ok = false;
|
|
qDebug()<<"ok="<<ok;
|
|
if (!ok)
|
|
{
|
|
Cells[pos.x()][pos.y()]=PlayerAlien+playerId;
|
|
return false;
|
|
}
|
|
//Cells[pos.x()][pos.y()]=PlayerTower-playerId;
|
|
bool * pathOK;
|
|
pathOK = new bool();
|
|
*pathOK = true;
|
|
qDebug("emit");
|
|
emit RecreateAlienPath(pathOK);
|
|
qDebug() << *pathOK;
|
|
if (!pathOK)
|
|
{
|
|
Cells[pos.x()][pos.y()]=PlayerAlien+playerId;
|
|
emit RecreateAlienPath(pathOK);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
qDebug()<<"Dont buid here" << Cells[pos.x()][pos.y()];
|
|
return false;
|
|
}
|
|
|
|
|
|
//void Map::CreateMapExample()
|
|
//{
|
|
// Cells.resize(16);
|
|
// for (int i=0; i<Cells.size(); i++)
|
|
// {
|
|
// Cells[i].resize(16);
|
|
// Cells[i][0]=Wall;
|
|
// Cells[i][Cells[i].size()-1]=Wall;
|
|
// }
|
|
// for (int i=0; i<Cells.size(); i++)
|
|
// {
|
|
// for (int j=0; j<Cells[i].size(); j++)
|
|
// {
|
|
// Cells[0][j]=Wall;
|
|
// Cells[Cells.size()-1][j]=Wall;
|
|
// }
|
|
// }
|
|
// for (int i=1; i<Cells.size()/2; i++)
|
|
// for (int j=1; j<Cells[i].size()-1; j++)
|
|
// Cells[i][j]=Player;
|
|
// for (int i=Cells.size()/2; i<Cells.size()-1; i++)
|
|
// for (int j=1; j<Cells[i].size()-1; j++)
|
|
// Cells[i][j]=Player+1;
|
|
// for (int i=2; i<Cells.size()-2; i++)
|
|
// Cells[i][Cells[i].size()/2] = Wall;
|
|
// Cells[Cells.size()/2][0]=Start;
|
|
// Cells[Cells.size()/2-1][0]=Start;
|
|
// Cells[Cells.size()/2][Cells[Cells.size()/2].size()-1]=Finish;
|
|
// Cells[Cells.size()/2-1][Cells[Cells.size()/2].size()-1]=Finish;
|
|
// QFile * f = new QFile("example16x16_64.map");
|
|
// f->open(QIODevice::ReadWrite);
|
|
// f->resize(0);
|
|
// QByteArray ba;
|
|
// QDataStream tmps(&ba,QIODevice::ReadWrite);
|
|
// tmps << Cells;
|
|
// ba = qCompress(ba);
|
|
// ba = ba.toBase64();
|
|
// QString str(ba);
|
|
//// QDataStream s(f);
|
|
//// s << ba;
|
|
// f->write(str.toUtf8());
|
|
// f->close();
|
|
// delete f;
|
|
//}
|
|
|
|
|
|
QVector<QPointF> Map::CreatePath(QPoint start, QPoint finish)
|
|
{
|
|
QPointF tp;
|
|
QVector<QPoint> srcPath;
|
|
QVector<QPointF> tmpPath;
|
|
QVector<QPointF> path;
|
|
//PathIndex = 1;
|
|
if (Cells[start.x()][start.y()] < 0) qDebug("ERROR invalid start"),exit(-1);
|
|
if (Cells[finish.x()][finish.y()] < 0) qDebug("ERROR invalid finish"),exit(-1);
|
|
srcPath = InvWaveTrace(finish,WaveTrace(start,finish));
|
|
for (int i=0; i<srcPath.size();i++)
|
|
{
|
|
int x = Cells.at(srcPath.at(i).x()).at(srcPath.at(i).y());
|
|
if (x > 0 && x < 1000) x = x+1000;
|
|
Cells[srcPath.at(i).x()][srcPath.at(i).y()] = x;
|
|
tmpPath.push_back(QPointF(srcPath.at(i)));
|
|
}
|
|
srcPath.clear();
|
|
//qDebug() << tmpPath.size();
|
|
if (!tmpPath.isEmpty())
|
|
{
|
|
for (int j=0; j<4; j++)
|
|
{
|
|
path.clear();
|
|
tp = tmpPath.at(0);
|
|
path.push_back(tp);
|
|
for (int i = 0; i < tmpPath.size() - 1; i++)
|
|
{
|
|
//if (j > 1) path.push_back(tmpPath[i]);
|
|
tp.setX((tmpPath.at(i).x() + tmpPath.at(i + 1).x()) / 2.0);
|
|
tp.setY((tmpPath.at(i).y() + tmpPath.at(i + 1).y()) / 2.0);
|
|
path.push_back(tp);
|
|
}
|
|
tp = tmpPath.at(tmpPath.size() - 1);
|
|
path.push_back(tp);
|
|
tmpPath = path;
|
|
}
|
|
tmpPath.clear();
|
|
if (path.size() >= 6)
|
|
{
|
|
path.remove(1);
|
|
path.remove(1);
|
|
path.remove(path.size()-2);
|
|
path.remove(path.size()-2);
|
|
}
|
|
return path;
|
|
}
|
|
path.clear();
|
|
return path;
|
|
}
|
|
|
|
|
|
int Map::WaveTrace(QPoint start, QPoint finish)
|
|
{
|
|
bool stop = false;
|
|
int step = 2;
|
|
QPoint cp, tp;
|
|
QRect fr(QPoint(), mapSize);
|
|
QVector<QPoint> tmpp, curp;
|
|
TmpCells << Cells;
|
|
for (int i = 0; i < Cells.size(); i++)
|
|
{
|
|
for (int j = 0; j < Cells.at(i).size(); j++)
|
|
{
|
|
if (Cells[i][j] < 0 ) TmpCells[i][j] = -1;
|
|
else TmpCells[i][j] = 0;
|
|
}
|
|
}
|
|
cp = start;
|
|
curp.push_back(cp);
|
|
TmpCells[cp.x()][cp.y()] = 1;
|
|
//qDebug() << "trace";
|
|
while (!stop) {
|
|
tmpp = curp;
|
|
curp.clear();
|
|
stop = true;
|
|
for (int i = 0; i < tmpp.size(); i++) {
|
|
cp = tmpp.at(i);
|
|
if (cp == finish) {
|
|
TmpCells[cp.x()][cp.y()] = step;
|
|
//qDebug() << "trace done!";
|
|
return step;
|
|
}
|
|
tp.setX(cp.x() - 1);
|
|
tp.setY(cp.y());
|
|
if (fr.contains(tp) && TmpCells[tp.x()][tp.y()] == 0) {
|
|
TmpCells[tp.x()][tp.y()] = step;
|
|
curp.push_back(tp);
|
|
stop = false;
|
|
}
|
|
tp.setX(cp.x() + 1);
|
|
if (fr.contains(tp) && TmpCells[tp.x()][tp.y()] == 0) {
|
|
TmpCells[tp.x()][tp.y()] = step;
|
|
curp.push_back(tp);
|
|
stop = false;
|
|
}
|
|
tp.setX(cp.x());
|
|
tp.setY(cp.y() - 1);
|
|
if (fr.contains(tp) && TmpCells[tp.x()][tp.y()] == 0) {
|
|
TmpCells[tp.x()][tp.y()] = step;
|
|
curp.push_back(tp);
|
|
stop = false;
|
|
}
|
|
tp.setY(cp.y() + 1);
|
|
if (fr.contains(tp) && TmpCells[tp.x()][tp.y()] == 0) {
|
|
TmpCells[tp.x()][tp.y()] = step;
|
|
curp.push_back(tp);
|
|
stop = false;
|
|
}
|
|
}
|
|
step++;
|
|
}
|
|
qDebug() << "trace false";
|
|
//qDebug() << TmpCells;
|
|
return -1;
|
|
}
|
|
|
|
|
|
QVector<QPoint> Map::InvWaveTrace(QPoint finish, int cnt)
|
|
{
|
|
QPoint wp, Ppnt;
|
|
QVector<QPoint> alpath;
|
|
if (cnt < 2) return alpath;
|
|
int Ind, c, xpp, ypp, xnn, ynn;
|
|
unsigned char chk;
|
|
Ppnt = wp = finish;
|
|
xnn=0;
|
|
xpp=0;
|
|
ynn=0;
|
|
ypp=0;
|
|
cnt--;
|
|
alpath.push_front(Ppnt);
|
|
while (cnt > 1)
|
|
{
|
|
cnt--;
|
|
chk = 0;
|
|
Ind = 0;
|
|
c = 0;
|
|
if (wp.x() - 1 >= 0 && TmpCells[wp.x()-1][wp.y()] == cnt)
|
|
{
|
|
chk = chk | 0x01;
|
|
c++;
|
|
}
|
|
if (wp.x() + 1 < mapSize.width() && TmpCells[wp.x()+1][wp.y()] == cnt)
|
|
{
|
|
chk = chk | 0x02;
|
|
c++;
|
|
}
|
|
if (wp.y() - 1 >= 0 && TmpCells[wp.x()][wp.y()-1] == cnt)
|
|
{
|
|
chk = chk | 0x04;
|
|
c++;
|
|
}
|
|
if (wp.y() + 1 < mapSize.height() && TmpCells[wp.x()][wp.y()+1] == cnt)
|
|
{
|
|
chk = chk | 0x08;
|
|
c++;
|
|
}
|
|
if (c == 0 || chk == 0) qDebug("ERROR in InvWaveTrace"),exit(-1);
|
|
if (c > 1)
|
|
{
|
|
if ((chk & 0x01)==0x01 && (chk & 0x04)==0x04)
|
|
{
|
|
if (xnn <= ynn && Ind == 0){
|
|
wp.rx()--;
|
|
xnn++;
|
|
if (xnn == ynn) xnn++;
|
|
Ind = 1;
|
|
} else if (Ind == 0) {
|
|
wp.ry()--;
|
|
ynn++;
|
|
ynn++;
|
|
Ind = 1;
|
|
}
|
|
}
|
|
if ((chk & 0x02)==0x02 && (chk & 0x04)==0x04)
|
|
{
|
|
if (xpp <= ynn && Ind == 0){
|
|
wp.rx()++;
|
|
xpp++;
|
|
if (xpp == ynn) xpp++;
|
|
Ind = 1;
|
|
} else if (Ind == 0) {
|
|
wp.ry()--;
|
|
ynn++;
|
|
ynn++;
|
|
Ind = 1;
|
|
}
|
|
}
|
|
if ((chk & 0x01)==0x01 && (chk & 0x08)==0x08)
|
|
{
|
|
if (xnn <= ypp && Ind == 0){
|
|
wp.rx()--;
|
|
xnn++;
|
|
if (xnn == ypp) xnn++;
|
|
Ind = 1;
|
|
} else if (Ind == 0) {
|
|
wp.ry()++;
|
|
ypp++;
|
|
ypp++;
|
|
Ind = 1;
|
|
}
|
|
}
|
|
if ((chk & 0x02)==0x02 && (chk & 0x08)==0x08)
|
|
{
|
|
if (xpp <= ypp && Ind == 0){
|
|
wp.rx()++;
|
|
xpp++;
|
|
if (xpp == ypp) xpp++;
|
|
Ind = 1;
|
|
} else if (Ind == 0) {
|
|
wp.ry()++;
|
|
ypp++;
|
|
ypp++;
|
|
Ind = 1;
|
|
}
|
|
}
|
|
}
|
|
if (c == 1 || Ind == 0)
|
|
{
|
|
xnn=0;
|
|
xpp=0;
|
|
ynn=0;
|
|
ypp=0;
|
|
if ((chk & 0x01)==0x01) {
|
|
wp.rx()--;
|
|
xnn++;
|
|
}
|
|
else if ((chk & 0x02)==0x02) {
|
|
wp.rx()++;
|
|
xpp++;
|
|
}
|
|
else if ((chk & 0x04)==0x04) {
|
|
wp.ry()--;
|
|
ynn++;
|
|
}
|
|
else if ((chk & 0x08)==0x08) {
|
|
wp.ry()++;
|
|
ypp++;
|
|
}
|
|
}
|
|
Ppnt = wp;
|
|
alpath.push_front(Ppnt);
|
|
}
|
|
return alpath;
|
|
}
|
|
|