Ludii Forum
Unexpected choice - Printable Version

+- Ludii Forum (https://ludii.games/forums)
+-- Forum: Problems (https://ludii.games/forums/forumdisplay.php?fid=5)
+--- Forum: Ludii Player Problems (https://ludii.games/forums/forumdisplay.php?fid=6)
+--- Thread: Unexpected choice (/showthread.php?tid=353)

Pages: 1 2


Unexpected choice - dale walton - 01-01-2021

The attached code which I am debugging offered an unexpected choice - The move has two branches that depend on the type of piece being removed. since only one type of piece is being removed there is no choice to make.

The value for <Multi:capture> in the Occupied by: option was: NonMover which seems to be working as both the white and black hexes were offered for capture.
The problem is that after clicking the red dot next to the white disc, a popup appeared offering a choice between replacing the hex location with a disc or with a hex - but the logic is that the choice depends on what was in the jumped location.... Either choice was allowed by the popup the replacement with disc / hex was made accordingly, but the game logic is meant to specify hexes only replace discs / discs only replace hexes, while simultaneously, ownership changes to the mover.

------------------------------
FWIW, I previously had all the actions in the apply section without using a pending to keep the (between) location, but that was causing the program to make a lot more errors ( - and trying to solve it with a (then (add...)) inside the applied moves caused the program to hang as well.) - You might look at whether those approaches reveal more about the bug, and/or whether the compiler needs to guard against such things...

Edit: I also got this choice coming up in another version in which
(then
    (and
    (remember Value (value Pending))
    (if (is In (value Pending) (sites Occupied by:Player component:"Disc"))
      (and
      {
        (remove (value Pending))
        (add (piece (id "Hex" mover)) (to (value Pending)))
        (addScore Mover 10)
      }
      )
      (and
      {
        (remove (value Pending))
        (add (piece (id "Disc" mover)) (to (value Pending)))
        (addScore Mover -10)
      }
  )))))
In this case both boxes read the same except for having or missing the - before the 10: i.e.
[P1+=-10, Pending=6, D2-B2][Or([Lgame.rules.play.moves.Moves;@74ad62d6),Or([Lgame.rules.play.moves.Moves;@39e48495)]

Note that there is no end square bracket after the @#####.

A separate bug issue: Using "Player" in the Occupied by: test above always activates one branch of this code regardless of whether -10 or +10 is chosen,
Using "Each" activates the other branch. but leaving the "by:" clause out -which is what I wanted to do, causes a garbage compiler error, even though the "by:" clause is optional in the documentation. What works for the logic seems to be to use Occupied by:All.
But the selection popup still appears.

Possibly related: I separately noticed that (and (...) (...) (then)) does the contents of (then) twice.

I think I understand the the problem in the quoted code: component takes "name of component" so this must match to the by: role?  - but that still doesn't explain why it "half" works. And it would be a nuisance if one needs a "forEach Player" ... somewhere in here...

-------------------
Further update. I managed to workaround this by totally separating the two cases, thus avoiding the condition. --- But then it popped up again when I tried to extend the logic to NonMover - So it does seem I do need to implement the move forEach player since I am writing for optional numbers of players... -- Even though sites Occupied by:<roleType> shows any role is allowed - can this be fixed? So that (sites Occupied by:NonMover component:"Disc") and  (sites Occupied component:"Disc") work as they should and one doesn't need to provide an unknown and hard to generate list like {"Disc0" "Disc2" "Disc3"} etc.


RE: Unexpected choice - Michael - 01-02-2021

The by-parameter is not optional..


RE: Unexpected choice - dale walton - 01-03-2021

(01-02-2021, 07:54 PM)Michael Wrote: The by-parameter is not optional..
You are right. I misread the documentation. but most of my tries have been based on including the by: parameter.

I am working on another workaround, and decided to set piece values to make the code more general, but this threw up the following compiler objection:

Unexpected syntax '(piece "Disc" Each va'
Unexpected syntax '(piece "Disc" P1 valu'
Unexpected syntax '(piece "Disc" value:10)'

As I tried different approaches.

What is wrong with that? and are the values associated to every piece of that type?
I want to use the values in (addScore (who at:(...)) (value Piece of:(what at:(...))) when doing replacements


RE: Unexpected choice - Eric Piette - 01-04-2021

Hi,

I am a bit lost with your long message here and the different updates you did.
Can you shortly explaining to me what you mean and the reasons why, with examples if possible?

Regards,
Eric


RE: Unexpected choice - dale walton - 01-05-2021

There are 2 separate bugs discussed:
1
The in text code in the first email was from a consequence of a hop, in which the between value was saved to pending.
The consequence begins with an (if... condition that has two branches, each with an (and ... enclosing 3 parallel consequences.
One branch adds to the score, the other subtracts.

The player appears to be matching both branches as if it considers the If condition both true and false. I say this because it gives me a popup choice when I click a single jump destination of a score increase, or a score decrease move.

Then, depending on other factors, such as whether I used "Player", "Each" or "All" in the Occupied by: ... or whether I had split the conditions at the move level instead of the consequence level ... the choice was executed according to what I selected during the trial, or according to what I had coded.

-- but in any case, I shouldn't see the popup choice: the logic shouldn't be both true and false at the same time.

If so it would mean it is a runtime error, and should stop gracefully. - or the compiler should tell me that the syntax is wrong eg. not every role can be used with Occupied by: in conjunction with a component, if that is the problem.

====================================================
2) Separate problem:
I tried to use set the value of a piece in the equipment section, and got the Unexpected Syntax errors shown in message #3 - they are examples based on different things I tried that seemed to be according to the documentation. I tried:
(piece "Disc" Each value:10)
(piece "Disc" P1 value:10)
(piece "Disc" value:10)

None of them worked. I was trying to use this value for (addScore Mover (value Piece of:(what at:(value Pending)))) to modify the score during a jump without testing directly for what piece it was, in order to generalize the code.

The documentation states value can be set in the equipment section for a variety of purposes, but does not tell what purposes or limitations on its use. This seemed like an obvious purpose to me.

In the end I gave up and used a define instead. What could have beenwrong wrong with the syntax?


RE: Unexpected choice - Eric Piette - 01-05-2021

Hi,

Still a bit hard to answer to you. But I can say something for sure, that's impossible for a BooleanFunction to return true and false in the same time. So if you saw a popup with 2 possible moves that's because 2 different conditions were true in your description at that moment.

For the RoleType related question, some roletypes can return nothing yes in some ludemes, depends of their uses and if they have sense for the ludeme. For example Each is working only for the components in the equipment and only for that. I saw in other thread you are talking about NonMover not working as expected, that's simply because that RoleType is not implemented for some cases. I did not make the NonMover RoleType, so I would not advise to use it and I can not help with it.

As a general answer you can use all the P1 to Pn (and Team1 to Teamn) with n the number of players, Prev, Mover, Next, All, Neutral, Shared safely.
The RoleType Each is only workable for the equipment and that's what we want for it.
The RoleType Player is only workable in case of a (forEach ...) iterating the players.

For the 2 last ones: Enemy and NonMover, I did not make them, so they are probably not fully implemented and can be removed/modified in the future. So for the moment, please do not use them.

I will add a short explanation on the Ludii Logic Guide for that.

For the compiler warnings, I told you in another thread, the warning will be more precise in the future, we have an idea to return the exact first argument on the expanded version which is not compiling. But that's not something on what we are working for the moment, so do not expect that soon.


----

For the other question about the value. That has changed some versions ago. The value has now to be defined in the place ludeme and not in the equipment (like for the state of a piece for example). The values of the pieces are now dynamic and not static. If you saw an example with that in the last LLR or Ludii Logic guide version please tell me where to remove it.

Regards,
Eric


RE: Unexpected choice - dale walton - 01-06-2021

OK for value, looks like I was using old documentation.

In another project I want to store value at each site to use in calculating what moves are possible. They would need updating at each (then..
Is this possible? my first attempt hung with the board displayed, but not the pieces.


RE: Unexpected choice - Eric Piette - 01-06-2021

Not sure what you mean.

You want to put a value in any site even if no piece?

Regards,
Eric


RE: Unexpected choice - dale walton - 01-07-2021

Yes, to keep track of whether a piece might be able to move there over the course of a series of subsequential movements and then selecting move to sites from among them at the end, rather than by selecting them as a series of independent decisions.

It would make the game play easier for both the humans and the AI to be able to move by turn rather than by specifying an exact path of steps.

Otherwise I would need an array or dynamic mapping to store the info. i.e. to store a dynamic list of sites and values associated to them. But from your response it looks like I need to think of another method. - Or for now stick with sequential "hops".

I noticed on some multi-step moves that the AI uses N seconds per move, making play slow, but a game player in a real life game not on Ludii normally gets time per turn. Also the look-ahead must be degraded when possible turn outcomes are not consolidated to a set to choose from before selection, especially if there are a lot of overlapping possibilities, as they artificially expand the branching factor.

Edit: OK, Maybe I can (move Select the starting position of the move, then use hidden neutral pieces as place markers (like your show moves spots) and then (move Select one of them and remove them all as a separate move to complete the turn.


RE: Unexpected choice - dale walton - 01-10-2021

I tried the principle of selecting a site in one move, laying down shared pieces and choosing one of them in a separate turn with a move from saved start selection to selected shared piece, and removing all shared pieces.

A main problem is the following move doesn't compile:

(move
  Select
  (from
  (sites Occupied by:Mover)
   if:(ge 7 ("InfluenceAt"(from)))
  )
  (then (set State at:(last To) (- 7 ("InfluenceAt" (last To)))))
))


(define "InfluenceAt"

  (-
    (+ 7 (count Pieces Next in:(sites Around (#1) includeSelf:true)))
    (count Pieces Mover in:(sites Around (#1) includeSelf:true))
  )
)

Other moves with "InfluenceAT" compile.

The documentation shows (move Select ...) as a decision move, and I have a consequence to the selection, by setting a state (and that state will be different to the base state 0 from before the move)

So why doesn't it compile?
Note: I also tried "last From", and I also tried including a (pass) consequential move linked to the (set ...) with an (and ...) or as a chained consequence, in case an effect consequence is not sufficient for a Select move (eg because no change to board state?)  But that did not solve the problem either.