Last active
August 29, 2015 14:02
-
-
Save nicklanng/394b4122c68282263c95 to your computer and use it in GitHub Desktop.
F# Spacewar Exploration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[<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