Dominion Strategy Forum

Please login or register.

Login with username, password and session length
Pages: [1] 2 3 ... 13  All

Author Topic: Dominiate: a Dominion simulator that runs on the Web  (Read 63943 times)

0 Members and 1 Guest are viewing this topic.

rspeer

  • Witch
  • *****
  • Offline Offline
  • Posts: 469
  • Respect: +869
    • View Profile
Dominiate: a Dominion simulator that runs on the Web
« on: September 11, 2011, 03:55:09 am »
+13

Hey all. I've got a new Dominion simulator, and it's made of JavaScript so you can run it right now on the Web (unless your browser sucks)! Here it is: http://rspeer.github.com/dominiate/play.html

Now, this is nowhere near a substitute for Geronimoo's simulator at this point. For one thing, I've only implemented 37-ish Kingdom cards so far (although now that OMG IT WORKS, I can probably get to defining a lot more of them quickly.) It'd also be nice if it had more pre-defined strategies than the few that appear in the dropdown box.

But running on the Web will hopefully make simulation accessible to many more people. Some other interesting differences are:
  • AIs can set their own priorities not just for gaining cards, but also actions, trashing, discarding, and so on. Every decision an AI is asked to make can actually be decided by the AI, except for really lame ones like which cards to clean up in which order. Or the decision can be left to the BasicAI, where I hope I've put some reasonable play rules.
  • There's a "play until one player dominates" button. It pits two AIs against each other repeatedly until it's 99.7% sure which AI is better. This could take 10 iterations, or it could take 10,000, or it might never stop if the AIs are functionally identical.
  • Strategies are designed in a concise form based on CoffeeScript. I don't think you'll need any prior familiarity with CoffeeScript -- you have a bunch of lines that look like this: "Colony" if state.current.countInDeck("Platinum") > 0
Notable deficiencies:
  • It probably has some terrible/hilarious bugs in it. Sometime around last week I found that the Witch was giving other players Witches instead of Curses, for example. I wonder what I haven't caught yet.
  • The Web page only has an interface for 2-player games, even though the command line supports more.
  • It doesn't yet do smart things like avoiding suicidal buys, or buying out piles when it's ahead.
  • It's unfortunately incompatible with Geronimoo's XML strategies. I code this for fun, and XML is the opposite of fun, but I totally wouldn't mind if someone could help make a translator.

This project is open source, and I really would appreciate help finishing it, because Dominion is a game with a lot of parts to it. Heck, I made all the JavaScript and CSS and stuff work, so implementing more cards and strategies is the fun part. Places to start with that include:
Logged

Davio

  • 2012 Dutch Champion
  • *
  • Offline Offline
  • Posts: 4733
  • Respect: +3315
    • View Profile
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #1 on: September 11, 2011, 07:48:01 am »
0

Nice work and good documentation.

I was looking through the card definitions and saw you've forgotten about Princess for the "real" cost calculation:

Code: [Select]
getCost: (state) ->
    coins = this.costInCoins(state)
    coins -= state.bridges

// Some of my pseudocode here
if state.princesses > 0 then coins -= 2
// Don't know if it counts TR'd or KC'd cards as multiple played "copies"
// End pseudocode

    if this.isAction
      coins -= state.quarries * 2
    if coins < 0
      coins = 0
    return [coins, this.costInPotions(state)]
Logged

BSG: Cagprezimal Adama
Mage Knight: Arythea

Geronimoo

  • Saboteur
  • *****
  • Offline Offline
  • Posts: 1038
  • Respect: +805
    • View Profile
    • Geronimoo's Dominion Simulator
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #2 on: September 11, 2011, 09:15:43 am »
0

OOOhh jealous of your documentation. No way you're a professional IT, they don't make docs  ;)

So do the bots learn to play better while they're playing?
Logged

rspeer

  • Witch
  • *****
  • Offline Offline
  • Posts: 469
  • Respect: +869
    • View Profile
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #3 on: September 11, 2011, 12:31:42 pm »
+1

Nice work and good documentation.

I was looking through the card definitions and saw you've forgotten about Princess for the "real" cost calculation:

Code: [Select]
getCost: (state) ->
    coins = this.costInCoins(state)
    coins -= state.bridges

// Some of my pseudocode here
if state.princesses > 0 then coins -= 2
// Don't know if it counts TR'd or KC'd cards as multiple played "copies"
// End pseudocode

    if this.isAction
      coins -= state.quarries * 2
    if coins < 0
      coins = 0
    return [coins, this.costInPotions(state)]

A bit confusing, I admit. This isn't counting copies of the card (that would be state.current.countInPlay('Bridge'), and it would fail on Throne Rooms and King's Courts).

Instead, there is a value in the state that applies a discount to every card cost, and I call it "bridges". The effect of playing a bridge is to increase the "bridges" value by 1, and the effect of playing a Princess (not that you can get a Princess at the moment...) is to increase it by 2.
Logged

rspeer

  • Witch
  • *****
  • Offline Offline
  • Posts: 469
  • Respect: +869
    • View Profile
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #4 on: September 11, 2011, 12:35:05 pm »
0

OOOhh jealous of your documentation. No way you're a professional IT, they don't make docs  ;)

So do the bots learn to play better while they're playing?

Not at the moment.

I have two things I want to try with that. One is to define strategies with parameters, and then the bots can learn which parameters win the most.

The other approach is Golem,  a separate project I've got which uses machine learning over all the games in dominionstats to learn which cards are good to buy when. It's definitely a goal I have to hook this up to Golem. But it'll require calls to a separate server, the interface code will be pretty messy, and it'll slow the simulation way down.
Logged

Davio

  • 2012 Dutch Champion
  • *
  • Offline Offline
  • Posts: 4733
  • Respect: +3315
    • View Profile
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #5 on: September 11, 2011, 01:04:04 pm »
0

IT professional here and yeah, making documentation is the equivalent of cleaning the coal containers on an ocean liner, one of the "less" fun tasks.

However, often there are moments you'd wish you've written some documentation, I have seen some forgotten software projects come back to life, because of a sudden interest from a client.


I like the clean CoffeeCode, haven't used it myself and how you deal with the governing 'state'. When I dabbled in Dominion simulation, I've often wondered where I should put stuff like Bridge's special action.
Logged

BSG: Cagprezimal Adama
Mage Knight: Arythea

rspeer

  • Witch
  • *****
  • Offline Offline
  • Posts: 469
  • Respect: +869
    • View Profile
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #6 on: September 11, 2011, 03:51:52 pm »
+1

HOLY HELL, IT RUNS ON MY PHONE.

Is it the future now? Because my phone just played a thousand or so games of Dominion against itself. (In the process it got rather warm and used about 8% of the battery. And the strategy editors were of course quite unusable.)
Logged

Tydude

  • Baron
  • ****
  • Offline Offline
  • Posts: 54
  • Respect: +5
    • View Profile
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #7 on: September 11, 2011, 04:16:18 pm »
0

Is it just my code, or does it not work if you don't include Colony and Platinum? For example, I just set up a simple code for Big Money+Smithy.
Code: [Select]
{
  name: 'BigMoneyU'
  gainPriority: (state) -> [
    "Colony" if state.current.countInDeck("Platinum") > 0
    "Province" if state.countInSupply("Colony") <= 6 \
               or state.countInSupply("Province") <= 6
   
    "Duchy" if 0 < state.gainsToEndGame() <= 5
    "Estate" if 0 < state.gainsToEndGame() <= 2
    "Platinum"
    "Gold"
    "Smithy" if state.current.countInDeck("Smithy")<1
    "Silver"
    "Copper" if state.gainsToEndGame() <= 3
  ]
}

Right? If I run it with Colonies, it works as expected (buys a single Smithy and then BM from there on out). With no Colonies, it seems to completely skip buying the Smithy.
Logged

rspeer

  • Witch
  • *****
  • Offline Offline
  • Posts: 469
  • Respect: +869
    • View Profile
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #8 on: September 11, 2011, 05:19:59 pm »
0

Is it just my code, or does it not work if you don't include Colony and Platinum? For example, I just set up a simple code for Big Money+Smithy.
Code: [Select]
{
  name: 'BigMoneyU'
  gainPriority: (state) -> [
    "Colony" if state.current.countInDeck("Platinum") > 0
    "Province" if state.countInSupply("Colony") <= 6 \
               or state.countInSupply("Province") <= 6
   
    "Duchy" if 0 < state.gainsToEndGame() <= 5
    "Estate" if 0 < state.gainsToEndGame() <= 2
    "Platinum"
    "Gold"
    "Smithy" if state.current.countInDeck("Smithy")<1
    "Silver"
    "Copper" if state.gainsToEndGame() <= 3
  ]
}

Right? If I run it with Colonies, it works as expected (buys a single Smithy and then BM from there on out). With no Colonies, it seems to completely skip buying the Smithy.

Oh man. The supply was pretty messed up if that box was unchecked. Thanks for finding the bug, and I've fixed it now.

Incidentally, I added the rule to buy a second Smithy once there are 16 cards in the deck, and put it up as a selectable strategy called "BigSmithy".
Logged

Matt_Arnold

  • Spy
  • ****
  • Offline Offline
  • Posts: 88
  • Designed the DS masthead & councilroom.com art.
  • Respect: +37
    • View Profile
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #9 on: September 11, 2011, 05:43:05 pm »
0

Awesome. Fantastic. I have forked and will submit my proposed file change soon.
Logged

Matt_Arnold

  • Spy
  • ****
  • Offline Offline
  • Posts: 88
  • Designed the DS masthead & councilroom.com art.
  • Respect: +37
    • View Profile
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #10 on: September 11, 2011, 05:52:27 pm »
0

So let me make sure I understand this. I decided to experiment with how I could code Monument in cards.coffee. There's a difference between being VP and accumulating VP tokens, but I'm not sure I see these represented differently in your code. Perhaps your intent is that at the end of the game, each Victory card will be "played" once, thereby activating their "vp" property and accumulating tokens? Therefore, Monument would just use the property "vp: 1". Is this a correct assumption?
Logged

Matt_Arnold

  • Spy
  • ****
  • Offline Offline
  • Posts: 88
  • Designed the DS masthead & councilroom.com art.
  • Respect: +37
    • View Profile
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #11 on: September 11, 2011, 05:55:54 pm »
0

Never mind; I found state.current.chips += 1
Logged

Geronimoo

  • Saboteur
  • *****
  • Offline Offline
  • Posts: 1038
  • Respect: +805
    • View Profile
    • Geronimoo's Dominion Simulator
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #12 on: September 12, 2011, 04:48:33 am »
0

Nice how you have 5 lines of code where I need 5 pages in some cases :)

I haven't read the docs in detail, but are you using the buy rules in deciding how to play certain cards (like Chapel, Remodel,...) ? I found that this improved the decisions a lot in my sim.
Logged

Davio

  • 2012 Dutch Champion
  • *
  • Offline Offline
  • Posts: 4733
  • Respect: +3315
    • View Profile
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #13 on: September 12, 2011, 05:14:43 am »
0

Is there an easy checklist for the cards you have done/need to be done?
Looking through the source it can be a bit difficult to spot which ones you still need.

I've been thinking about Trade Route, adding "tradeRouteValue" to state seems enough to me, no need to do something with a mat.
This value should be increased whenever a VP card is bought.
Calculating the TR value by counting if the full amount of VP cards is left in a certain pile is incorrect due to Ambassador.

I don't think it's necessary to explicitly not use this value if Trade Route is not in the supply, we can still update the value as an O(1) operation, but just do nothing with it, but if it can be easily programmed, of course it should be done.

I wanted to create a trunk and try some things myself, but somehow my adjustment (Adding Trade Route Value to the state) ended up in the main branch. Please retract if you find this erroneous.

I will refrain from proceeding with the tricky part.

The tricky part is where to maintain if the token was already moved to the "TR Mat".

We could:
- Create some extra TR pool with the names of the VP cards that have been gained at least once from the Supply. If a card on the "gain" (or "buy") action wants to add himself to this pool (and increase the TR value), it only succeeds if it's not yet in there.
- Create explicit booleans for each card to maintain which has added to the TR value (not what we want).
« Last Edit: September 12, 2011, 05:57:12 am by Davio »
Logged

BSG: Cagprezimal Adama
Mage Knight: Arythea

Buggz

  • Spy
  • ****
  • Offline Offline
  • Posts: 88
  • Respect: +12
    • View Profile
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #14 on: September 12, 2011, 05:56:11 am »
0

This value should be increased whenever a VP card is bought.
..that hasn't been bought before. You'll need to specifically keep track of which VP cards have been used to increase TRs value.

EDIT: A Trade Route object containing current value and an array of the cards used should suffice, but I haven't had the chance to look at the code yet and how things are implemented.
Logged

Davio

  • 2012 Dutch Champion
  • *
  • Offline Offline
  • Posts: 4733
  • Respect: +3315
    • View Profile
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #15 on: September 12, 2011, 05:57:46 am »
0

This value should be increased whenever a VP card is bought.
..that hasn't been bought before. You'll need to specifically keep track of which VP cards have been used to increase TRs value.
Yes, I discovered this too, see my edit in my previous post.
Logged

BSG: Cagprezimal Adama
Mage Knight: Arythea

Thisisnotasmile

  • Saboteur
  • *****
  • Offline Offline
  • Posts: 1493
  • Respect: +664
    • View Profile
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #16 on: September 12, 2011, 06:11:19 am »
0

I'm not a programmer so if this is not possible, ignore me. Idea:

When Trade Route is in play, use a (mathematical) set that starts as the empty set S = {}. Whenever a Victory card is gained, a copy of it gets moved into this set (e.g. S = {Province, Estate}). Since one of the properties of sets is that all members are unique, adding duplicate cards to the set will not change the value of the set (e.g. S = {Province, Estate, Province} = {Province, Estate}). Then, whenever someone uses a Trade Route, all you need to do is measure the cardinality of set S to find the value of Trade Route.
Logged

Davio

  • 2012 Dutch Champion
  • *
  • Offline Offline
  • Posts: 4733
  • Respect: +3315
    • View Profile
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #17 on: September 12, 2011, 06:13:35 am »
0

Hmm,I doubt whether a "loose" language like JavaScript has such a mathematical set.

It can be easily simulated though.
Logged

BSG: Cagprezimal Adama
Mage Knight: Arythea

Geronimoo

  • Saboteur
  • *****
  • Offline Offline
  • Posts: 1038
  • Respect: +805
    • View Profile
    • Geronimoo's Dominion Simulator
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #18 on: September 12, 2011, 06:16:03 am »
0

Thank you thisisnotasmile, I updated my Trade Route code (which used a List instead of a Set)
Logged

Thisisnotasmile

  • Saboteur
  • *****
  • Offline Offline
  • Posts: 1493
  • Respect: +664
    • View Profile
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #19 on: September 12, 2011, 06:16:54 am »
+1

Finally my three years at university studying maths has paid off!
Logged

Buggz

  • Spy
  • ****
  • Offline Offline
  • Posts: 88
  • Respect: +12
    • View Profile
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #20 on: September 12, 2011, 06:40:28 am »
0

Pseudocode ahoy:
Code: [Select]
var coinValue = TradeRouteArrayOfBoughtCards.length;

if(!$.inArray(VPCardJustBought, ArrayOfBoughtVPCards)) {
    ArrayOfBoughtVPCards.push(VPCardJustBought);
}
Only would only need to store the name, not the whole card object. Discard if already in the array. If one wants to be more gentle with the processor one could initialize it with every VP card and then remove them instead, thus you won't need the extra check. Then one could just return false or coin value or whatever needed directly if the array is empty (I doubt it would have a noticeable effect though).

But I shouldn't get into too much detail without having a clue on how the code looks and works.

EDIT: Just got another idea, one could just bind another function on a buy event (or whatever applicable) of a VP card, and then remove that bind after the first purchase.
Logged

Sopenas

  • Herbalist
  • **
  • Offline Offline
  • Posts: 6
  • Respect: +2
    • View Profile
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #21 on: September 12, 2011, 07:33:58 am »
0

Hello,

  Amazing work! Keep it going :)

  I found one problem with trashing. I was experimenting with fishing villages, and noticed bot wants to leave at least 3 coppers before trashing them. And when counting coppers it does not include fishing willage's +1 coin. So it leads to situations, where it thashes less than it should to. I copy/pasted one example. Here bot has already bought fishing village, so it needs two coppers to keep buying power, but it keeps three of them. I guess trashing algorithm is hard coded, but maybe i am wrong? Here is log:

== BankWharf's turn 1 ==
BankWharf plays Copper.
BankWharf plays Copper.
BankWharf plays Copper.
Coins: 3, Potions: 0, Buys: 1
BankWharf buys Chapel.
BankWharf draws 5 cards (Copper,Estate,Copper,Copper,Copper).

== BankWharf's turn 2 ==
BankWharf plays Copper.
BankWharf plays Copper.
BankWharf plays Copper.
BankWharf plays Copper.
Coins: 4, Potions: 0, Buys: 1
BankWharf buys Fishing Village.
(BankWharf shuffles.)
BankWharf draws 5 cards (Estate,Copper,Copper,Chapel,Fishing Village).

== BankWharf's turn 3 ==
BankWharf plays Fishing Village.
BankWharf plays Chapel.
BankWharf trashes Estate.
BankWharf trashes Copper.
BankWharf trashes Copper.
Coins: 1, Potions: 0, Buys: 1
BankWharf draws 5 cards (Copper,Copper,Copper,Estate,Copper).

== BankWharf's turn 4 ==
BankWharf resolves the duration effect of Fishing Village.
BankWharf plays Copper.
BankWharf plays Copper.
BankWharf plays Copper.
BankWharf plays Copper.
Coins: 5, Potions: 0, Buys: 1
BankWharf buys Wharf.
(BankWharf shuffles.)
BankWharf draws 5 cards (Estate,Copper,Chapel,Copper,Copper).


== BankWharf's turn 5 ==
BankWharf plays Chapel.
BankWharf trashes Estate.
BankWharf trashes Copper.
BankWharf trashes Copper.
BankWharf plays Copper. - should trash it too, because bot still is capable of buying silver with 2 coppers ant fishing village
Coins: 1, Potions: 0, Buys: 1
BankWharf draws 5 cards (Estate,Copper,Wharf,Fishing Village,Copper).

Good luck :)
Logged

Davio

  • 2012 Dutch Champion
  • *
  • Offline Offline
  • Posts: 4733
  • Respect: +3315
    • View Profile
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #22 on: September 12, 2011, 07:49:39 am »
0

I have made some modifications to the sources for Trade Route.

I kept it simple:
- Added a Trade Route "Mat" (array) and Value (int) to the State.
- Whenever a card is gained, it fires and checks to see if TR is in play, the card is a VP card and already on the list and adds the card and sets a new Trade Route Value if the card is not yet on the list

I even sent a Pull Request I believe.

I am new to GitHub, so bear with me.


I wanted to add the event to the VP cards instead of the main gainCard() method, but I could only find an overridable Buy method and not Gain.
I think a Gain method may be needed not only for this, but other cards as well, but my understanding of the source is still very little, so maybe you can do the rest of the work.

Logged

BSG: Cagprezimal Adama
Mage Knight: Arythea

rrenaud

  • Administrator
  • *****
  • Offline Offline
  • Posts: 987
  • Uncivilized Barbarian of Statistics
  • Respect: +1177
    • View Profile
    • CouncilRoom
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #23 on: September 12, 2011, 09:31:12 am »
0

Nice.

How hard would it be to make a councilroom feature where you can start from a given turn from an already played game and simulate from strategies from there?  We could make the simplifying assumption that both decks start shuffled.
Logged

rspeer

  • Witch
  • *****
  • Offline Offline
  • Posts: 469
  • Respect: +869
    • View Profile
Re: Dominiate: a Dominion simulator that runs on the Web
« Reply #24 on: September 12, 2011, 11:45:54 am »
0

Nice how you have 5 lines of code where I need 5 pages in some cases :)

I haven't read the docs in detail, but are you using the buy rules in deciding how to play certain cards (like Chapel, Remodel,...) ? I found that this improved the decisions a lot in my sim.

Chapel follows the trashPriority / trashValue rules. trashPriority is an ordered list of what to trash with possible conditions, like the buy rules. Everything that can be defined as a priority list can also be defined as a function returning a value for each choice, but I haven't used this much because priority lists are easier.

I haven't done Remodel and Expand yet, but it seems to me like they may require a separate decision (to know about things like remodeling gold into province). I suppose this could be deduced if the strategy defines both a gainValue and a trashValue, because you could take the difference, but that will almost never be the case.
Logged
Pages: [1] 2 3 ... 13  All
 

Page created in 0.104 seconds with 20 queries.