// GetScore determines how "good" a track is. Should take into account: // // - How close the track is to forming a complete loop // - How many collisions exist in the track // - Whether the car can make it all the way around the track // // As well as other components that mark a track as "interesting". func GetScore(t []tracks.Element) (int64, scoreData) { if len(t) == 0 { return 0, scoreData{} } vectors := geo.Vectors(t) stationStart := geo.Vector{geo.Point{0, 0, 0}, 0} trackEnd := vectors[len(t)-1] if trackEnd.Dir >= 350 { log.Panic("trackend is too high", trackEnd.Dir) } trackPieces := CompleteTrack(t[len(t)-1], trackEnd, stationStart) startingScore := int64(2700 * 1000) completedTrack := append(t, trackPieces...) data := &tracks.Data{ Elements: completedTrack, Clearance: 2, ClearanceDirection: tracks.CLEARANCE_ABOVE, } numCollisions := geo.NumCollisions(data) numNegativeSpeed := physics.NumNegativeSpeed(data) return startingScore - 8000*int64(len(trackPieces)) - 10000*int64(numCollisions) - 5000*int64(numNegativeSpeed), scoreData{ Collisions: numCollisions, Distance: len(trackPieces), NegativeSpeed: numNegativeSpeed, } }
// GetScore determines how "good" a track is. Should take into account: // // - How close the track is to forming a complete loop // - How many collisions exist in the track // - Whether the car can make it all the way around the track // // As well as other components that mark a track as "interesting". func GetScore(t []tracks.Element) int64 { if len(t) == 0 { return 0 } eΔ, forwardΔ, sidewaysΔ := 0, 0, 0 direction := tracks.DIR_STRAIGHT // XXX, we're probably computing this multiple times. for i := range t { ts := t[i].Segment eΔ, forwardΔ, sidewaysΔ, direction = geo.Advance( ts, eΔ, forwardΔ, sidewaysΔ, direction) } vectors := geo.Vectors(t) stationStart := geo.Vector{geo.Point{0, 0, 0}, 0} trackEnd := vectors[len(t)-1] trackPieces := completeTrack(trackEnd, stationStart) return int64(10*1000*1000 - 4000*len(trackPieces)) }
// CreateMineTrainRide takes a track and builds all the rest of the ride // structure around it // // complete: Whether to return a completed track or a partial one. Note RCT2 // will crash unless you return a complete track func CreateMineTrainRide(elems []tracks.Element, complete bool) *Ride { coaster := NewCoaster() coaster.RideType = RIDE_MINE_TRAIN coaster.VehicleType = VEHICLE_MINE_TRAIN x, y := geo.XYSpaceRequired(elems) coaster.XSpaceRequired = x coaster.YSpaceRequired = y if complete { vectors := geo.Vectors(elems) stationStart := geo.Vector{geo.Point{0, 0, 0}, 0} trackEnd := vectors[len(elems)-1] completeTrack := genetic.CompleteTrack(elems[len(elems)-1], trackEnd, stationStart) fmt.Println(elems[len(elems)-1]) fmt.Printf("%#v\n", trackEnd) for i := 0; i < len(completeTrack); i++ { fmt.Println(tracks.ElementNames[completeTrack[i].Segment.Type]) } fmt.Println("====") coaster.TrackData = tracks.Data{ Elements: append(elems, completeTrack...), Clearance: 2, ClearanceDirection: tracks.CLEARANCE_ABOVE, } } else { coaster.TrackData = tracks.Data{ Elements: elems, Clearance: 2, ClearanceDirection: tracks.CLEARANCE_ABOVE, } } coaster.HasLoop = false coaster.SteepLiftChain = false coaster.CurvedLiftChain = false coaster.Banking = false coaster.SteepSlope = false coaster.FlatToSteep = false coaster.SlopedCurves = false coaster.SteepTwist = false coaster.SBends = false coaster.SmallRadiusCurves = false // copied from whatever this value is in mine-train.td6 coaster.DatData = []uint8{0x80, 0x46, 0xc1, 0x8, 0x41, 0x4d, 0x54, 0x31, 0x20, 0x20, 0x20, 0x20, 0xad, 0x74, 0xec, 0xe8} return coaster }