dc: A Primer
Even though I generally have an HP or two handy, the POSIX command-line RPN calculator, dc
, is probably the calculator that I use most often. The manpage is pretty clear on its operation, albeit in a very manpagish way. While the manpage makes for a nice reference, I’ve not seen a friendly, readable primer available on the program before. This is likely because there aren’t really people lining up to use dc
, but there are a couple of compelling reasons to get to know it. First, it’s a (and in fact, the only calculator, if memory serves) required inclusion in a POSIX-compliant OS. This is important if you’re going to be stuck doing calculations on an unknown system. It’s also important if you’re already comfortable in a postfix environment, as the selection of such calculators can be limiting.
The Basics
First of all, if you’re not familiar with postfix/RPN, it works on the principle of building a stack of objects and then operating on them rather than evaluating a statement of mixed up objects and operators. While many are used to the latter (infix or algebraic), it’s often a rather inefficient method of computation. That’s not really a debate for right now, however, because dc
is a postfix calculator, so that’s what you’re stuck with. The thing to take away from all of this is that rather than calculations being input like (5 + 3) * 2 =
, they are entered like 5 3 + 2 *
. In dc
, whitespace is mostly meaningless. The only time it is really necessary is when putting multiple numbers on the stack. If we want to put 5, 3, and 2 on the stack, we must separate it out 5 3 2
, else we’re putting a single number, 532 on the stack. This whitespace can be a space or a newline.
Hitting enter evaluates the current line. Basic arithmetic, the four commands +
, -
, /
, and *
work as expected. By default, nothing is returned to the screen; to get the last entry on the stack (the result of basic operations), the command p
must also be executed. So, to get to the bottom of (32*2)/4, we would input 32 2 * 4 / p
, and get 16
returned. Of course, since whitespace is optional, this can also be entered as 32 2*4/p
. Note, for postfix newbies, that parenthesis are never necessary, as ambiguity is impossible.
The full contents of the stack can be displayed using the command f
, and the stack can be fully cleared using the command c
. The command !
executes the remainder of the line as a shell command, thus I often clear my screen at the same time as my stack by executing c!clear
. Two other stack manipulations that come up often are d
to duplicate the last item on the stack, and r
to swap (or reverse) the last two items.
Precision is arbitrary and fixed using the command k
. Certain operations ‘float’ to an extent, that is, 2.25 2*p
returns 4.50
, though 4.50 2/p
does not follow, returning 2
. Thus, the first thing I usually do when I open dc
is give myself a few points of precision, generally four, by entering 4k
. Upon doing this, 4.5 2/p
properly returns 2.2500
. The currently set precision can be pushed to the stack with the command K
, a scheme that we’ll see again with operating radices. If we’ve set 4k
, entering Kp
should then return 4
.
Input and output radices (bases) are controlled with the commands i
and o
, respectively. To output in hexadecimal, enter 16o
. To input in binary, enter 2i
. If you’re going to be working in a given radix (input and output), it’s probably best for your sanity to adjust output first and then input, since such things take place immediately. That is, both 16o16i
and 16i10o
change both input and output to hexadecimal, but the first choice is much clearer. Likewise, when you need to switch again, be mindful of your current input radix. If we have 16i
set, and we need to get back to decimal, 10i
will not work (it will simply re-set input to hex). Instead, we need to remember we’re inputting in hex, and use Ai
instead. Conversion from-radix-to-radix are as simple as setting unmatched input and output radices. Assuming our input is set to decimal, and we need to convert to binary, we will just leave input alone and enter 2o
. Then, entering 48p
will convert that decimal 48 to binary, returning 110000
. We can then set 16i
if we want to convert from hex to binary, enter AFp
, and get the result 10101111
. We can use I
and O
to push the respective radices onto the stack — but again, keep in mind, they will ultimately be output in the current output radix. Thus, O
will always return 10
, making it useless outside of macros.
Strings, Registers, Macros, Comparisons
For the most part, strings are handled pretty transparently inside of dc
. Anything wrapped in square brackets is considered a string. Strings sit on the stack like numbers, and can be printed using the same p
command. Strings can be used to prompt users for input, provide context for output, or, most importantly, define macros (akin to functions). A macro is simply a string containing a bunch of dc
commands, such as [8 4*]
being a macro that multiplies eight by four. Macros are, most basically, executed with the command x
. Thus, [8 4*]xp
will define our macro (pushing it onto the stack), execute it, and then print the result.
The manpage for dc
claims that ‘at least 255′ registers can be defined. A register, for those unfamiliar, is akin to a variable. It’s a place where information can be stored and then retrieved later. Registers in dc
are complex — they contain their own stacks, and can also be indexed arrays. For the purposes of this primer, we’re only going to deal with simple registers, each holding a single piece of data. This piece of data can be anything that would sit on the stack — that is, either a number or a string (including macros). The command sr
is used to store a value in a register, and lr
is used to load the value of a register back onto the stack. In both cases, r
is a single character used to name the register. So, entering 42sa
puts the value 42 into a register named ‘a.’ Later, when we need to retrieve this undeniably useful number, we can execute la
, and then p
to see that we do, in fact, have our 42 back.
The ability to store and retrieve macros is one of the most powerful tools at our disposal in dc
. If we need to multiply a number by 65535, we can create and store a macro [65535*]sb
. Then, we can do things like (whitespace added for clarity from here on) 1 lb x p 2 lb x p 3 lb x p
and get back 65535
, 131070
, and 196605
, as expected. To make a macro that converts the current stack value into hex, we can enter [O sz 16 o p lz o]sc
. To run this, we can leave our input as decimal, and do things like 15 lc x 64 lc x 255 lc x
, returning F
, 40
, and FF
.
Comparative operations in dc
work by making the comparison, and if it ends up being true, running a set macro. Where r is the register containing the macro to run, the following comparators are available: >r
(greater than), <r
(less than), !>r
(not greater than — put simply, less than or equal to), !<r
(not less than — again, put simply, greater than or equal to), =r
(equal to), !=r
(not equal to). If we define a simple macro to echo ‘true’ upon execution, [ [true] p ]sd
, we can do some quick comparisons. Entering 5 6 >d 6 5 >d 6 6 !=d 6 6 =d
will return true
, (null), (null), and true
, as our macro d
is only executed on the two that are true — 6 greater than 5, and 6 equal to 6.
For loops can be constructed using comparators that call the macro they’re inside. For instance, a typical for ($i=0; $i<10; $i++){ echo $i; }
can be expressed as 0 si [li p 1+ d si 10>e] se lex
. First, we initialize i
as 0 ($i=0), then we set up our ‘for loop’ macro. Our macro first loads i
back onto the stack, then it prints it out (echo $i), adds one ($i++), duplicates it (because storing it will pop one instance off the stack — and we need it to still be there for the next step), and finally checks if it’s less than 10 ($i<10), running the macro e
if this is the case. We save this macro as e
, and then run it, giving us a printout of the numbers 0-9.
The end, for now
This should serve as a pretty good introduction to the operations of dc
, while not covering all of its commands or capabilities. I’m bound to write more on the matter at some point, but until now have never seen a good way for newbies to break in to the program. The manpage covers things I didn’t, including the more complicated register and array operations, as well as commands for getting extra division operation results, exponents (6 3 ^ p
returns 216
), and square roots (64 v p
returns 8
). All of the examples given in this primer can also be viewed in exploded, commented form in this document (if you’re using vim, it’ll look best with my dc syntax file). I can’t fathom a life without dc
, the simple yet powerful RPN calculator that can be found nearly everywhere.
Variant Chess in FENipulator
FENipulator 1.5-1.7 have been released, and they are all about chess variants. The full changelog reveals all the saucy details, but I’ll point out the big ones here. First, in order to accommodate certain chess variants, two fairy pieces have been added to the unicode and simple piecesets — the archbishop and the chancellor. They correspond to FEN a and c, and are represented as such in the simple set. In the unicode set, the archbishop is a bishop rotated 90º, and the chancellor a rook rotated 90º. Additionally, my friend and sometimes design partner Alex Coblentz has illustrated six or seven new piecesets which I am slowly building into files and adding as time permits. They’re pretty awesome, and I’m pretty excited about them.
The first variant to make its way into FENipulator is 960 chess. 960 is a randomized opening, adhering to certain rules — home ranks match between players, bishops are counter-color, king is always between rooks. Castling in 960 is as in orthodox chess (that is, the file the king and rook end up on are the same as in orthodox), which meant a major rewrite of the castling code. New functions were thrown in to determine where the king sits on the board — this is necessary to determine if a rook is a- or h-side. A king must also be able to move onto himself now, because castling in 960 can mean the king (or the rook) never moves.
Large Boards (and Small Boards)
Previous to v1.6, boards were largely hardcoded to be 8×8. Presentation of a smaller board may have been possible, but moving sure wasn’t. Larger boards were out of the question. The board is now entirely flexible, allowing board sizes from 1×1 to 26×26. Theoretically, the code will allow for board size up to 99×99, but files start outputting character codes that confuse it right now — best to stick to only an alphabet’s worth. Several shortcuts have been programmed in for large board variants — submitting ‘gothic,’ ‘embassy,’ ‘capablanca,’ or ‘grand’ for FEN results in the opening boards for the respective games. Unfortunately no custom castling rules have been implemented yet — I’m unsure how castling works in Gothic and Capablanca chess, and Embassy chess will require custom rules. If all three are the same, one rule can exist for a 10-wide board, otherwise I’m not sure how I’ll handle it. In the meantime, castling can be achieved manually by resetting the turn value in FEN and performing two moves. Grand chess doesn’t allow castling, so there is no issue there.
Alice Chess (and Ms. Alice Chess)
Version 1.7 brings a rather fun variant, Alice Chess, playable at fenipulator.brhfl.com/alice.php. Alice is played on two boards, with every move transferring to the opposite board. Every move must be legal on the board it’s played on, and every destination space must be empty on the opposite board. This condition is not yet checked for validity, but probably will be in the future (can be a hassle to keep track of manually). A straight drop (or zero move) is possible (for the variant Ms. Alice Chess) by picking a piece to move, and then clicking it again as the destination. All moves on FENipulator Alice should be done on the same board — then FENipulator Alice handles the transfer. Two shortcuts to common variants are available here as well, by entering ‘small’ or ‘opposite’ into the FEN box. Small is a variant playable on a single board (though FENipulator Alice presents it as two half-boards), and opposite is a variant where black and white start on opposite boards.Since FENipulator works exclusively by manipulating FEN data, a specialized FEN must be used to track two boards. Since I’ve not seen an official solution to this, FENipulator separates both boards with a pipe (|), resulting in a starting FEN board representation of rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR|8/8/8/8/8/8/8/8
. There are mixed beliefs bout castling and en passant in Alice, and for now, for the sake of getting the code working at all, neither are possible in FENipulator Alice.
Next up in the short-term are the aforementioned validity checks for Alice, castling and en passant in Alice, and castling on large boards. Also, for the sake of chess problems, &c. a third turn state will be added, allowing universal movement. Shortcuts will be added for orthodox, 960, and Alice, and a page outlining all variant shortcuts will be made. Board flipping is going to be moved to the Options page, with options for always, white, black, and never. After these changes, code needs to be cleaned up, and a core file should be made for code shared between standard and Alice FENipulator. This will help in the future if other board variants are necessary (Omega, for instance).
FENipulator
FENipulator is my latest project, a chess board application written in PHP. I call it a chess board application and not a chess application, because of its dumb nature. With a few small exceptions, it does not care about (or, frankly, know) the rules of chess. It does not, generally speaking, validate anything. It assumes the players are smart and honest enough to play by the rules. It also does not keep track of anything that isn’t a component of Forsyth-Edwards Notation(FEN). It is not connected to a database, it has no sense of state. Rather, it relies entirely on being passed FEN via HTTP-GET. It takes in FEN, allows the player to make a move, and generates new FEN based on the move made.
Let me back up a little bit, and say that as much as I love gaming, chess is almost certainly my favorite game. Correspondence chess systems online have all proven too heavy and complicated for my taste. I decided last night to implement an extremely simple system myself, a system that just simplified the process of getting the state of a chess board back and forth among two players. Play is simple — white clicks a piece to select it, clicks a space to move it to, reviews her move, and copies/pastes a link to the current board state to black. The link can be sent over email, IM, Twitter, whatever. Black does the same, and so on until the game is over. Because no state is ever saved on the server, there’s no overhead for an individual game. Thus, there’s no incentive (or, possibility even) for me to make games time out after so much inactivity, etc. It is, perhaps easiest to simply think of FENipulator as an interface to viewing and manipulating FEN data — hence the name.
Simplicity exists in many aspects of FENipulator. Aside from the aforementioned lack of a database, FENipulator also makes zero use of Javascript. There are no images, pieces are all represented by text. If one wanted, one could use images for pieces and spaces, as all of that is defined in CSS. Every space is a span, every piece is an :after pseudo-element attached to that span. For users who like their board flipped, a setting for this is possible using vendor-specific CSS transforms. Thus, flipping is not available on IE or older browsers, but for users of modern browsers, the possibility is there.
Update: Version 1.4 has all the short-term improvements taken care of except figuring out how I’m going to license the thing (see footnote). I got a bit carried away. Anyway, without going into the full changelog, here’s what has happened since v0.9: pawn promotion (to queen only); en passant (works on board and is recorded in FEN); POST is now used for sending move to/from data instead of GET, this meant switching the spaces from <a> to <button>; some classes added to CSS, making board-flipping easier and more things possible with board display (active state now exists after a move, showing to and from); board state URLs go through urlencode(), so everything validates now; and finally, no spaces are ‘live’ after a move has been made — the user must either choose to send the link or reset the board (the earlier behavior where the user could essentially change their move was unintentional and unpredictable). Anyway, read the footnote about licensing, then download it here, or just play.
As I have not yet determined how to license FENipulator, currently all rights are reserved. This will change soon, I promise. Also, know that while I have tested it, and it should not be able to cause any damage, I assume no liability or responsibility for its installation and/or use.