Fluxx¶
Introduction:¶
Fluxx is a mildly popular card game. All things considered, it’s actually fairly contentious. It has a score of 5.7 on Board Game Geek, but it has a serious cult following. This is a python implementation of version 5.0 of the Vanilla Fluxx card game. The full rules are available here. The core idea is that the players can play cards which change the rules of the game. Each turn, each player draws a certain number of cards and plays a certain number of cards. There are four types of cards. There are Keepers, which are laid on the table in front of the player, Goals which determine how the game is won, New Rules which change the rules of the game, and finally Actions, which are played to the discard pile and perform the action printed on the card.
This particular implementation of the game was built from the ground-up, using no third-party libraries or assets. Card text has been abridged slightly, but retains all of the original’s gameplay meaning.
Fluxx is a registered trademark of Looney Labs – College Park, MD 20741-0763
The goal of this project is to create a playground for advanced AI
experiments with a complicated, not-analytically-solvable traditional
game. Looney Labs has developed a polished and well-made digital version
of Fluxx available
here.
Which is actually optimized for play by humans, and I suggest that
anyone who found this project with the intention of playing the game for
fun pay them the $0.99 and get the digital edition. That being said,
there is a human-interface portion to this project which can be played
by running engine.py
.
Installation and Use:¶
To play the game, all you need to do is run engine.py
. The
construction is fully portable and relies on no third party packages.
For actually interesting uses of this project, a user needs to do the following.
from fluxx.objects import Board
- Create an instance of
Board
, which I will callboard
. - Use
board.info
to get a dictionary which contains all of the player-knowable information about the game. board.info['options']
will show a list of the choices that the player has at the given stage of the game.- Run
board.action(option)
whereoption
is the index of the desired option inboard.info['options']
. - Repeat 4 and 5 until a winner becomes apparent. The
board.action()
will throw aBoard.Win
exception which contains the number of the player who won.
Objects¶
Author: Coen D. Needell Copyright: Looney Labs
This file contains all of the ‘meat and potatoes’ of the game. It contains all the objects that the game engine interacts with and does all of the computational work of the game. It’s a card game though, so that’s not too hard. The main purpose is for a Board object to act as a finite state machine which can be controlled using board.action().
-
class
objects.
Board
(num_players: int)¶ The Board object houses all of the information about the current game. Each card in the game has to be connected to a Board object.
-
exception
IllegalMove
(board, *args)¶ Thrown when the player tries to do something illegal.
-
exception
IllegalPlay
(board, *args)¶ Thrown when the player tries to play a card in an illegal way. Undoes the card_played effect.
-
exception
Win
(*args)¶ Thrown when the game is won.
-
action
(option)¶ The method which advances the game.
Parameters: option – int The index of the option (from board.options) which the player would like to perform. Returns: NoneType
-
active_player
¶ The player who currently must make a decision. When a limit is resolving, this is the player who must choose what to discard. Otherwise it’s the player whose turn it is.
Returns: int
-
card_set
¶ Gives a list of all the cards in the game.
Returns: list
-
cards_seen
¶ Gives a list of all the cards that the active player can see.
Returns: list
-
check_goal
()¶ Checks to see if the goal has been satisfied. If it has, then it throws a win.
Returns: NoneType
-
check_rules
()¶ Goes through the list of rules and runs their .rule() methods.
Returns: NoneType
-
check_starts
()¶ There’s a special class of rules whose rule is only executed at the start of a turn. This runs their .start() method. Those rules’ .rule() methods just run pass.
Returns: NoneType
-
curr_hand
¶ Gives the active player’s hand.
Returns: Hand
-
curr_keep
¶ Gives the active player’s keep.
Returns: Keep
-
draw_state
¶ The total draw rule.
Returns: int
-
inc_cards_played
()¶ Increases the count of cards played. If the count goes over the play_state, then the turn_state will roll-over to the next player.
Returns: NoneType
-
inc_player_state
()¶ Increases the turn_num, and calculates the current player state.
Returns: NoneType
-
info
¶ Gives a dictionary telling the player what they need to know.
Draws: How many draws are allowed. Plays: How many plays are allowed. Player: The active player. Keeps: A list of the Keeps in the game. Goals: The GoalSpace for the game. Rules: The RuleSpace for the game. Discard: The discard pile. Hand: The active player’s hand. Options: A list of the things that the active player is allowed to do. Actiontype: The current type of action that the active player must perform. Mystery: A description of the most recent MysteryPlay, if there was one. Remaining: The number of plays the active player has remaining. Drawn: The number of cards that hte active player has drawn. Returns: dict
-
options
¶ Gives a list of the actions that the active player can take. Depends greatly on the current action_type
Returns: list
-
play_state
¶ The total play rule.
Returns: int
-
exception
-
class
objects.
CardSpace
(kind, board)¶ The generic form of the RuleSpace, GoalSpace, and Keep.
May only hold `Card`s and acts like a MutableSet but with an attached Board.
-
add
(x: objects.Card) → None¶ Add an element.
-
discard
(x: objects.Card) → None¶ Remove an element. Do not raise an exception if absent.
-
-
class
objects.
Deck
(board)¶ -
classmethod
discard_creator
(board)¶ Alternate constructor, generates an empty Deck.
Parameters: board – Board Returns: Deck
-
draw
()¶ Takes the top Card off of the deck and returns it.
Returns: Card
-
insert
(index: int, value)¶ S.insert(index, value) – insert value before index
-
classmethod
-
class
objects.
GoalSpace
(board)¶ -
add
(x)¶ Runs some special code to ensure that the thing you’re adding is a Goal card. Also makes sure that there is only one (or two with Double Agenda) Goal in play. If Double Agenda is in play, then this initiates a special turn to remove one of those Goals.
Parameters: x – Card Returns: NoneType
-
discard
(x: objects.Card)¶ Remove an element. Do not raise an exception if absent.
-
remove
(x)¶ Remove an element. If not a member, raise a KeyError.
-
-
class
objects.
Hand
(player_num, board, _draw=True)¶ -
add
(x: objects.Card) → None¶ Add an element.
-
discard
(x: objects.Card) → None¶ Remove an element. Do not raise an exception if absent.
-
draw
(amount)¶ Draws amount Card`s from `board.deck.
Parameters: amount – int Returns: NoneType
-
classmethod
temphand
(size, board)¶ Alternate constructor. Sets _draw=False so that the Hand which is returned is of size size. Draws size cards and is connected to board.
Parameters: - size – int
- board – Board
Returns: Hand
-
-
class
objects.
Keep
(player_num, board)¶
Engine¶
Author: Coen D. Needell
Copyright: Looney Labs
Fluxx is a registered trademark of Looney Labs – College Park, MD 20741-0763
This file constitutes the ‘Engine’ of the game. In strict terms, the engine is actually split between the object.Board and here, but I’ve called this file engine.py for simplicity. This file contains the interface for the game. After trying a number of interfaces for python scripts, I chose to implement our engine with the standard python input-response loop. The point-of-interface between the engine and the game objects is intended to be minimal. This is because I intend the game to be machine-playable in the case of future development.
-
engine.
card_text_info
(card_name)¶ Returns the card text of the card specified by card_name.
-
engine.
get_card_text
()¶ Runs the ‘read card text’ environment.
-
engine.
interact
(entry)¶ This is the function that interacts with the board.action() method from objects.py.
-
engine.
play_game
()¶ The core environment for the game.
-
engine.
print_info
()¶ Gives the active player information about the game state.
-
engine.
start_screen
()¶ Shows the start screen, and sets up the game.
Assets¶
The point of defining the Assets folder as seperate from the objects folder is to make it easy to add new assets to the game, especially those which have their own behavior. You’ll notice I didn’t include CREEPERs in the game, because they are considered an auxiliary mechanic by most players. Every card-code in this file which has an underscore before it refers to a card which has special behavior within its class. This behavior is recorded in subclasses for their type. The foodlist is stored here, too.