Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Game programming in general will test your ability to manage complexity. I find that functional programming encourages you to break problems your solving into smaller pieces.</p> <p>The first thing you want to do is turn your script into a bunch of functions by separating all the different concerns. I know it sounds silly but the very act of doing this will make the code more functional (pun intended.) Your main concern is going to be state management. I used a record to manage the position state and a tuple to manage the running state. As your code gets more advanced you will need objects to manage state cleanly.</p> <p>Try adding more to this game and keep breaking the functions apart as they grow. Eventually you will need objects to manage all the functions.</p> <p>On a game programming note don't change state to something else and then change it back if it fails some test. You want minimal state change. So for instance below I calculate the <code>newPosition</code> and then only change the <code>playerPosition</code> if this future position passes.</p> <pre><code>open System // use a third party vector class for 2D and 3D positions // or write your own for pratice type Pos = {x: int; y: int} with static member (+) (a, b) = {x = a.x + b.x; y = a.y + b.y} let drawBoard map = //clear the console Console.Clear() //send each row of the map to the Console map |&gt; List.iter (printfn "%s") let movePlayer (keyInfo : ConsoleKeyInfo) = match keyInfo.Key with | ConsoleKey.UpArrow -&gt; {x = 0; y = -1} | ConsoleKey.DownArrow -&gt; {x = 0; y = 1} | ConsoleKey.LeftArrow -&gt; {x = -1; y = 0} | ConsoleKey.RightArrow -&gt; {x = 1; y = 0} | _ -&gt; {x = 0; y = 0} let validPosition (map:string list) position = map.Item(position.y).Chars(position.x) = ' ' //clear the square player was standing on let clearPlayer position = Console.SetCursorPosition(position.x, position.y) Console.Write( ' ' ) //draw the square player is standing on let drawPlayer position = Console.SetCursorPosition(position.x, position.y) Console.Write( '@' ) let takeTurn map playerPosition = let keyInfo = Console.ReadKey true // check to see if player wants to keep playing let keepPlaying = keyInfo.Key &lt;&gt; ConsoleKey.Q // get player movement from user input let movement = movePlayer keyInfo // calculate the players new position let newPosition = playerPosition + movement // check for valid move let validMove = newPosition |&gt; validPosition map // update drawing if move was valid if validMove then clearPlayer playerPosition drawPlayer newPosition // return state if validMove then keepPlaying, newPosition else keepPlaying, playerPosition // main game loop let rec gameRun map playerPosition = let keepPlaying, newPosition = playerPosition |&gt; takeTurn map if keepPlaying then gameRun map newPosition // setup game let startGame map playerPosition = drawBoard map drawPlayer playerPosition gameRun map playerPosition //define the map let map = [ " "; " "; " "; " "; " ############################### "; " # # "; " # ###### # "; " # # # # "; " #### #### # # # "; " # # # # # # "; " # # # # # # "; " #### #### ###### # "; " # = # "; " # = # "; " ############################### "; " "; " "; " "; " "; " " ] //initial player position on the map let playerPosition = {x = 8; y = 6} startGame map playerPosition </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload