The Game of Reverse in F-Script

Revised August 2009

Articles in this series

     Fundamentals
  1. Exploring Cocoa with F-Script
  2. Learn F-Script in 20 Minutes and Have Fun Playing with Core Image
  3. Scripting Cocoa with F-Script
  4. Creating Cocoa Classes with F-Script
  5. System-wide Scripting with F-Script
  6. Embedding F-Script into Cocoa Applications
  7. Accessing Mac OS X Frameworks with F-Script
     Miscellaneous
  1. Google Chart API Fun with Cocoa and F-Script
  2. 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 copy}.

[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 copy].
        result := flip value:unsortedCount.
        journal addObject:numbers copy.
    ].
    unsortedCount := unsortedCount - 1.
].

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

It is based on the following process:


Copyright © 2006-2009 Philippe Mougin