// Rotates this object around the desired axis in a counter clockwise direction // (viewed from the + end of the axis) private void _Rotate(RotationAxis axis) { TranformationFunc f; Discrete3DCoord new_dims; switch (axis) { case RotationAxis.X_AXIS: new_dims = new Discrete3DCoord(this.dims.x, this.dims.z, this.dims.y); f = coord => new Discrete3DCoord(coord.x, coord.z, this.dims.y - coord.y - 1); break; case RotationAxis.Y_AXIS: new_dims = new Discrete3DCoord(this.dims.z, this.dims.y, this.dims.x); f = coord => new Discrete3DCoord(this.dims.z - coord.z - 1, coord.y, coord.x); break; case RotationAxis.Z_AXIS: new_dims = new Discrete3DCoord(this.dims.y, this.dims.x, this.dims.z); f = coord => new Discrete3DCoord(this.dims.y - coord.y - 1, coord.x, coord.z); break; default: throw new System.Exception(string.Format("Attempted to rotate along axis {0} which is not accounted for", axis)); } _ApplyTransformation(f, new_dims); }
public void TestDiscrete3DCoordHashAndEquals() { Discrete3DCoord a = new Discrete3DCoord(1, 2, 3); Discrete3DCoord a_copy = new Discrete3DCoord(1, 2, 3); Discrete3DCoord b = new Discrete3DCoord(2, 3, 4); Assert.AreEqual(a, a_copy); Assert.AreEqual(a.GetHashCode(), a_copy.GetHashCode()); Assert.AreNotEqual(a, b); Assert.AreNotEqual(a.GetHashCode(), b.GetHashCode()); }
public void AddBlock(Discrete3DCoord coord, int subdesign_id) { this.blocks[coord.x, coord.y, coord.z] = subdesign_id; if (!valid_ids.Contains(subdesign_id)) { valid_ids.Add(subdesign_id); } if (next_subdesign_id <= subdesign_id) { next_subdesign_id = subdesign_id + 1; } }
public void TestGetDims() { Blueprint a = new Blueprint(1, 2, 3); Discrete3DCoord dims = a.GetDims(); Assert.AreEqual(1, dims.x); Assert.AreEqual(2, dims.y); Assert.AreEqual(3, dims.z); Blueprint a_copy = new Blueprint(new Discrete3DCoord(1, 2, 3)); Assert.AreEqual(dims, a_copy.GetDims()); }
private void _UnstableMutate() { System.Random rng = new System.Random(); // 0) Decide if we are adding or deleting. if (valid_ids.Count() == 0 || rng.NextDouble() > DELETE_CHANCE) { bool placed_block = false; int tries = 0; while (tries < MAX_PLACEMENT_ATTEMPTS && !placed_block) { // ------------- ADDING ------------- // 1) Pick a design from the notebook randomly int i = rng.Next(design_notebook.Count); // Debug.Log(string.Format("Using design {0}", i)); Blueprint random_design = design_notebook[i]; // 2) Randomly rotate the object System.Array enum_values = System.Enum.GetValues(typeof(RotationAxis)); RotationAxis axis = (RotationAxis)enum_values.GetValue(rng.Next(enum_values.Length)); int mag = rng.Next(3); Blueprint rotated = random_design.Rotate(axis, mag); // 3) Try to find a place for it Discrete3DCoord placement = FindValidOffsetFor(rotated); if (placement != null) { this.ApplyDesign(rotated, placement.x, placement.y, placement.z); placed_block = true; } // 4) Upon failure try again, limited to n tries tries++; } if (tries == MAX_PLACEMENT_ATTEMPTS && !placed_block) { // TODO: Figure out how to handle this error nicely Debug.Log("Could not find a valid mutation"); } } else { // ------------- DELETING------------- // TODO: Keep track of a set of valid ids // 1) Pick a valid id int[] valid_arr = valid_ids.ToArray(); int random_id = valid_arr[rng.Next(valid_arr.Count())]; // 2) Zero out all blocks with the same id // 3) Invalidate the id this.DeleteID(random_id); } }
// -------------- Basic Methods -------------- public Blueprint(int dim_x, int dim_y, int dim_z) { if (dim_x < 0 || dim_y < 0 || dim_z < 0) { throw new System.ArgumentException("dimensions must be non-negative"); } blocks = new int[dim_x, dim_y, dim_z]; this.dims = new Discrete3DCoord(dim_x, dim_y, dim_z); for (int x = 0; x < dim_x; x++) { for (int z = 0; z < dim_z; z++) { this.attatchment_points.Add(new Discrete3DCoord(x, 0, z)); } } }
private void _ApplyTransformation(TranformationFunc f, Discrete3DCoord new_dims) { int[,,] new_blocks = new int[new_dims.x, new_dims.y, new_dims.z]; for (int x = 0; x < this.dims.x; x++) { for (int y = 0; y < this.dims.y; y++) { for (int z = 0; z < this.dims.z; z++) { Discrete3DCoord new_coord = f(new Discrete3DCoord(x, y, z)); new_blocks[new_coord.x, new_coord.y, new_coord.z] = this.blocks[x, y, z]; } } } this.blocks = new_blocks; this.dims = new_dims; }
// Copy over a blueprint at location (x,y,z). // NOTE: If the blueprint would overflow any of the dimensions // the operation will truncate the design in order to fit. public void ApplyDesign(Blueprint design, int x_start, int y_start, int z_start) { int subdesign_id = this.next_subdesign_id; next_subdesign_id += design.next_subdesign_id; int[] my_dims = this.GetDimsArr(); int[] other_dims = design.GetDimsArr(); int[] copy_dims = { Mathf.Min(my_dims[0] - x_start, other_dims[0]), Mathf.Min(my_dims[1] - y_start, other_dims[1]), Mathf.Min(my_dims[2] - z_start, other_dims[2]) }; for (int x = 0; x < copy_dims[0]; x++) { for (int y = 0; y < copy_dims[1]; y++) { for (int z = 0; z < copy_dims[2]; z++) { if (design.blocks[x, y, z] > 0) { int this_x = x + x_start; int this_y = y + y_start; int this_z = z + z_start; this.blocks[this_x, this_y, this_z] = subdesign_id + design.blocks[x, y, z]; if (this_y + 1 < this.dims.y && this.blocks[this_x, this_y + 1, this_z] == 0) { attatchment_points.Add(new Discrete3DCoord(this_x, this_y + 1, this_z)); } Discrete3DCoord this_coord = new Discrete3DCoord(this_x, this_y, this_z); if (attatchment_points.Contains(this_coord)) { attatchment_points.Remove(this_coord); } } } } } }
public Blueprint(Discrete3DCoord dims) : this(dims.x, dims.y, dims.z) { }
public override bool Equals(object obj) { Discrete3DCoord other = obj as Discrete3DCoord; return(other.x == this.x && other.y == this.y && other.z == this.z); }