示例#1
0
std::vector<Faction*> FactionOctsapling::CandidateFactions(const Sector sec, Uint32 sysIndex)
{
	/* answer the factions that we've put in the same octobox cell as the one the
	   system would go in. This part happens every time we do GetNearest faction
	   so *is* performance criticale.e
	*/
	Sector::System sys = sec.m_systems[sysIndex];
	return octbox[BoxIndex(sys.sx)][BoxIndex(sys.sy)][BoxIndex(sys.sz)];
}
bool LockedCandidates(Sudoku &sudoku)
{
    Log(Trace, "searching for locked candidates in line/box intersections\n");
    // these locals are for logging purposes only
    std::vector<Index_t> cellsChanged;
    Index_t valChanged;
    for (Index_t i = 0; i < 9; ++i) {
        House line = sudoku.GetRow(i);
        for (Index_t j = 0; j < 3; ++j)
        {
            Index_t boxIndex = BoxIndex(i, j*3);
            House box = sudoku.GetBox(boxIndex);
            if (IntersectionOfHouses(line, box, CommonCellsRowBox(i, boxIndex),
                        cellsChanged, valChanged)) {
                std::ostringstream sstr;
                for (Index_t k = 0; k < cellsChanged.size(); ++k) {
                    if (k != 0)
                        sstr << ", ";
                    sstr << 'r' << i+1 << 'c' << cellsChanged[k]+1 << '#'
                        << valChanged;
                }
                Log(Info, "row %d intersection with box %d ==> %s\n",
                        i+1, boxIndex+1, sstr.str().c_str());

                sudoku.SetRow(line, i);
                return true;
            }

            if (IntersectionOfHouses(box, line, CommonCellsBoxRow(boxIndex, i),
                        cellsChanged, valChanged)) {
                std::ostringstream sstr;
                for (Index_t k = 0; k < cellsChanged.size(); ++k) {
                    if (k != 0)
                        sstr << ", ";
                    sstr << 'r' << i+1 << 'c'
                        << ColForCellInBox(boxIndex, cellsChanged[k])+1 << '#'
                        << valChanged;
                }
                Log(Info, "box %d intersection with row %d ==> %s\n",
                        boxIndex+1, i+1, sstr.str().c_str());

                sudoku.SetBox(box, boxIndex);
                return true;
            }
        }

        line = sudoku.GetCol(i);
        for (Index_t j = 0; j < 3; ++j)
        {
            Index_t boxIndex = BoxIndex(j*3, i);
            House box = sudoku.GetBox(boxIndex);
            if (IntersectionOfHouses(line, box, CommonCellsColBox(i, boxIndex),
                        cellsChanged, valChanged)) {
                std::ostringstream sstr;
                for (Index_t k = 0; k < cellsChanged.size(); ++k) {
                    if (k != 0)
                        sstr << ", ";
                    sstr << 'r' << cellsChanged[k]+1 << 'c' << i+1 << '#'
                        << valChanged;
                }
                Log(Info, "column %d intersection with box %d ==> %s\n",
                        i+1, boxIndex+1, sstr.str().c_str());

                sudoku.SetCol(line, i);
                return true;
            }

            if (IntersectionOfHouses(box, line, CommonCellsBoxCol(boxIndex, i),
                        cellsChanged, valChanged)) {
                std::ostringstream sstr;
                for (Index_t k = 0; k < cellsChanged.size(); ++k) {
                    if (k != 0)
                        sstr << ", ";
                    sstr << 'r' << RowForCellInBox(boxIndex, cellsChanged[k])+1
                        << 'c' << i+1 << '#' << valChanged;
                }
                Log(Info, "box %d intersection with column %d ==> %s\n",
                        boxIndex+1, i+1, sstr.str().c_str());

                sudoku.SetBox(box, boxIndex);
                return true;
            }
        }
    }
    return false;
}
示例#3
0
void FactionOctsapling::Add(Faction* faction)
{
	/*  The general principle here is to put the faction in every octbox cell that a system
	    that is a member of that faction could be in. This should let us cut the number
		of factions that have to be checked by GetNearestFaction, by eliminating right off
		all the those Factions that aren't in the same cell.

		As I'm just going for the quick performance win, I'm being very sloppy and
		treating a Faction as if it was a cube rather than a sphere. I'm also not even
		attempting to work out real faction boundaries for this.

		Obviously this all could be improved even without this Octsapling growing into
		a full Octree.

		This part happens at faction generation time so shouldn't be too performance
		critical
	*/
	Sector sec = Sector(faction->homeworld.sectorX, faction->homeworld.sectorY, faction->homeworld.sectorZ);

	/* only factions with homeworlds that are available at faction generation time can
	   be added to specific cells...
	*/
	if (faction->hasHomeworld && (faction->homeworld.systemIndex < sec.m_systems.size())) {
		/* calculate potential indexes for the octbox cells the faction needs to go into
		*/
		Sector::System sys = sec.m_systems[faction->homeworld.systemIndex];

		int xmin = BoxIndex(Sint32(sys.FullPosition().x - float((faction->Radius()))));
		int xmax = BoxIndex(Sint32(sys.FullPosition().x + float((faction->Radius()))));
		int ymin = BoxIndex(Sint32(sys.FullPosition().y - float((faction->Radius()))));
		int ymax = BoxIndex(Sint32(sys.FullPosition().y + float((faction->Radius()))));
		int zmin = BoxIndex(Sint32(sys.FullPosition().z - float((faction->Radius()))));
		int zmax = BoxIndex(Sint32(sys.FullPosition().z + float((faction->Radius()))));

		/* put the faction in all the octbox cells needed in a hideously inexact way that
		   will generate duplicates in each cell in many cases
		*/
		octbox[xmin][ymin][zmin].push_back(faction);  // 0,0,0
		octbox[xmax][ymin][zmin].push_back(faction);  // 1,0,0
		octbox[xmax][ymax][zmin].push_back(faction);  // 1,1,0
		octbox[xmax][ymax][zmax].push_back(faction);  // 1,1,1

		octbox[xmin][ymax][zmin].push_back(faction);  // 0,1,0
		octbox[xmin][ymax][zmax].push_back(faction);  // 0,1,1
		octbox[xmin][ymin][zmax].push_back(faction);  // 0,0,1
		octbox[xmax][ymin][zmax].push_back(faction);  // 1,0,1

		/* prune any duplicates from the octbox cells making things slightly saner
		*/
		PruneDuplicates(0,0,0);
		PruneDuplicates(1,0,0);
		PruneDuplicates(1,1,0);
		PruneDuplicates(1,1,1);

		PruneDuplicates(0,1,0);
		PruneDuplicates(0,1,1);
		PruneDuplicates(0,0,1);
		PruneDuplicates(1,0,1);

	} else {
	/* ...other factions, such as ones with no homeworlds, and more annoyingly ones
	   whose homeworlds don't exist yet because they're custom systems have to go in
	   *every* octbox cell
	*/
		octbox[0][0][0].push_back(faction);
		octbox[1][0][0].push_back(faction);
		octbox[1][1][0].push_back(faction);
		octbox[1][1][1].push_back(faction);

		octbox[0][1][0].push_back(faction);
		octbox[0][1][1].push_back(faction);
		octbox[0][0][1].push_back(faction);
		octbox[1][0][1].push_back(faction);
	}
}