Click the image or follow the link to play: http://ugamarkj.co.nf/Monopoly/Monopoly.html
A while back I posted about a Monopoly game that I made in
Excel (link).
At the end of the post I said, “Maybe one of these days I'll try this again,
except using Tableau as the canvas. I'm pretty certain it could be done.”
I thought about the problem for a while and never came up
with a satisfactory solution for storing the data needed to track the game
history. After all, Tableau doesn’t let you write data to it’s data sources.
Well that isn’t exactly true. With the JavaScript API you could capture actions
occurring in Tableau and pass them off to a server side web programming
language like PHP that writes data to a database. If Tableau had a live
connection to that database, then you could make the Monopoly game work. That
is all pretty involved however so I thought it was too ambitious of a project
and shelved the idea for a while.
Then I saw Joshua Milligan pull off a few games in Tableau
like Star Trek,
Blackjack,
and Tic-Tac-Toe.
I was inspired again and started trying to think about how he stored the game
history. Some time later Nick Parry did a guest blog post on my site about
fuzzy matching with parameters.
He was building some really long string values into a parameter so I asked him
how many characters would fit in a single string parameter. To my surprise he
told me it fit around 34,000 characters. Then it hit me. I could store all the
game data in a parameter and use the JavaScript API to read from and write to
the parameter field. And with version 9 of Tableau I could take advantage of regular
expressions to help me parse the data structure to extract the values so I
could plot the data in Tableau. This could work!
I’ve built quite a few KPI data models in Excel that operate
off of just a handful of index fields and the rest of the fields populate based
on VLOOKUP (or similar) formulas. I knew I could apply the same concept for my
Monopoly game in Tableau. So my primary data source that I imported into
Tableau looks like this:
To store the game data in a parameter I needed to develop a
minimalistic JSON like structure. Below is an example of the data structure
that I settled on. This structure repeats for each turn/move in the game. The “p”,
“t” and “m” values correspond to the “player”, “turn” and “move” values in my
Excel file above. Using some string parsing functions I’m able to match the relevant
data in the parameter to the corresponding record in my Excel file. Then using
REGEX I’m able to parse the rest of the string to determine what player owns
each property and track transactions that are occurring between players and the
bank.
{p:1,t:1,m:1,d:[0,0],j:0,c:[],e:[0,1500,0,0,0,0,0,0,0],r:0,l:[1,1,-1,-1,-1,-1,-1,1,-1,-1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,-1,-1,1]}
p
|
player #
|
t
|
turn #
|
m
|
move #
|
d[]
|
dice array (die 1, die 2)
|
j
|
jail status (0=not in
jail, 1=one move left, 2=two moves left, 3=three moves left)
|
c[]
|
owned card array
|
e[]
|
move expense array
(bank,p1,p2,etc.)
|
r
|
roll total
|
l[]
|
land ownership status
array (-1=not owned, 0=mortgaged, 1=owned, 2=one building, etc.)
|
Originally I was more minimalistic with my JavaScript code
having it largely perform the functions of calculating random numbers for the
dice and appending the data model at the end of each move. I had to use a lot
of LOD calculations in Tableau to make it work, which ended up with a very long
spinner between moves. I pushed more of the work back into the JavaScript and
greatly reduced the render time.
Example JavaScript
code:
I have to offer a lot of thanks to Russell Christopher for
his work in demonstrating so much of the Tableau JS API. I’m not sure I
would have figured out how to do much of this just by reading the online
documentation. You can find Russell’s work here: http://russellchristopher.me/htdocs2/htdocs/index.html
In future posts I’ll go into more detail about how
everything works. At the time of this post the game is about 80% working. Monopoly
has a lot of nuanced conditional rules that I haven’t accounted for yet. Some
of my to-do’s include expanding the game beyond two players, calculating total
net worth, taking action based on the Community Chest and Chance cards and
making property changes. I also hope to add a save game feature at some point.
For now, have a go at it and let me know what you think. I hope this inspires
you to attempt crazy things with Tableau that you share with the community.