private PlacedOrganelle SplitOrganelle(PlacedOrganelle organelle) { var q = organelle.Position.Q; var r = organelle.Position.R; var newOrganelle = new PlacedOrganelle(); newOrganelle.Definition = organelle.Definition; // Spiral search for space for the organelle int radius = 1; while (true) { // Moves into the ring of radius "radius" and center the old organelle var radiusOffset = Hex.HexNeighbourOffset[Hex.HexSide.BottomLeft]; q = q + radiusOffset.Q; r = r + radiusOffset.R; // Iterates in the ring for (int side = 1; side <= 6; ++side) { var offset = Hex.HexNeighbourOffset[(Hex.HexSide)side]; // Moves "radius" times into each direction for (int i = 1; i <= radius; ++i) { q = q + offset.Q; r = r + offset.R; // Checks every possible rotation value. for (int j = 0; j <= 5; ++j) { newOrganelle.Position = new Hex(q, r); // TODO: in the old code this was always i * // 60 so this didn't actually do what it meant // to do. But perhaps that was right? This is // now fixed to actually try the different // rotations. newOrganelle.Orientation = j; if (organelles.CanPlace(newOrganelle)) { organelles.Add(newOrganelle); return(newOrganelle); } } } } ++radius; } }
private OrganelleTemplate GetRealisticPosition(OrganelleDefinition organelle, OrganelleLayout <OrganelleTemplate> existingOrganelles) { var result = new OrganelleTemplate(organelle, new Hex(0, 0), 0); // Loop through all the organelles and find an open spot to // place our new organelle attached to existing organelles // This almost always is over at the first iteration, so its // not a huge performance hog foreach (var otherOrganelle in existingOrganelles.OrderBy(_ => random.Next())) { // The otherOrganelle is the organelle we wish to be next to // Loop its hexes and check positions next to them foreach (var hex in otherOrganelle.RotatedHexes) { // Offset by hexes in organelle we are looking at var pos = otherOrganelle.Position + hex; for (int side = 1; side <= 6; ++side) { for (int radius = 1; radius <= 3; ++radius) { // Offset by hex offset multiplied by a factor to check for greater range var hexOffset = Hex.HexNeighbourOffset[(Hex.HexSide)side]; hexOffset *= radius; result.Position = pos + hexOffset; // Check every possible rotation value. for (int rotation = 0; rotation <= 5; ++rotation) { result.Orientation = rotation; if (existingOrganelles.CanPlace(result)) { return(result); } } } } } } // We didnt find an open spot, this doesn't make much sense throw new ArgumentException("Mutation code could not find a good position " + "for a new organelle"); }