Closed schrum2 closed 1 year ago
Actually, instead of two HashSets, let's have a HashMap<MinecraftCoordinates, Block>
for the blocks and then a HashSet<MinecraftCoordinates>
for the empty space
The type T
for the Genotype<T>
will be Pair<HashMap<MinecraftCoordinates, Block>, HashSet<MinecraftCoordinates>>
Make a helper method in this class: Block getBlockAtLocation(MinecraftCoordinates coord)
that returns a Block
from blocks
if it exists, or creates an AIR
block for those coordinates if the location is in the empty spaces. Also, make a method placeBlock(Block block)
that puts a block into the shape. It replaces what is already there. If there is a block at the location, change the type and orientation to match the new one. If the space is empty, then remove the coordinates from the empty spaces.
Once you have these, implement crossover in the following way:
Save a copy
of the input parameter genotype (you will modify this)
Nest three loops to go through all the x, y, z coordinates.
For each set of (x,y,z) coordinates, do a RandomNumbers
coin flip.
If true, then call this.getBlockAtLocation
and copy.getBlockAtLocation
and save the results in variables.
Call this.placeBlock
and copy.placeBlock
, but swap the blocks returned from the previous calls so that the blocks from each shape go to the other.
This will make copy
be roughly half from one parent, and half from the other. Return copy
Look at the mutate
method of TWEANNGenotype
.
There is a StringBuilder
for logging purposes. Then you have classes being constructed that extend Mutation
. However, you should make a new abstract class MinecraftShapeMutation
that is sort of like the TWEANNMutation
class. This class will be responsible for indicating that mutation will be performed if a random number is less than a "rate" associated with it. The "rate" for each specific type of mutation will be specified by a command line parameter in the individual classes that extend MinecraftShapeMutation
(once again, similar to the mutation operations that extend TWEANNMutation
)
There is an issue with the fitness function we can't test further until #904 is resolved.
@TjRaffert You still need to add support for all the mutation operators in the mutate method
Assertion errors indicate that the placeBlock
method is probably the source of the error with AIR blocks. This is probably causing other hidden errors as well. Basically, the behavior of placeBlock
needs to depend on whether the input parameter is a block with type AIR
or not. If the block being placed is AIR
, then it needs to be handled differently than is currently being done.
I think I fixed it with the last commit I got both back up and running again.
Once of the purposes behind this was the hope that directly manipulating the shape would make it easier to search the space of possible shapes. So, re-do these simple experiments with this encoding (neither requires simulation, so you can run it on a machine that already has a Minecraft server running).
These can stop running as soon as it is clear we are covering the whole archive, but if that does not happen, we have a problem. Either way, post pictures of the final archives in this issue thread to report.
TESTING-MEObserverVectorPistonOrientation100_MAPElites.pdf This is the WHD it is getting full coverage. The image above also shows the same results if not better compared to the encoding before.
I think a lot of the problems we are having exploring the search space deals with a poor genome encoding. The steps from real-valued vector or even integer encoding make it difficult to manipulate the corresponding shape correctly. Some of the changes in issue #879 seem promising, but I think we can do better.
Make a
MinecraftShapeGenotype
class inedu.southwestern.tasks.evocraft.genotype
(a new package).This will represent a shape as two HashSets. One is a HashSet of Blocks in the shape. The other is a HashSet of MinecraftCoordinates that are empty, meaning that they are block positions that can potentially hold part of the shape. You will need to make a new
ShapeGenerator
class for this genotype, but it will be trivial: Just take the elements from the HashSet of Blocks and put them in a list.The reason for this new encoding is that it allows us to define some mutation operators that are more appropriate for Minecraft and make it easier to search the space. Store these in a new package:
edu.southwestern.tasks.evocraft.mutation
RemoveBlockMutation
: pick a random block from the Block set and remove it. Add that block's coordinates to the empty block set. If the Block set is empty, do nothing.AddBlockMutation
: pick random coordinates to remove from the empty block set, and pick a random block type. Add a new block of that type (with random orientation) at the specified coordinates to the block set. If the empty block set is empty, do nothing.ChangeBlockTypeMutation
: pick a random block from the block set and assign a random type. If the set is empty, do nothing. Make sure the new type is different from what it was beforeChangeBlockOrientationMutation
: pick random block and assign new mutation that is different from what it was before. Do nothing if block set is empty.SwapBlocksMutation
: if block set has at least two blocks, pick two random blocks and swap their coordinates.That's enough for now. We may have more later.
Each of these mutation types will need to have their own command line parameters indicating what their rate of occurrence is. We can discuss appropriate default values once you have a prototype running.