Dominion Strategy Forum

Please login or register.

Login with username, password and session length
Pages: [1]

Author Topic: IGG again  (Read 3779 times)

0 Members and 1 Guest are viewing this topic.

DStu

  • Margrave
  • *****
  • Offline Offline
  • Posts: 2627
  • Respect: +1490
    • View Profile
IGG again
« on: April 10, 2012, 03:47:51 pm »
0

I kind of think we have discussed this before, but I can't find it:

So on the IGG-article on the blog there was something about Dominiate which led me play with the heuristics when to gain Coppers with IGG. Dominate said "never" which is clearly wrong. I thought it is "common knowledge" that in a IGG-rush, you gain a Copper if it helps you buy something "better". This would be this bot
Code: [Select]
{
  name: 'IGG'
  author: 'DStu'
  requires: ["Ill-Gotten Gains"]
  gainPriority: (state, my) -> [
    "Ill-Gotten Gains"
    "Province"
    "Duchy"
    "Estate" if state.gainsToEndGame() <= 2
    "Gold"
    "Silver"
  ]
 
  gainCopperPriority: (state, my) ->
    if my.ai.coinGainMargin(state) <= my.countInHand("Ill-Gotten Gains")
      [yes]
    else
      [no]

 #Performance
  actionPriority: (state, my) -> []
}
Now I compared with "always gain Copper", and this seems to beat the one above, as well as win more heavily against BM-Smithy
Code: [Select]
{
  name: 'IGG'
  author: 'DStu'
  requires: ["Ill-Gotten Gains"]
  gainPriority: (state, my) -> [
    "Ill-Gotten Gains"
    "Province"
    "Duchy"
    "Estate" if state.gainsToEndGame() <= 2
    "Gold"
    "Silver"
  ]
 
  gainCopperPriority: (state, my) -> [yes]
 #Performance
  actionPriority: (state, my) -> []
}

Anyone any ideas?
Logged

blueblimp

  • Margrave
  • *****
  • Offline Offline
  • Posts: 2849
  • Respect: +1559
    • View Profile
Re: IGG again
« Reply #1 on: April 10, 2012, 04:11:18 pm »
0

The copper-gaining logic in the "IGG" bot you've posted does not seem to work correctly. Example turn:
Code: [Select]

== IGG's turn 20 ==
IGG plays Silver.
IGG plays Ill-Gotten Gains.
IGG gains Copper.
IGG plays Copper.
IGG plays Ill-Gotten Gains.
IGG plays Ill-Gotten Gains.
Coins: 6, Potions: 0, Buys: 1
IGG buys Duchy.
IGG draws 5 cards: [Copper, Silver, Copper, Silver, Copper].

Clearly the bot should be gaining coppers from all three IGGs in order to buy a province. Also, since it's buying a Duchy, why is it gaining any copper at all?

By the way, if you're looking for some baseline bots to start with, try out the bots WW and I posted in the optimizing BMU+X thread: mine and his.
« Last Edit: April 10, 2012, 04:14:14 pm by blueblimp »
Logged

blueblimp

  • Margrave
  • *****
  • Offline Offline
  • Posts: 2849
  • Respect: +1559
    • View Profile
Re: IGG again
« Reply #2 on: April 10, 2012, 05:01:11 pm »
0

OK here is the reason this messes up. The nested hypotheticals confuse it.

Code: [Select]
The first time IGG is played, when gainCopperPriority is invoked:
  Coins is $3.
  A hypothetical state is created to determine the coin gain margin.

  In this hypothetical state, the first time IGG is played, in gainCopperPriority:
    Coins is $4.
    A hypothetical state is created to determine the coin gain margin.
    In this hypothetical state:
      A recursion-avoidance check changes the phase from treasure to buy.
      (This means we don't play the IGG we have in hand, in this hypothetical.)
      Therefore the amount of coins is $4.
    We want a Duchy, so the coin gain margin is $1. We have one IGG in hand, so
    we gain the copper.

  In this hypothetical state, the second time IGG is played, in gainCopperPriority:
    Coins is $6 (since we gained a copper with the previous IGG, played it, then
                 played this IGG).
    A hypothetical state is created to determine the coin gain margin.
    In this hypothetical state:
      A recursion-avoidance check changes the phase from treasure to buy.
      (This doesn't matter since we have no treasure remaining in hand.)
      Therefore the amount of coins is $5.
    So the coin gain margin is $3, since hypothetically we can afford a duchy and
    the next step up is province. We have no IGGs in hand, so we don't gain a copper.

  Therefore the coin gain margin will be $2, since we ended the hypothetical state
  with $6, and we would like to bump up our buy to province. We have 2 IGGs in hand,
  so therefore we decide to gain a copper.

The second time IGG is played, when gainCopperPriority is invoked:
  Coins is $5.
  A hypothetical state is created to determine the coin gain margin.

  In this hypothetical state, when IGG is played, in gainCopperPriority:
    Coins is $6.
    A hypothetical state is created to determine the coin gain margin.
    In this hypothetical state:
      A recursion-avoidance check changes the phase from treasure to buy.
      (This doesn't matter since we have no treasure remaining in hand.)
      Therefore the amount of coins is $6.
    We want a province, so the coin gain margin is $2. We have no IGGs in hand, so
    we do not gain a copper.

  Therefore the coin gain margin will be $2, since we ended the hypothetical state
  with $6, and we would like to bump up our buy to province. We have 1 IGG in hand,
  so therefore we decide to NOT gain a copper.

So that explains why it gains copper with the first IGG and not the second IGG.
Logged

blueblimp

  • Margrave
  • *****
  • Offline Offline
  • Posts: 2849
  • Respect: +1559
    • View Profile
Re: IGG again
« Reply #3 on: April 10, 2012, 05:06:59 pm »
0

Here is a fix to the bot. I just fixed the copper-gaining logic and didn't make any other modification.

In hypothetical states (i.e. state.depth > 0), it chooses to always gain coppers. This way, if you see the coin gain margin is $1, the copper from this IGG will be useful. Otherwise, it won't be.

(Another reasonable approach would be to never gain coppers in hypotheticals, then require the coin gain margin to be at most 1 more than the number of IGGs in hand. For this bot, the results should be identical. If you mix in other cards that use coinGainMargin in their play rules, such as Mining Village, then it would produce different behaviour.)

Code: [Select]
{
  name: 'IGG Fixed'
  author: 'DStu+blueblimp'
  requires: ["Ill-Gotten Gains"]
  gainPriority: (state, my) -> [
    "Ill-Gotten Gains"
    "Province"
    "Duchy"
    "Estate" if state.gainsToEndGame() <= 2
    "Gold"
    "Silver"
  ]
 
  gainCopperPriority: (state, my) ->
    if state.depth > 0
      [yes]
    else if my.ai.coinGainMargin(state) <= 1
      [yes]
    else
      [no]

 #Performance
  actionPriority: (state, my) -> []
}

With this modification, it performs similarly to the bot that always gains copper.
« Last Edit: April 10, 2012, 05:14:35 pm by blueblimp »
Logged

DStu

  • Margrave
  • *****
  • Offline Offline
  • Posts: 2627
  • Respect: +1490
    • View Profile
Re: IGG again
« Reply #4 on: April 11, 2012, 12:53:45 am »
0

Thanks. Probably there's also just a +1 missing
Code: [Select]
    if my.ai.coinGainMargin(state) <= my.countInHand("Ill-Gotten Gains")+1
Logged

blueblimp

  • Margrave
  • *****
  • Offline Offline
  • Posts: 2849
  • Respect: +1559
    • View Profile
Re: IGG again
« Reply #5 on: April 11, 2012, 12:58:31 am »
0

You'll still need to forbid gaining coppers in hypotheticals, or else I strongly suspect it will sometimes gain coppers when it shouldn't.
Logged

DStu

  • Margrave
  • *****
  • Offline Offline
  • Posts: 2627
  • Respect: +1490
    • View Profile
Re: IGG again
« Reply #6 on: April 11, 2012, 01:01:27 am »
0

You'll still need to forbid gaining coppers in hypotheticals, or else I strongly suspect it will sometimes gain coppers when it shouldn't.

The log looks quite good, including
Code: [Select]
IGG plays Copper.
IGG plays Copper.
IGG plays Ill-Gotten Gains.
IGG plays Ill-Gotten Gains.
IGG gains Copper.
IGG plays Copper.
Coins: 5, Potions: 0, Buys: 1
IGG buys Duchy.
Logged

blueblimp

  • Margrave
  • *****
  • Offline Offline
  • Posts: 2849
  • Respect: +1559
    • View Profile
Re: IGG again
« Reply #7 on: April 11, 2012, 01:37:34 am »
0

Quote
Testing shows the presence, not the absence of bugs.
-- Edsger W. Dijkstra

(That said, it might somehow work by coincidence. It's still wrong to have inconsistent copper-gaining behaviour inside a hypothetical.)
Logged

DStu

  • Margrave
  • *****
  • Offline Offline
  • Posts: 2627
  • Respect: +1490
    • View Profile
Re: IGG again
« Reply #8 on: April 11, 2012, 01:48:02 am »
0

True.

But if there's still a probelm, we should change it in coinGainMargin or pessimisticBuyPhase or wherever, because copperGainPriority is kind of "front-end", so I don't think it's a good idea to have the work arounds there.

OK, I see what you mean:
Code: [Select]
IGG plays Copper.
IGG plays Copper.
IGG plays Ill-Gotten Gains.
IGG gains Copper.
IGG plays Copper.
IGG plays Ill-Gotten Gains.
IGG plays Ill-Gotten Gains.
Coins: 6, Potions: 0, Buys: 1
IGG buys Duchy.
(IGG shuffles.)
« Last Edit: April 11, 2012, 01:55:53 am by DStu »
Logged

Geronimoo

  • Saboteur
  • *****
  • Offline Offline
  • Posts: 1059
  • Respect: +868
    • View Profile
    • Geronimoo's Dominion Simulator
Re: IGG again
« Reply #9 on: April 11, 2012, 04:26:52 am »
0

The way this is handled in my simulator:

-IGG has a default value of $2 (so the sim thinks it will give $2)
-when IGG is played it produces $1 and then the sim looks if adding the Copper will increase its buying power for that turn (so counting other IGG's in hand as $2)
-that's it...

https://github.com/Geronimoo/Geronimoo-s-Dominion-Simulator/blob/master/Geronimoo%27s%20Dominion%20Simulator/src/be/aga/dominionSimulator/cards/Ill_Gotten_GainsCard.java

Btw, this thread belongs in Simulation
Logged

DStu

  • Margrave
  • *****
  • Offline Offline
  • Posts: 2627
  • Respect: +1490
    • View Profile
Re: IGG again
« Reply #10 on: April 11, 2012, 04:46:44 am »
0

Btw, this thread belongs in Simulation

Yeah, I first thought the problem was real and not in the code.

edit:
Quote
The way this is handled in my simulator:

-IGG has a default value of $2 (so the sim thinks it will give $2)
-when IGG is played it produces $1 and then the sim looks if adding the Copper will increase its buying power for that turn (so counting other IGG's in hand as $2)
-that's it...
Not sure if that's possible in Dominiate this way, but hacking the card is probably the right way. Using blueblimps workaround in the definition of IGG directly
Code: [Select]
makeCard 'Ill-Gotten Gains', treasure, {
  cost: 5
  coins: 1
  playEffect: (state) ->
    ###added this
    if state.depth>0
      state.gainCard(state.current, c.Copper, 'hand')
   ###end
    else if state.current.ai.choose('gainCopper', state, [yes, no])
      state.gainCard(state.current, c.Copper, 'hand')
 
  gainEffect: (state) ->
    # For each player but the current: gain a curse.
    for i in [1...state.nPlayers]
      state.gainCard(state.players[i], c.Curse)
}
Now it always gains Coppers in hypothetical states, which is what we want here. Possibly we can also make this modificable by putting it into a
Code: [Select]
  if my.gainCopperDefault() ...

:e2
Now, are there more situations where we think the prevention of the recursion leads to wrong decisions? Or do we need default-Values for all decisions that might effect the current buy? Ironworks? Steward?
Is the prevention of the recursion really necessary? I think it is a bit counter-intuitive, especially as you possibly don't which functions act on hypothtical states and which not. So if I have a bot, I have to assume that every function I e.g. call for the actionPriority could potentially call an hyp-state, which means that the decision I want to make is made under the assumption that the result of either default-Values (if we would do this) or undefined (as it is now).
« Last Edit: April 11, 2012, 05:07:25 am by DStu »
Logged

blueblimp

  • Margrave
  • *****
  • Offline Offline
  • Posts: 2849
  • Respect: +1559
    • View Profile
Re: IGG again
« Reply #11 on: April 11, 2012, 12:53:57 pm »
0

The way this is handled in my simulator:

-IGG has a default value of $2 (so the sim thinks it will give $2)
-when IGG is played it produces $1 and then the sim looks if adding the Copper will increase its buying power for that turn (so counting other IGG's in hand as $2)
-that's it...

Yes, I looked at your behaviour out of curiosity and it's a lot cleaner and simpler. I think Dominate uses a more complicated system because of customizable play rules: for example, in a bot that never takes coppers, IGG should count as $1; in a bot that always takes coppers, IGG should count as $2; and in a bot where it depends on the state of the supply, it depends. Using hypotheticals means less coding for the bot writer, unless the value of IGG depends on a hypothetical situation involving other IGGs (as is the case here).

Is the prevention of the recursion really necessary?

Unfortunately it seems necessary. Otherwise, with k IGGs in hand, gainCopperPriority would be called (2^k-1) times, which would slow down the simulation by a lot.
Logged
Pages: [1]
 

Page created in 0.045 seconds with 20 queries.