Featured post
Very simple RogueLike in F#, making it more "functional" -
i have existing c# code very, simple roguelike engine. deliberately naive in trying minimum amount possible. move @ symbol around hardcoded map using arrow keys , system.console:
//define map var map = new list<string>{ " ", " ", " ", " ", " ############################### ", " # # ", " # ###### # ", " # # # # ", " #### #### # # # ", " # # # # # # ", " # # # # # # ", " #### #### ###### # ", " # = # ", " # = # ", " ############################### ", " ", " ", " ", " ", " " }; //set initial player position on map var playerx = 8; var playery = 6; //clear console console.clear(); //send each row of map console map.foreach( console.writeline ); //create empty consolekeyinfo storing last key pressed var keyinfo = new consolekeyinfo( ); //keep processing key presses until player wants quit while ( keyinfo.key != consolekey.q ) { //store player's current location var oldx = playerx; var oldy = playery; //change player's location if pressed arrow key switch ( keyinfo.key ) { case consolekey.uparrow: playery--; break; case consolekey.downarrow: playery++; break; case consolekey.leftarrow: playerx--; break; case consolekey.rightarrow: playerx++; break; } //check if square player trying move empty if( map[ playery ][ playerx ] == ' ' ) { //ok empty, clear square standing on before console.setcursorposition( oldx, oldy ); console.write( ' ' ); //now draw them @ new square console.setcursorposition( playerx, playery ); console.write( '@' ); } else { //they can't move there, change location old location playerx = oldx; playery = oldy; } //wait them press key , store in keyinfo keyinfo = console.readkey( true ); }
i playing around doing in f#, trying write using functional concepts, turned out bit on head, did pretty straight port - it's not really f# program (though compiles , runs) it's procedural program written in f# syntax:
open system //define map let map = [ " "; " "; " "; " "; " ############################### "; " # # "; " # ###### # "; " # # # # "; " #### #### # # # "; " # # # # # # "; " # # # # # # "; " #### #### ###### # "; " # = # "; " # = # "; " ############################### "; " "; " "; " "; " "; " " ] //set initial player position on map let mutable playerx = 8 let mutable playery = 6 //clear console console.clear() //send each row of map console map |> seq.iter (printfn "%s") //create empty consolekeyinfo storing last key pressed let mutable keyinfo = consolekeyinfo() //keep processing key presses until player wants quit while not ( keyinfo.key = consolekey.q ) //store player's current location let mutable oldx = playerx let mutable oldy = playery //change player's location if pressed arrow key if keyinfo.key = consolekey.uparrow playery <- playery - 1 else if keyinfo.key = consolekey.downarrow playery <- playery + 1 else if keyinfo.key = consolekey.leftarrow playerx <- playerx - 1 else if keyinfo.key = consolekey.rightarrow playerx <- playerx + 1 //check if square player trying move empty if map.item( playery ).chars( playerx ) = ' ' //ok empty, clear square standing on console.setcursorposition( oldx, oldy ) console.write( ' ' ) //now draw them @ new square console.setcursorposition( playerx, playery ) console.write( '@' ) else //they can't move there, change location old location playerx <- oldx playery <- oldy //wait them press key , store in keyinfo keyinfo <- console.readkey( true )
so question is, need learn in order rewrite more functionally, can give me hints, vague overview, kind of thing.
i'd prefer shove in right direction rather seeing code, if that's easiest way explain me fine, in case can please explain "why" rather "how" of it?
game programming in general test ability manage complexity. find functional programming encourages break problems solving smaller pieces.
the first thing want turn script bunch of functions separating different concerns. know sounds silly act of doing make code more functional (pun intended.) main concern going state management. used record manage position state , tuple manage running state. code gets more advanced need objects manage state cleanly.
try adding more game , keep breaking functions apart grow. need objects manage functions.
on game programming note don't change state else , change if fails test. want minimal state change. instance below calculate newposition
, change playerposition
if future position passes.
open system // use third party vector class 2d , 3d positions // or write own pratice type pos = {x: int; y: int} static member (+) (a, b) = {x = a.x + b.x; y = a.y + b.y} let drawboard map = //clear console console.clear() //send each row of map console map |> list.iter (printfn "%s") let moveplayer (keyinfo : consolekeyinfo) = match keyinfo.key | consolekey.uparrow -> {x = 0; y = -1} | consolekey.downarrow -> {x = 0; y = 1} | consolekey.leftarrow -> {x = -1; y = 0} | consolekey.rightarrow -> {x = 1; y = 0} | _ -> {x = 0; y = 0} let validposition (map:string list) position = map.item(position.y).chars(position.x) = ' ' //clear square player standing on let clearplayer position = console.setcursorposition(position.x, position.y) console.write( ' ' ) //draw square player standing on let drawplayer position = console.setcursorposition(position.x, position.y) console.write( '@' ) let taketurn map playerposition = let keyinfo = console.readkey true // check see if player wants keep playing let keepplaying = keyinfo.key <> consolekey.q // player movement user input let movement = moveplayer keyinfo // calculate players new position let newposition = playerposition + movement // check valid move let validmove = newposition |> validposition map // update drawing if move valid if validmove clearplayer playerposition drawplayer newposition // return state if validmove keepplaying, newposition else keepplaying, playerposition // main game loop let rec gamerun map playerposition = let keepplaying, newposition = playerposition |> taketurn map if keepplaying gamerun map newposition // setup game let startgame map playerposition = drawboard map drawplayer playerposition gamerun map playerposition //define map let map = [ " "; " "; " "; " "; " ############################### "; " # # "; " # ###### # "; " # # # # "; " #### #### # # # "; " # # # # # # "; " # # # # # # "; " #### #### ###### # "; " # = # "; " # = # "; " ############################### "; " "; " "; " "; " "; " " ] //initial player position on map let playerposition = {x = 8; y = 6} startgame map playerposition
- Get link
- X
- Other Apps
Comments
Post a Comment