Ubuntu insights, Programming in groovy, java, et als!

Showing posts with label Pharo. Show all posts
Showing posts with label Pharo. Show all posts

Sunday, March 18, 2012

TicTacToe Game in Pharo Smalltalk

For an absolute pharo/smalltalk beginner, I think this would be a good place to start with. This is a simple TicTacToe implementation with just three classes : TicTacToe, TicTacToeCell and TicTacToeModel using Morphs. Works on MVC based architecture with view and model separate (no specific class for controller though).

Object subclass: #TicTacToe
instanceVariableNames: 'container model'
classVariableNames: ''
poolDictionaries: ''
category: 'VK-Games'

initialize 
container := Morph new 

              layoutPolicy: TableLayout new; 
              color: Color transparent.
model := TicTacToeModel new:3.
self addRows.
self addControls.
^self.

addRows
| rowMorph aCell rowCol |
1 to:3 do:[ :row |
rowMorph := Morph new layoutPolicy: RowLayout new.
1 to: 3 do: [ :col |
aCell := TicTacToeCell new.
aCell setModel: (model) row: row col: col.
rowMorph addMorph: aCell.
].
container addMorph: rowMorph.
]

addControls
| rowMorph newGameButton exitGameButton |
rowMorph := Morph new 

             layoutPolicy: RowLayout new; 
             color: Color transparent.
newGameButton := self createCtrlLabelled: 'New'      onClickExecutes: [self restart].
exitGameButton := self createCtrlLabelled: 'Exit'  onClickExecutes: [container delete].
rowMorph addMorph: exitGameButton.
rowMorph addMorph: newGameButton.
container addMorph: rowMorph.

createCtrlLabelled: aString onClickExecutes: aBlock
| aCtrlButton |
aCtrlButton := SimpleButtonMorph new label: aString.
aCtrlButton color: (Color black alpha: 0.2).
aCtrlButton extent: 60@30.
aCtrlButton on: #click send: #value to: aBlock.
^aCtrlButton.

open 
container openInWorld.

restart
container delete.
Smalltalk garbageCollect.
TicTacToe new open.

*****************************************

SimpleButtonMorph subclass: #TicTacToeCell
instanceVariableNames: 'parentModel rowNum colNum'
classVariableNames: ''
poolDictionaries: ''
category: 'VK-Games'



initialize 
super initialize.
self label: ''.
self extent: 40@40.
self on: #click send: #value to: (self onClickExecutionBlock).
^self.



setModel: ticTacToeModel row: aRow col: aCol
parentModel := ticTacToeModel.
rowNum := aRow.
colNum := aCol.



onClickExecutionBlock
^[
(self label size) == 0
ifTrue:[
self label: (parentModel updateAtRow: rowNum 
                Col: colNum).
parentModel checkWinCondition.
self extent: 40@40.
].
 ]


***************************************** 

Matrix subclass: #TicTacToeModel
instanceVariableNames: 'filledCellCount currentFill winner'
classVariableNames: ''
poolDictionaries: ''
category: 'VK-Games'

initialize 
super initialize.
filledCellCount := 0.
currentFill := nil.
winner := nil.

updateAtRow: r Col: c
currentFill == nil
ifTrue:[ currentFill := 'X'. ]
ifFalse:[
currentFill == 'X'
ifTrue: [ currentFill := 'O'. ]
ifFalse: [ currentFill := 'X'. ]
].
self at: r at: c put: currentFill.
filledCellCount := filledCellCount + 1.
^currentFill.

checkWinCondition
filledCellCount >= 5 "for optimization. Win can occur minimum at 5th turn"
ifTrue: [
Transcript show: 'Yes'.
1 to: 3 do: [:idx |
self checkWinConditionInRow: idx.
self checkWinConditionInColumn: idx.
].
self checkWinConditionInDiagonals.
].
checkWinConditionInRow: rowNum
|set|
winner isNil
ifTrue: [
set := (self atRow: rowNum) asSet.
self checkWinConditionInSet: set
].
^winner.

checkWinConditionInColumn: colNum
|set|
winner isNil
ifTrue: [
set := (self atColumn: colNum) asSet.
self checkWinConditionInSet: set.
].
^winner.

checkWinConditionInDiagonals
|set1 set2 |
winner isNil
ifTrue: [
set1 := (self diagonal) asSet.
set2 := Set newFrom: {(self at: 1 at: 3). (self at: 2 at: 2). (self at: 3 at: 1)} asOrderedCollection.
self checkWinConditionInSet: set1.
self checkWinConditionInSet: set2.
].
^winner.

checkWinConditionInSet: aSet
aSet size == 1
ifTrue: [
(aSet includes: 'X')
ifTrue: [winner := 'P1'. Transcript open. Transcript show: 'Player 1 is the winner!!'.].
(aSet includes: 'O')
ifTrue: [winner := 'P2'.  Transcript open. Transcript show: 'Player 2 is the winner!!'.].
].



Friday, March 02, 2012

Find RSS Feed URL of a Webpage

Given a URL of a web page, one can programatically search through the meta tags of the webpage's content for alternate URL links (like atom or RSS feed links for the same) to thereon further use them to parse and process the content of the webpage. Typically this is the way Google Reader works. Here I present a very simple implementation of the same in pharo smalltalk.


Object subclass: #RSSReader
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'VamsiExperiments'


getURLContent: url
  "## Comment : Supply the url String of the webpage,
 
   ## example: http://nerdysermons.blogspot.in"
| urlContent |
urlContent := (url asUrl retrieveContents contents asString).
^urlContent



findAlternateLinksInUrlContent: urlContent
  "## Comment : The above fetched page content to 

   ## be passed here to get an ordered collection 
   ## of alternate links"      
| links|
links := OrderedCollection new.
urlContent linesDo:  [:line |
(line findString: '<link rel="alternate"') > 0
ifTrue: [
links add: (line findTokens:'"' includes: 'http://').
].  
].
^links.

Monday, December 05, 2011

Pharo Beginner : My first Smalltalk Program


DockingBarMorph new
  position: 0@225;

        addMorph: (SimpleButtonMorph new
                          label: 'Close';
                          target: [DockingBarMorph allInstances last delete];
     height: 55;
                          actionSelector: #value);

        addMorph: (SimpleButtonMorph new
            label: 'Open Transcript';
                          target: [Transcript open.
                                        Transcript show: '*** Default text in Transcript ***'
                                        ];
                          actionSelector: #value);

addMorph: (SimpleButtonMorph new
                        label: 'Open Browser';
     target: [Browser open.];
                        actionSelector:#value);

       addMorph: (SimpleButtonMorph new
                            label: 'New Workspace ';
                            target: [Workspace new open.];
                            actionSelector:#value);

addMorph: (SimpleButtonMorph new
                          label: 'Dock';
                          target: [UIManager inform: 'Hello world.. This is a sample Dock..'];
                         height: 55;
                          actionSelector: #value);
  openInWorld.


*************************

Tried to add up custom launchers for pharo development utilities. Currently implemented new Workspace open, System Browser, Transcript, etc.. Will have to make it complete so that the dock should be able to launch every component under the conventional right click popup in the pharo environment..

A simple pharo starter program which you can fiddle and extend, after a thorough understanding on ProfStef go.