Sunday, October 18, 2015

Using traits to reuse code in Pharo

While working on a small Tetris-like clone in Pharo, I found an opportunity to reuse some code.

It's common for Tetris implementations to show a small preview of the tetrimino that comes next. Here's how it looks:

I wanted to create a separate Morphic component to show this preview. But I didn't want to duplicate the code required to paint the tetriminos. Sharing this code will allow me to have just one place to change the way tetriminos look. Also I didn't want to create a base class on top of both the game and the preview Morphs.

While reading about Pharo and Squeak I found that it supports Traits. The Pharo collaborActive book provides a nice explanation of how to use traits. Here's a quick definition from this document:

... traits are just groups of methods that can be reused in different classes.

This is exactly what I needed for reusing the tetrimino matrix drawing code. The following code shows the code defined in the game matrix Morph component.

drawOn: canvas
   "Draws the current game state"
   |rows columns currentValue rectangle currentColor cellWidth cellHeight|

   rows := gameState size x.
   columns := gameState size y.

   super drawOn: canvas.

   cellWidth :=   ((self width) / columns) asFloat truncated.
   cellHeight :=   ((self height) / rows) asFloat truncated.
   1 to: rows do: [ :row |
      1 to: columns do: [ :column|
         currentValue := gameState at: row at: column .
         currentValue ~= 0 ifTrue: [
                 currentColor := (colors at: currentValue).
                 rectangle := Rectangle left: (self bounds left)



                 canvas frameAndFillRectangle: rectangle
                                 fillColor:  currentColor
                                 borderWidth:  1
                                 borderColor: (Color white).
                  ]
          ]
       ].

Moving this code to a trait implies that I have to pass all instance state variables as an argument of the draw method.

The definition of the trait looks like this:

Trait named: #TTetriminoDrawing
    uses: {}
    category: 'TryTrix'

And the definition of the method inside this trait looks like this:

drawGameStateOn: canvas 
      width: areaWidth height: areaHeight 
      columns: columns rows: rows 
      morphBounds: morphBounds
      matrix: contentMatrix
      colors:  colorPalette
   "Draw the contents of the specified matrix on the given canvas"
   |cellWidth cellHeight currentValue currentColor rectangle|
      cellWidth :=   (areaWidth / columns) asFloat truncated.
   cellHeight :=   (areaHeight / rows) asFloat truncated.
   1 to: rows do: [ :row |
      1 to: columns do: [ :column|
         currentValue := contentMatrix at: row at: column .
         currentValue ~= 0 ifTrue: [ 
            currentColor := (colorPalette at: currentValue).
            rectangle := Rectangle left: (morphBounds left) + ((column - 1)*cellWidth) 
                                    right: (morphBounds left) + ((column - 1)*cellWidth) + cellWidth
                                    top: (morphBounds top) + ((row - 1)*cellHeight )
                                    bottom: (morphBounds top) + ((row - 1)*cellHeight ) + cellHeight.
            canvas frameAndFillRectangle: rectangle
                  fillColor:  currentColor
                  borderWidth:  1
                  borderColor: (Color white).
             ]
          ]
       ].

Now I can use this trait inside each morph definition:

Morph subclass: #TryTrixMorph
    uses: TTetriminoDrawing
    instanceVariableNames: 'gameState colors eventHandlers'
    classVariableNames: ''
    category: 'TryTrix'


Morph subclass: #TetriminoPreview
    uses: TTetriminoDrawing
    instanceVariableNames: 'matrix'
    classVariableNames: ''
    category: 'TryTrix'

This code can be found in here.

Tuesday, September 15, 2015

A small Tetris-like Morphic component in Pharo

As part of my exploration of Pharo, I wanted to create a small basic/naive/incomplete implementation of a Tetris-like game as a Morphic component. Here's an example of the current state of the code:

Implementation

The (still incomplete) implementation is very simple. It uses a matrix to represent the game state. When we want to paint the current game state, we examine the matrix and paint a small rectangle for each of the occupied positions.

drawOn: canvas
   "Draws the current game state"
   |rows columns currentValue rectangle currentColor cellWidth cellHeight|

   rows := gameState size x.
   columns := gameState size y.
   
   super drawOn: canvas.
   
   cellWidth :=   ((self width) / columns) asFloat truncated.
   cellHeight :=   ((self height) / rows) asFloat truncated.
   1 to: rows do: [ :row |
      1 to: columns do: [ :column|
         currentValue := gameState at: row at: column .
         currentValue ~= 0 ifTrue: [ 
            currentColor := (colors at: currentValue).
            rectangle := Rectangle left: (self bounds left) + ((column - 1)*cellWidth) 
                                   right: (self bounds left) + ((column - 1)*cellWidth) + cellWidth
                                   top: (self bounds top) + ((row - 1)*cellHeight )
                                   bottom: (self bounds top) + ((row - 1)*cellHeight ) + cellHeight.
            canvas frameAndFillRectangle: rectangle
                  fillColor:  currentColor
                  borderWidth:  1
                  borderColor: (Color white).
             ]
          ]
       ].

Each Tetrimino is also represented as a small matrix.

Here's the definition for the 'J' and 'S' tetriminos:


   kind = #J ifTrue: [ 
      resultTetrimino := 
         Tetrimino 
            create: gameMatrix 
            tetriminoMatrix: 
               (Matrix rows: 2 
                  columns: 3 
                  contents: { 1. 1. 1.
                              0. 0. 1. })  
            colorIndex: 5.
      ].

...

   kind = #S ifTrue: [ 
      resultTetrimino := 
         Tetrimino 
            create: gameMatrix 
            tetriminoMatrix: 
               (Matrix rows: 2 
                  columns: 3 
                  contents: { 0. 1. 1.
                              1. 1. 0. })  
            colorIndex: 3.
      ].

The implementation is still incomplete, I hope that future posts will show more progress.

The source code can be found here: http://www.github.com/ldfallas/TryTrix .

Friday, August 28, 2015

Glider Gun

Just a quick look at the Gosper's Glider Gun pattern.

This is running on Pharo using this program https://github.com/ldfallas/GameOfLife

Sunday, August 23, 2015

Game Of Life and Pharo

For me, watching executions of the Conway's Game of Life is hypnotizing. It is interesting how a small set of simple rules creates such complex and beautiful patterns.

Creating a naive version of the Game of Life is a small programming task, which is ideal for learning a new programming language. I used it to create a small example in Pharo which is a Smalltalk based language. For its implementation I also used the Morphic UI environment.

Game of life Morph executing

The program is written as a Morph, which is the name of an object on the screen. Here's the definition:

Morph subclass: #GameOfLifeMorph
        instanceVariableNames: 'columns rows content mouseInteraction nextGrid'
        classVariableNames: ''
        category: 'GameOfLife'

Drawing the matrix with the contents of the game is very simple:

drawing
drawOn: canvas
     "Draws the game of life widget with the current state"
     | cellWidth cellHeight rectangle  cellColor cellValue|
      
     cellWidth :=   (self width) / columns.
     cellHeight :=   (self height) / rows.
     1 to: rows do: [ :row |
          1 to: columns do: [ :column |
                 cellValue := (content at: row at: column).
                 cellColor := cellValue = 1 ifTrue: [ Color black ] ifFalse: [ Color white  ].
                 rectangle := Rectangle left: (self bounds left) + ((column - 1)*cellWidth) 
                                        right: (self bounds left) + ((column - 1)*cellWidth) + cellWidth
                                        top: (self bounds top) + ((row - 1)*cellHeight )
                                         bottom: (self bounds top) + ((row - 1)*cellHeight ) + cellHeight.
         
                 cellValue = 1 ifTrue: [canvas fillRectangle:  rectangle color:  cellColor]
                               ifFalse: [canvas frameAndFillRectangle: rectangle 
                                                   fillColor:  (Color white) 
                                                   borderWidth: 1 
                                                   borderColor: (Color black)].
             ]
       ].
       ^self.

The implementation of the animation part of the program was created using the step and stepTime methods.

stepping and presenter
step
      "Verifies the rules of the Game Of Life"
      | tmp |
      
      1 to: rows do:  [ :row | 
          1 to: columns do:  [ :column |
              nextGrid at: row at: column put: (self getNextGenerationFor: row column: column).
          ]
      ].
      tmp := content.
      content := nextGrid.
      nextGrid := tmp.
      self changed.

The following method shows how to get the next generation for a given (row, column) individual.

This method is going to check for the game of life rules.

game of life rules
getNextGenerationFor: row column: column
      "Verifies the Game Of Life rules"
      |topLeft top topRight left right bottomLeft bottomRight bottom neighbors|

      topLeft :=  self getCellValue: (row - 1) column: (column - 1).
      top := self getCellValue: (row - 1) column: column.
      left := self getCellValue: row column: (column - 1).
      right := self getCellValue: row column: (column + 1).
      topRight := self getCellValue: (row - 1) column: (column + 1).
      bottomRight := self getCellValue: (row + 1) column: (column + 1).
      bottom := self getCellValue: (row + 1) column: column.
      bottomLeft := self getCellValue: (row + 1) column: (column - 1).
   
      neighbors := topLeft + top + left + right + topRight + bottomRight + bottom  + bottomLeft.

      ^ ((content at: row at: column) = 1) 
             ifTrue: [ (neighbors < 2 | (neighbors > 3)) ifTrue: [ 0 ] ifFalse: [ 1 ]  ] 
             ifFalse: [ (neighbors = 3) ifTrue: [ 1 ] ifFalse: [ 0 ] ].

The last statement verifies the rules:

  • A live cell with less than two neighbors dies in the next generation
  • A live cell with two or three neighbors survives to the next generation
  • A live cell with more than three neighbors dies
  • A dead cell with three neighbors becomes alive in the next generation

To open this Morph into the Pharo environment we can evaluate:

|m|
m := GameOfLifeMorph rows: 30 columns: 30.
m width: 300 ;height: 300 ; openInWorld.
m stopStepping.
m enableMouseInteraction . 

To start the execution we can evaluate:


GameOfLifeMorph allInstances last startStepping.

Programming in Pharo is a very interesting experience. This mainly because the development environment is really integrated with the program you are developing. Something that called my attention is how you can define missing code while debugging and without stopping the debugging session.

The code for this experiment can be found here: http://github.com/ldfallas/GameOfLife

Monday, August 10, 2015

Starting with Pharo and external source control

Here's a series of steps I'm following for using Git to store the source code of some Pharo experiments I'm working on.

I'm starting learning about Pharo. The information on this post is based on the nice Pharo and Github using Sourcetree video and an introduction to Monticello.

Configuring a repository

We can start by creating a repository that is located in the filesystem. To define configure this repository we open the "Monticello Browser" from the "World" menu and press the "+Repository" button.

We are going to select the filetree:// repository type. This is useful to store the code in separate files.

When this option is selected the UI will prompt us for the folder where the code will be stored. We are going to specify a directory where we executed the git init command . Other source control systems could be used to manage this directory since it will contain the source code as text files.

Creating a package

Now we're going to define a package where we will the create the code to be stored in source control. To define the package we open the "Monticello Browser" from the "World" menu and press the "+Package" button.

Now we can create a class inside this package. We are going to define the GameOfLifeMorph class to be in the GameOfLife category.

We are going to add a method to the GameOfLifeMorph class.

After adding these elements we can save the changes to the GameOfLife package. We can review the changes before saving by pressing the Changes button on the "Monticello" browser.

This option opens the following screen to review the changes before saving.

After reviewing the changes we can save the changes to the file system using the Save button in the "Monticello Browser" window. Now we can go to the command line to directory we selected when creating the repository and execute a git status command.

~/devel/pharo/GameOfLife$ git add .filetree GameOfLife.package/
~/devel/pharo/GameOfLife$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

        new file:   .filetree
        new file:   GameOfLife.package/.filetree
        new file:   GameOfLife.package/GameOfLifeMorph.class/README.md
        new file:   GameOfLife.package/GameOfLifeMorph.class/instance/initWithRows.columns..st
        new file:   GameOfLife.package/GameOfLifeMorph.class/methodProperties.json
        new file:   GameOfLife.package/GameOfLifeMorph.class/properties.json
        new file:   GameOfLife.package/monticello.meta/categories.st
        new file:   GameOfLife.package/monticello.meta/initializers.st
        new file:   GameOfLife.package/monticello.meta/package
        new file:   GameOfLife.package/monticello.meta/version
        new file:   GameOfLife.package/properties.json

~/devel/pharo/GameOfLife$ git commit -m "First commit"

Sunday, June 29, 2014

Writing (very) simple tests in C

A couple of weeks ago I was trying to write some small tests for a toy C program I'm working on

Although there are some nice frameworks for writing units tests in C, I wanted something minimal. So I wrote some functions that let me do that:


void run_test(char* testname, void (*testfunc)()) {
  printf("Running %s\n", testname);
  testfunc();
}

#define RUN_TEST(testname) run_test(#testname, testname);

void tassert(int result, const char* testName, char* formatString, ...) {

  va_list args;
  va_start(args, formatString);
  if (!result) {
    printf("ASSERT FAILED in test \"%s\": ", testName);
    vprintf(formatString, args);
    printf("\n");
  }
  va_end(args);
}

void tassert_equal_ints(int expectedValue,int actualValue, const char* testName) {
  int comparisonResult;
  comparisonResult = expectedValue == actualValue;
  tassert(comparisonResult,
          testName,
          "expected: %d, actual %d", 
          expectedValue, 
          actualValue);
}

These very simple functions allowed me to write small tests. For example:

void testTreeFormation1() {
   Expr* expr;
   OutStream stringOut;
   
   stringOut = createStringOutStream(15);
   expr =
      createAddition(
            createAddition(
               createNumLiteral(10.2),
               createNumLiteral(-13)),
            createNumLiteral(13));

   printExpr(expr, &stringOut);

   tassert_equal_strings("<<11.2 + -13> + 13>",
                        getStringFromStringOutStream(&stringOut),
                        __FUNCTION__);
   
   deepReleaseExpr(expr);
   destroyOutStream(&stringOut);
}

This test is verifies that an expression tree is created as expected.

The main method to execute the tests looks like this:

int main(int argc, char* argv[]) {
  
  printf("Running tests\n");
  
  RUN_TEST(testStrBuffer1);
  RUN_TEST(testStrBuffer2);
  RUN_TEST(testStrBuffer3);
  RUN_TEST(testStrBuffer4);
  RUN_TEST(test1);
  RUN_TEST(testTreeFormation1);
  ...
}

Saturday, October 6, 2012

An example use of Haskell Views

In this post I'm going to show how I'm using Haskell Views in a small Scheme implementation to deal with syntactic sugar.

One example of syntactic sugar in Scheme is the way to define functions. You can do it the following way:


(define square (lambda (x) (* x x))
But you can also use the following shortcut:

(define (square x) (* x x))

I'm going to take advantage of Haskell Views to simplify the implementation of this feature. The following code shows the data type representing Scheme code.


       data Expr a where
               ScSymbol :: String -> Expr a
               ScString :: String -> Expr a
               ScNumber :: Integer -> Expr a
               ScDouble :: Double -> Expr a 
               ScCons :: (Expr a) -> (Expr a) -> (Expr a)
               ScNil :: Expr a
               ScBool :: Bool -> Expr a
               ScQuote :: (Expr a) -> Expr a
               ScEnv ::  (Expr a)
               ScChar :: Char -> Expr a
               ScPort :: Handle -> Expr a
               ScClosure :: ScExecutable a =>  [String] -> a -> (Env a) -> Expr a
               ScPrimitive ::  ([Expr a] -> ScInterpreterMonad (Expr a))  -> Expr a

As a side note,I'm using ScCons/ScNil to represent lists which is different from the way "Write Yourself a Scheme in 48 Hours" defines them (a wrapper around a Haskell list). This decision turned out to be incorrect since manipulating a Haskell list is easier.

Given Scheme datatype definition we can represent the following function definition:

(define (id x) x)

As the following structure:


  (ScCons
     (ScSymbol "define")
     (ScCons
        (ScCons
           (ScSymbol "id")   
           (ScCons
              (ScSymbol "x")
              ScNil))
        (ScCons
           (ScSymbol "x")
           ScNil)))

And the following code:

(define id (lambda (x) x))

Using the following structure


  (ScCons
     (ScSymbol "define")
     (ScCons
        (ScSymbol "id")
        (ScCons
           (ScCons
              (ScSymbol "lambda")
              (ScCons
                 (ScCons
                    (ScSymbol "x")
                    ScNil)
                 (ScCons
                    (ScSymbol "x")
                    ScNil)))
           ScNil)))

Using Haskell Views we can create a view that returns the desired parts:


defineView :: (Expr a) -> Maybe (String, Expr a)
defineView  (ScCons 
             (ScSymbol "define")
             (ScCons 
                 name@(ScSymbol symbolToDefine)
                 (ScCons
                    value
                    ScNil))) = Just (symbolToDefine, value)
defineView  (ScCons 
                (ScSymbol "define")
                (ScCons 
                   (ScCons 
                      name@(ScSymbol symbolToDefine)
                      args)
                   (ScCons
                       value
                       ScNil))) = Just (symbolToDefine, 
                                        (ScCons (ScSymbol "lambda") 
                                                (ScCons args 
                                                        (ScCons value ScNil))))
defineView _ = Nothing

As shown above, this view will extract the parts of the original expression or create the necessary elements in the case of the function definition. Also it will fail in case of non supported syntax.

This view is used in the following code:


prepare (defineView -> Just (symbolToDefine, value)) = 
         do
            preparedValue <- prepare value
            return $ ScSeqDefine symbolToDefine preparedValue 

Code for this post is available in the ToyScheme repo.