Prolog 3 - Effective Prolog

Generate and Test

Declarative and Procedural Thinking

Picking with select

Debugging with writeln

Use is to Evaluate Arithmetic

Avoid Infinite Searches

Pick a Good Data Representation

Know The Standard Library

Lab

???

Step 1: The Thirty-One Game

  1. Consider the following game:
    The Thirty-one Game. (Geoffrey Mott-Smith (1954)) From a deck of cards, take the Ace, 2, 3, 4, 5, and 6 of each suit. These 24 cards are laid out face up on a table. The players alternate turning over cards and the sum of the turned over cards is computed as play progresses. Each Ace counts as one. The player who first makes the sum go above 31 loses.

    Describe three different representation for the game state.

Step 2: Computing the State Value

  1. We will use the following representation of the game state: A list of six integers between 0 and 3, indicating the number of aces, twos, threes, etc. that have been turned over. At the beginning, the game state is [0,0,0,0,0,0]. After an ace and two threes are flipped over, the state is [1,0,2,0,0,0].

    We need to compute the value of a game state. If it is over 31, that state is losing.

    In Java, this would simply be

    for (int i = 0; i < state.length; i++) value += (i + 1) * state[i];

    But in Prolog, we don't have loops, so we need to have a recursive helper.

    value(L, N) :- value(L, 1, N).

    (You can overload a function name if it has different arity.) Implement the helper function:

    value([], _, 0).
    value([X|Xs], S, N) :- P is X * S, ..., ..., N is + P + ...

    What is your implementation?

  2. How do you compute the value of [1,0,2,0,0,0]?

Step 3: Computing Possible Flips

  1. When you flip a card, the number of turned card increases, but it can be at most 4. The legal flips are
    flip(0, 1).
    flip(1, 2).
    flip(2, 3).
    flip(3, 4).

    Now we want to express game state changes that involve legal flips, from [A X B] to [A Y B], where A and B are sublists and flip(X, Y) is true. Of course, that is sloppy notation which won't work in Prolog. How do you write that F is a list that starts with a list A, then has a single element X and is followed by a list B? (You need to use append.)

  2. Now implement flipmove(F, T), to indicate that it is possible to change the state F to the state T by flipping.
    flipmove(F, T) :- append(...), flip(X, Y), append(...).
  3. What are all possible moves from the state [0, 1, 2, 3, 0, 0]?

Step 4: Winning the Game

  1. As with the Nim game in the last lab, we want move(F, T) to indicate that it is legal to move from F to T, that is, the move is possible, and the resulting value is < 32. What is your definition of move(F, T)?
  2. What are all legal moves from the state [3, 2, 3, 3, 0, 0]?
  3. As before, we define
    win(X) :- move(X,Y), not(win(Y)).

    What happens when you run

    win([0,0,0,0,0,0]).

    You may have to wait a while for the answer.

  4. Ok, that is nice. But what move should you make? Write a predicate next(X, Y) indicating that it is legal to move from X to Y, and Y doesn't make the other player win. (It is really easy.)
  5. What is the next move you should make when you start with the initial position [0,0,0,0,0,0]?
  6. Play with your buddy. You get to use Prolog, and your buddy has to figure out moves by hand. That's not fair. You get to start. That's really not fair. Record how you trounce your buddy.