floatingpointisation

This commit is contained in:
Nico 2021-03-19 16:10:24 +00:00
parent 068fdd65af
commit 5c132631b3
1 changed files with 44 additions and 39 deletions

83
main.fs
View File

@ -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