The Game of Reverse in F-Script

by Philippe Mougin
April 2006

Read all the articles in this series
  1. Scripting Cocoa with F-Script
  2. Exploring Cocoa with F-Script
  3. Embedding F-Script into Cocoa Applications
  4. The game of Reverse in F-Script

Paul Bissex writes about how the game of Reverse can be implemented in various languages.

The game of Reverse requires you to arrange a list of numbers in numerical order from left to right. To move, you tell the computer how many numbers (counting from the left) to reverse. For example, if the current list is 2 3 4 5 1 6 7 8 9 and you reverse 4, the result will be 5 4 3 2 1 6 7 8 9. Now if you reverse 5, you win.

Here is a version in F-Script:

numbers := (9 random: 9) + 1.
steps := -1.

flip := [:flipCount| 
    numbers at: flipCount iota put: (numbers at:flipCount iota) reverse.
    steps := steps + 1.
    (numbers isEqual: 9 iota + 1) ifTrue:['Done! That took you ' ++ steps printString ++ ' steps.']
                                  ifFalse:[numbers]].

flip value:0.

Upon execution of this program, F-Script displays the initial list of numbers. In the spirit of F-Script, we interact with the game using F-Script itself. We play by evaluating the flip block, passing it the number of elements to reverse. For example, here is the end of a game:

...
{3, 1, 2, 4, 5, 6, 7, 8, 9}

> flip value:3
{2, 1, 3, 4, 5, 6, 7, 8, 9}

> flip value:2
'Done! That took you 9 steps.'

Now that we have an implementation of the game, we can play with it interactively. We can also have fun writing programs that play automatically (and hopefully win). Below is such a program. Upon completion, it displays the detail of each step of the game and the number of steps it took to win.

sorted := numbers at: numbers sort.
unsortedCount := numbers count.
journal := {numbers clone}.

[numbers isEqual: sorted] whileFalse:
[
    maxIndex := numbers indexOfObject: (numbers at: unsortedCount iota) \ #max: .
    maxIndex + 1 = unsortedCount ifFalse:
    [
        maxIndex = 0 ifFalse:[flip value: maxIndex + 1. journal addObject:numbers clone].
        result := flip value: unsortedCount.
        journal addObject: numbers clone.
    ].
    unsortedCount := unsortedCount - 1
].

journal printString ++ '\n' ++ result.

It is based on the following process:


Copyright © 2006 Philippe Mougin