/*************************************************************************** board.cpp - description ------------------- begin : ven fév 22 17:11:00 CET 2002 copyright : (C) 2002 by Romain Vinot email : vinot@aist.enst.fr ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifdef _WIN32 #pragma warning (disable : 4786) #endif #include #include "board.h" #include "creature.h" #include "guicreature.h" Board::Board(void) : Xmax(0), Ymax(0) {} Board::~Board(void) {} void Board::setMax(int x, int y) { Xmax = x; Ymax = y; } int Board::addCase(int x, int y) { if (x>=0 && x < Xmax && y>=0 && y < Ymax) { cases[x+y*Xmax].clear(); // There is nothing on this case. return x+y*Xmax; } return -1; } int Board::addCase(int caseId) { if (caseId < Xmax*Ymax) { // cases[caseId].clear(); cases[caseId]; // This will create the case if it doesn't exist yet. return caseId; } return -1; } bool Board::addObject(Object *obj, bool force) { int caseId = obj->getPosition(); cases[caseId].insert(obj); if (obj->Type() == EXIT) exitzone.insert(caseId); else if (obj->Type() == ENTRYZONE) entryzone.insert(caseId); return true; } set* Board::getObject (int caseId) { map >::iterator it = cases.find(caseId); if (it == cases.end() || it->first!=caseId) return 0; return &(it->second); } bool Board::isNotWall (int caseId) { if (cases.find(caseId)==cases.end()) return false; return true; } void Board::delObject (Object *obj) { int caseId = obj->getPosition(); cases[caseId].erase(obj); } bool Board::isEmpty(int pos) { map >::iterator it = cases.find(pos); if (it == cases.end()) // This is a wall. return false; if (it->second.size() == 0) // This is a void case. return true; for (set::iterator ite=it->second.begin(); ite!=it->second.end(); ite++) // Case is empty if all the object are empty. if (!(*ite)->isEmpty()) return false; return true; } bool Board::isEntryZoneCase(int pos) { if (entryzone.find(pos) != entryzone.end()) return true; return false; } bool Board::isEntryBlocked(int pos) { if (entryzone.find(pos) == entryzone.end()) return false; map >::iterator it = cases.find(pos); if (it!=cases.end()) for (set::iterator ite=it->second.begin(); ite!=it->second.end(); ite++) // Case is empty if all the object are empty. if (((*ite)->Type()==BULKHEAD) && !(*ite)->isEmpty()) return true; return false; } bool Board::isExitCase(int pos) { return (exitzone.find(pos)!=exitzone.end()); } set * Board::getExits(void) { return &exitzone; } QString Board::getStringEntryZoneCase(void) { QString str; QTextStream res (&str,IO_WriteOnly); int toFlush=1; for (set::iterator it=entryzone.begin(); it!= entryzone.end(); it++) { if (toFlush%9==0) res << endl; res << " [" << *it%Xmax << " " << *it/Xmax << "] "; toFlush++; } return str; } const set* Board::getEntryZoneCases(void) { return &entryzone; } bool Board::hasObject(int caseId, ObjectType type) { map >::iterator it = cases.find(caseId); if (it!=cases.end()) for (set::iterator ite=it->second.begin(); ite!=it->second.end(); ite++) if ((*ite)->Type()==type) return true; return false; } void Board::move(Object *crea, int from, int to) { cases[from].erase(crea); cases[to].insert(crea); } bool Board::areNeighbors(int c1, int c2) { int x1=c1%Xmax; int y1=c1/Xmax; int x2=c2%Xmax; int y2=c2/Xmax; int xdiff=x2-x1; int ydiff=y2-y1; if (abs(xdiff)>1 || abs(ydiff)>1) return false; if (!xdiff || !ydiff) // Neighbors in cardinal direction. return true; if (isEmpty(c1+xdiff) || isEmpty(c1+Xmax*ydiff)) // Neighbors in diagonal. return true; return false; } // Distance is max of coords and not sum. int Board::Distance(int c1, int c2) { int xdiff = abs(c1%Xmax-c2%Xmax); int ydiff = abs(c1/Xmax-c2/Xmax); return (xdiff>ydiff) ? xdiff : ydiff; } int Board::DistanceSum(int c1, int c2) { int xdiff = abs(c1%Xmax-c2%Xmax); int ydiff = abs(c1/Xmax-c2/Xmax); return xdiff+ydiff; } // Return the caseId from the case position int Board::getCaseId(int x, int y) { return x+y*Xmax; } void Board::removeAll(void) { Xmax=0; Ymax=0; for (map >::iterator it=cases.begin(); it != cases.end(); it++) { for (set::iterator ite=it->second.begin(); ite!=it->second.end(); ite++) delete *ite; it->second.clear(); } cases.clear(); entryzone.clear(); exitzone.clear(); }