static bool isJumpPossible(GeneColumn start, GeneColumn end) { if (start == null || end == null) { return(false); } int xBlockDistance = Mathf.Abs(start.GlobalX - end.GlobalX); int direction = start.GlobalX < end.GlobalX ? 1 : -1; GeneColumn iterator = start.SeekNthColumn(direction); float xPixelDistance = xBlockDistance * Global.TilePixelWidth; float d = xPixelDistance; float H = maxJumpHeight; float K = -4 * H / (d * d); for (int i = 1; i <= xBlockDistance; i++) { float xi = Global.TilePixelWidth * i; float yi = K * xi * (xi - d); int maxObstacleHeight = (int)(yi / Global.TilePixelWidth) + start.ObstacleHeight; if (maxObstacleHeight < iterator.ObstacleHeight) { return(false); } iterator = iterator.SeekNthColumn(direction); if (iterator == null) { return(false); } } return(true); }
internal MapIndividual CrossoverWith(MapIndividual parent2) { Random random = new Random(); int mutableXRange = this.GenerationTail.GlobalX - this.GenerationHead.GlobalX + 1; int leftCrossLimit = (mutableXRange / 3); int rightCrossLimit = mutableXRange - (mutableXRange / 3); MapIndividual leftParent = random.Next(1) == 0 ? this : parent2; MapIndividual rightParent = leftParent == this ? parent2 : this; int maxTries = rightCrossLimit - leftCrossLimit + 1; int tries = 0; int originalCrossoverXPoint = random.Next(leftCrossLimit, rightCrossLimit); int crossoverXPoint = originalCrossoverXPoint; GeneColumn leftParentCrossPoint = leftParent.GenerationHead.SeekNthColumn(crossoverXPoint); GeneColumn rightParentCrossPoint = rightParent.GenerationHead.SeekNthColumn(crossoverXPoint); int lowestDiff = Mathf.Abs(leftParentCrossPoint.GroundHeight - rightParentCrossPoint.GroundHeight); // Make sure gene combination creates a valid individual int crossoverJump = 1; while (tries < maxTries && !IsCrossOverXValid(leftParentCrossPoint, rightParentCrossPoint)) { leftParentCrossPoint = leftParentCrossPoint.SeekNthColumn(crossoverJump); rightParentCrossPoint = rightParentCrossPoint.SeekNthColumn(crossoverJump); if (leftParentCrossPoint.GlobalX - leftParent.GenerationHead.GlobalX > rightCrossLimit) { leftParentCrossPoint = leftParent.GenerationHead.SeekNthColumn(leftCrossLimit); rightParentCrossPoint = rightParent.GenerationHead.SeekNthColumn(leftCrossLimit); } tries++; } // Here we start cloning the child genes from the left parent GeneColumn parentIterator = leftParent.Head; // Used to iterate over left parent GeneColumn childHead = new GeneColumn(parentIterator); // This head will be returned in the end GeneColumn childIterator = new GeneColumn(parentIterator.Next, childHead, null); // To actually iterate, this is used childHead.Next = childIterator; parentIterator = parentIterator.Next; // Pointing now to the second column // Now, starting from the 3rd column now, iterate until the crossover point is reached for (parentIterator = parentIterator.Next; parentIterator != leftParentCrossPoint; parentIterator = parentIterator.Next) { // We need to clone the parent's genes, but link to the child neighbor columns. GeneColumn nextChildColumn = new GeneColumn(parentIterator, childIterator, null); childIterator.Next = nextChildColumn; childIterator = nextChildColumn; } // Copy right parent genetic code to child, starting from crossover point. for (parentIterator = rightParentCrossPoint; parentIterator != null; parentIterator = parentIterator.Next) { GeneColumn nextChildColumn = new GeneColumn(parentIterator, childIterator, null); childIterator.Next = nextChildColumn; childIterator = nextChildColumn; } // Finally, create an individual from the child genetic code! MapIndividual childIndividual = new MapIndividual(childHead); return(childIndividual); }