Skip to content

Instantly share code, notes, and snippets.

@nicklanng
Last active August 29, 2015 14:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nicklanng/394b4122c68282263c95 to your computer and use it in GitHub Desktop.
Save nicklanng/394b4122c68282263c95 to your computer and use it in GitHub Desktop.
F# Spacewar Exploration
[<Measure>]
type ly;
[<Measure>]
type s;
type Coordinate = {
x: float<ly>
y: float<ly>
z: float<ly>
}
let add coordinate1 coordinate2 = {
x = coordinate1.x + coordinate2.x
y = coordinate1.y + coordinate2.y
z = coordinate1.z + coordinate2.z
}
let subtract subtrahend minuend = {
x = minuend.x - subtrahend.x
y = minuend.y - subtrahend.y
z = minuend.z - subtrahend.z
}
let magnitude coordinate =
let x = ((float)coordinate.x ** 2.0 + (float)coordinate.y ** 2.0 + (float)coordinate.z ** 2.0) ** 0.5
LanguagePrimitives.FloatWithMeasure<ly> x
let divideScalar divisor dividend = {
x = dividend.x / (float)divisor
y = dividend.y / (float)divisor
z = dividend.z / (float)divisor
}
let multiplyScalar factor coordinate = {
x = coordinate.x * (float)factor
y = coordinate.y * (float)factor
z = coordinate.z * (float)factor
}
let normalize coordinate =
let magnitudeOfCoordinate =
coordinate
|> magnitude
match magnitudeOfCoordinate with
| 0.0<ly> ->
coordinate
| _ ->
coordinate
|> divideScalar magnitudeOfCoordinate
type ShipId = ShipId of int
type Ship = {
Id: ShipId
Speed: float<ly/s>
}
type FleetId = FleetId of int
type FleetName = FleetName of string
type Fleet = {
Id: FleetId
Name: FleetName
Coordinates: Coordinate
Ships: Ship list
}
let speed fleet =
match fleet.Ships with
| [] ->
0.0<ly/s>
| _ ->
fleet.Ships
|> List.map (fun ship -> ship.Speed)
|> List.min
let assign ship fleet =
{ fleet with Ships = ship :: fleet.Ships }
let unassign ship fleet =
{ fleet with Ships = fleet.Ships |> List.filter (fun x -> x <> ship) }
let moveTowards targetCoordinate (seconds:float<s>) fleet =
let distanceMoved = (fleet |> speed) * seconds
let movementVector =
targetCoordinate
|> subtract fleet.Coordinates
|> normalize
|> multiplyScalar distanceMoved
{ fleet with Coordinates = fleet.Coordinates |> add movementVector }
//----------------------------
let coordinates = {
x = 0.0<ly>;
y = 0.0<ly>;
z = 0.0<ly>;
}
let targetCoordinates = {
x = 2.0<ly>;
y = 0.0<ly>;
z = 0.0<ly>;
}
let ship = {
Id = ShipId 1
Speed = 2.0<ly/s>
}
//let ship2 = {
// Id = ShipId 2
// Speed = Speed 2.0
//}
//
let fleet = {
Id = FleetId 1
Name = FleetName "Boom"
Coordinates = coordinates
Ships = []
}
//
////-----------------------------
//
let fleet2 = fleet |> assign ship
//
//let fleet3 = fleet |> unassign ship
fleet2 |> moveTowards targetCoordinates 1.0<s>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment