Age | Commit message (Collapse) | Author |
|
Loads of changes, some which I wasn't sure what I was on when doing
them
|
|
|
|
|
|
Card is a structure instead of just a type. Stronger type checking,
automatic constructor, destructors and existence check.
|
|
|
|
Instead of an association list and a type contract, let's use a hash
table and a structure. This is: more explicit, encapsulates state
more effectively, generates much of the cruft (constructors,
destructors) for me.
A hash table is more efficient when considering large player bases.
In particular, we'll be generating unique player IDs to make it a bit
more difficult for a malicious agent to guess another player's ID and
make bad requests.
|
|
|
|
Custom errors for malformed/nonexistent player IDs as well as a player
not having a high enough balance for the money requested.
This will allow me to encode more information in the errors, for
callers to use. I'm generally of the opinion that callers should be
checking error conditions before calling these functions, but per
Murphy's law it would be nice to have more information in the error
message.
|
|
This package defines a player data structure, collections of players,
and different interactions you can have with them:
- Extracting attributes (destructors)
- Checking if they're bankrupt or can bet
- Modifying a collection to adjust the balance of any one
player (including errors in case that isn't possible)
|
|
Currently can deal some hands and redeal some cards.
|
|
|
|
Gives a hand from a shuffled deck to the user, asks them to provide
indices for cards they wish to re-deal then does so.
|
|
Joker constructor takes a rank for uniqueness - rank doesn't really
change anything in terms of the "power" of a joker but helps with
ensuring jokers are unique in a deck.
Deck constructor takes an optional argument for the number of decks.
A deck includes two jokers, so n decks include 2n jokers.
|
|
I can now use this package for a console application since we can
pretty print cards.
|
|
|
|
Given n in 0..51, certainly there exists r, s s.t. `n = 13s + r`
where r in 0..12 and s in 0..3. `r` is the rank, and `s` is the suit.
ranks are ordered Ace, 2, 3, ..., Queen, King and suits are ordered
Diamond, Club, Heart, Spade.
Therefore there is a 1-1 correspondence between 0..51 and any card in
the deck.
Jokers are a bit less straightforward; for now I'll define them as an
outlier which doesn't exist in the same bounds (which is why they're
the default return for suit in int->suit). Likely I'll go for -1
representing a Joker.
|
|
Time to do the fun non-yakshaving part. I'll start out by writing
some custom types for the objects of concern: ranks, suits, cards and
sets of cards.
|
|
Instead of exporting cantedraw.lib.macro._ and making anyone who wants
to use the --> macro _require_ importing that specific symbol, let's
just make it so the user has to supply a placeholder name before they
do anything. This means each package provides its own placeholder
symbol which lowers coupling.
|
|
This is mostly a sanity check in-case anyone else decides to load this
system for use in their own package - don't want to conflict with
their names.
|
|
|
|
Why name it something unique when this is what I'm going to be making
at the end of it all? Just makes it more confusing for the end user.
|
|
|
|
|
|
Given an indicator function (A->B) and a list of items of A, return
an association list associating B to the elements that map to it;
essentially the inverse map of the indicator.
|
|
|
|
Given a list and index into that list, return a cons where the car is
all elements up to that index (exclusive) and the cdr is the rest of
the list.
|
|
Basically a wrapper over subseq but for when using `->>` as the list
is the last parameter.
|
|
The `$` operator takes a sequence of FORMS and returns a unary
function which applies the input through that sequence via the `->>`
operator.
For example, consider the predicate "not null". `null` is built into
Common Lisp but "not null" requires writing a
function (lambda (x) (not (null x))). Now, using this operator, you
can write ($ not null) which returns the same lambda as above while
being more concise.
|
|
Splitting macros and functions into different packages and source code
makes it easier to look at. Functions currently implemented:
- range: like Python's range
- parse-integer*: parse-integer but junk-allowed is set to t.
|
|
`fn' is a convenience macro for defining functions with a type
specifier. Only really matters for `sbcl` and other hard-optimising
Lisp interpreters which actually take these seriously.
|
|
|
|
|
|
Setup boilerplate for system/package management. In particular, setup
an entry-point and Shinmera's "deploy" to build executables.
Also write some scripts to easily load or build the project without
Emacs - just `sbcl --load <x>.lisp`.
|