From 5c132631b3d449c724bd130ff35a6dba948c28c8 Mon Sep 17 00:00:00 2001 From: Nihilazo Date: Fri, 19 Mar 2021 16:10:24 +0000 Subject: [PATCH] floatingpointisation --- main.fs | 83 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 44 insertions(+), 39 deletions(-) diff --git a/main.fs b/main.fs index 8b5fe53..8b3fd03 100644 --- a/main.fs +++ b/main.fs @@ -1,5 +1,8 @@ \ JAVAPOOL - THE GAME (an incremental game based on the lore of #javapool on tilde.town) \ this code likely sucks, because I'm bad at forth and figuring stuff out as I go. +\ written for 64-bit gforth, might be portable to other forths with some tweaking, idk. + +include debug.fs \ ANSI escape sequences. gforth already provides at-xy and page, but I also need a word for clearing the current line and displaying the cursor. : hide-cursor esc[ ." ?25l" ; @@ -18,15 +21,13 @@ \ the word changed? leaves a -1 if the value has changed since last clear, 0 otherwise. : changed? ( addr offset -- flag ) cells + @ ; -\ initialise some variables that encode game state. -\ the variable "counter" holds the count of the current tick. It always starts at 0. -variable counter \ the variable "devices" holds the amount of devices currently in the pool. It has a change flag. It begins with the change flag set, to draw the screen the first time. -create devices 0 , -1 , -\ the variable "devicerate" is the amount of ticks between devices getting added. -variable devicerate -2000 devicerate ! -\ the variable "membercost" is the cost of hiring a new chat member. If it is zero, hiring chat members hasn't been unlocked yet. It has a change flag. +\ this variable can contain decimal-point amounts of devices. Things that need a non-decimal amount can round it with ftrunc. +create devices 0e f, -1 , +\ the variable "base-devices/tick" is the base amount of devices added per tick. +variable base-devices/tick +0.0005e base-devices/tick f! +\ the variable "membercost" is the cost of hiring a new chat member. If it is zero, hiring chat members hasn't been unlocked yet. It has a change flag and is fixed-point. create membercost 0 , 0 , \ the variable "membercount" is how many chat members you've hired. For each chat member, device gain delay decreases. variable membercount @@ -43,16 +44,21 @@ variable count-messages-shown \ set an initial message S" you feel like throwing some stuff into the pool." set-message +\ f+! is +! for floats +: f+! ( addr -- ) ( F: r -- ) dup f@ f+ f! ; + \ any-change? leaves a -1 on the stack if any value has changed, 0 otherwise : any-change? ( -- flag ) membercost 1 changed? devices 1 changed? message 2 changed? or or ; \ clear-all clears the change flag on all values. : clear-all membercost 1 cleared devices 1 cleared message 2 cleared ; \ the word !0= tests if something is non-zero -: !0= 0= 0= ; +: !0= ( n -- flag ) 0= 0= ; +\ the word f!0= tests if a floating thing is non-zero +: f!0= ( r -- flag ) f0= 0= ; \ the world unlock-members tests to see if hiring chat members can be unlocked. if so, they are unlocked. : unlock-members - devices @ 5 = membercost @ 0= and if + devices f@ ftrunc 5e f= membercost @ 0= and if 10 membercost ! S" A friendly townie wants to help out." set-message then ; @@ -62,23 +68,34 @@ S" you feel like throwing some stuff into the pool." set-message \ the word wait-tick waits a tick. Ticks are 1ms currently. : wait-tick 1 ms ; -\ the word tick-up ticks the counter up -: tick-up 1 counter +! ; +\ the word debug-console is used for entering debug mode. +: debug-console + page + ." Entering debug/cheat shell. use `restart` to restart the game." cr + .s cr f.s + quit ; +\ devices/tick calculates the amount of devices that are to be added per tick. +: devices/tick ( f: -- r ) + base-devices/tick f@ + membercount @ s>f 2000e f/ \ each member adds 0.5 d/s + f+ ; \ set-count-message sets the message to certain things based on the amount of devices in the pool. The count-messages-shown variable is used to track how many of these have already been shown. : set-count-message - devices @ 50 > count-messages-shown @ 1 < and if + devices f@ ftrunc 50e f> count-messages-shown @ 1 < and if S" The pool is starting to look a little cluttered. " set-message 1 count-messages-shown +! then ; \ the word game-tick runs a single tick of the game -: game-tick tick-up unlock - counter @ devicerate @ mod 0= if - 1 devices +! +: game-tick unlock + devices/tick devices f+! set-count-message - devices 1 changed then ; + \ TODO only set devices as changed on an integer change + \ this seems to somehow cause a float overflow lol + devices 1 changed + ; \ TODO saving \ the word exit-game exits the game. @@ -86,33 +103,20 @@ S" you feel like throwing some stuff into the pool." set-message \ the word hire-chat-member hires a chat member. -\ TODO something funky is going on with the rate past a certain point. find out where and why. +\ TODO subtract the membercost from the \ goes negative at 12 members, seems to be doing weird stuff before that with speeds. : hire-chat-member membercost @ dup !0= swap \ checks if member cost is nonzero, leaving member cost on the stack - devices @ <= \ tests if the member cost is less than the amount of devices we have + s>f devices f@ f<= \ tests if the member cost (converted to a float) is less than the amount of devices we have and if - devices @ membercost @ - devices ! \ remove devices that "pay" for the member - membercount @ dup !0= if \ membercount is nonzero - devicerate @ swap 1 + 750 swap / - devicerate ! \ TODO this line is causing the weirdness - else - devicerate @ 750 - devicerate ! drop - then + ." hit!" + devices f@ membercost @ s>f f- devices f! \ remove devices that pay for the member 1 membercount +! \ add a member to the count membercount @ 2 * 5 + membercost +! \ increase the cost of buying a new member membercost 1 changed S" " set-message \ blank the message, because we did a thing. then ; -\ the word debug-console is used for entering debug mode. -: debug-console - page - ." Entering debug/cheat shell. use `restart` to restart the game." - quit ; - -\ throw-device throws a device into the pool. -\ : throw-device 1 devices +! devices 1 changed ; - \ the word handle-input handles input every time around the game loop. : handle-input key? if key case @@ -126,7 +130,7 @@ S" you feel like throwing some stuff into the pool." set-message : print-rate 2 set-precision \ first convert to floating point, divide by 1000 to get seconds from milliseconds, then do 1/n to get the devices/second from seconds/device - ." (" devicerate @ s>f 1000e f/ 1e fswap f/ f. ." devices/second)"; + ." (" devices/tick 1000e f* f. ." devices/second)" ; \ draw-message draws the stored message on the screen. : draw-message @@ -135,7 +139,7 @@ S" you feel like throwing some stuff into the pool." set-message \ draw-devices draws the number of devices on the screen. : draw-devices - devices @ dup + devices f@ f>s dup 1 1 at-xy clear-line 1 = if ." There is 1 device in the javapool." drop else @@ -158,10 +162,11 @@ S" you feel like throwing some stuff into the pool." set-message ." (q)uit (without saving)" ; \ draw-screen redraws the screen, but only if there's been a change. -: draw-screen any-change? if draw-devices draw-actions draw-message clear-all then ; +: draw-screen any-change? if draw-devices draw-actions draw-message clear-all then ; +\ : draw-screen clear-all ; \ main game loop -: game-loop begin wait-tick game-tick handle-input draw-screen 0 until ; +: game-loop begin wait-tick game-tick handle-input draw-screen 0 until ; \ the seconds, minutes and hours words are used with skip-time in debugging. : seconds 1000 * ; @@ -175,4 +180,4 @@ S" you feel like throwing some stuff into the pool." set-message : restart page game-loop ; \ clear the screen and start the game -page hide-cursor game-loop ; +page hide-cursor game-loop