Created
June 10, 2020 04:03
-
-
Save LukePammant/80d9bd74b4d009d66386e69ceb4f812f to your computer and use it in GitHub Desktop.
An attempt to learn F# & functional programming by building something for my game. This script should simple take a Miner and a Minable object and move resources from the Minable to the Minable while taking into account capacity on the Miner and availability on the Minable.
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
type ResourceType = Metal | Gas | |
type MinerId = MinerId of string | |
type MinerResource = | |
{ Type: ResourceType | |
Capacity: int | |
CurrentAmount: int | |
GatherRate: int } | |
type Miner = { Id: MinerId; Resources: MinerResource list } | |
type MinableId = MinableId of string | |
type MinableResource = { Type: ResourceType; MinableAmount: int } | |
type Minable = { Id: MinableId; Resources: MinableResource list } | |
type ResourceToMine = { Type: ResourceType; Amount: int } | |
type MiningResult = | |
{ Type: ResourceType | |
RemaingAmount: int | |
MinedAmount: int } | |
let getMatchingResourceOrEmpty (minableResources: MinableResource list) resourceType = | |
let resourceResult = minableResources |> List.tryFind (fun x -> x.Type = resourceType) | |
match resourceResult with | |
| Some resource -> resource | |
| None -> { Type = resourceType; MinableAmount = 0 } | |
let getMinerCollectionRates (storage: MinerResource) = | |
match ((storage.CurrentAmount + storage.GatherRate) > storage.Capacity) with | |
| true -> { Amount = storage.Capacity - storage.CurrentAmount; Type = storage.Type } | |
| false -> { Amount = storage.GatherRate; Type = storage.Type } | |
let getMinableAmount (minableResources: MinableResource list) (amountToMine: ResourceToMine) = | |
let a = getMatchingResourceOrEmpty minableResources amountToMine.Type | |
{amountToMine with Amount = min a.MinableAmount amountToMine.Amount} | |
let subtractResources (minableResource: MinableResource) (resourcesToMine: ResourceToMine list) = | |
let resourceResult = resourcesToMine |> List.tryFind (fun x -> x.Type = minableResource.Type) | |
match resourceResult with | |
| Some resource -> { minableResource with MinableAmount = minableResource.MinableAmount + resource.Amount } | |
| None -> minableResource | |
let addResources (minerResource: MinerResource) (resourcesToMine: ResourceToMine list) = | |
let resourceResult = resourcesToMine |> List.tryFind (fun x -> x.Type = minerResource.Type) | |
match resourceResult with | |
| Some resource -> { minerResource with CurrentAmount = minerResource.CurrentAmount + resource.Amount } | |
| None -> minerResource | |
let mine (miner: Miner) (minable: Minable) = | |
let amountToMine = miner.Resources |> List.map (getMinerCollectionRates >> (getMinableAmount minable.Resources)) | |
let minerResources = miner.Resources |> List.map (fun minerResource -> addResources minerResource amountToMine) | |
let minableResources = minable.Resources |> List.map (fun minableResource -> subtractResources minableResource amountToMine) | |
({ miner with Resources = minerResources }, { minable with Resources = minableResources }) | |
// Test if it works | |
let minableResources = [ | |
{ Type = Metal; MinableAmount = 500 } | |
] | |
let minable = { Id = MinableId "abc"; Resources = minableResources } | |
let minerResources = [ | |
{ Type = Metal; CurrentAmount = 0; Capacity = 500; GatherRate = 10 } | |
{ Type = Gas; CurrentAmount = 0; Capacity = 500; GatherRate = 10 } | |
] | |
let miner: Miner = { Id = MinerId "cba"; Resources = minerResources } | |
let result = mine miner minable | |
printfn "%O" result |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment