From VisualWorks®, 7.5 of April 16, 2007 on August 8, 2007 at 2:52:40 pm (Dialog confirm: 'You are filing-in a Parcel source file!\\While this is possible it will not have\the same effect as loading the parcel.\None of the Parcel''s prerequisites will\be loaded and none of its load actions\will be performed.\\Are you sure you want to file-in?' withCRs) ifFalse: [self error: 'Parcel file-in abandoned. Choose terminate or close.'] <class> <name>WATicTacToeLibrary</name> <environment>Seaside</environment> <super>Seaside.WAFileLibrary</super> <private>false</private> none <imports></imports> <category>My Classes</category> <attributes> <package>TicTacToe</package> </attributes> </class> <class> <name>WATicTacToe</name> <environment>Seaside</environment> <super>Seaside.WAComponent</super> <private>false</private> none p1 p2 board currentPlayer winner <imports></imports> <category>My Classes</category> <attributes> <package>TicTacToe</package> </attributes> </class> <class> <name>WATicTacToeBoard</name> <environment>Seaside</environment> <super>Seaside.WAComponent</super> <private>false</private> none board combos game <imports></imports> <category>My Classes</category> <attributes> <package>TicTacToe</package> </attributes> </class> <class> <name>WATicTacToePlayer</name> <environment>Seaside</environment> <super>Seaside.WAComponent</super> <private>false</private> none name score bored symbol game <imports></imports> <category>My Classes</category> <attributes> <package>TicTacToe</package> </attributes> </class> <class> <name>WATicTacToeTask</name> <environment>Seaside</environment> <super>Seaside.WATask</super> <private>false</private> none <imports></imports> <category>TicTacToe</category> <attributes> <package>TicTacToe</package> </attributes> </class> <name>DefaultPicture</name> <environment>Seaside.WATicTacToeBoard</environment> <private>false</private> <constant>false</constant> <category>static</category> <initializer>nil</initializer> <attributes> <package>TicTacToe</package> </attributes> <methods> Seaside.WATicTacToeLibrary <category>stylesheets</category>
tacCss ^ ' .player { width: 150px; padding-left: 10px; padding-right: 10px; background-color: lightgrey; } #player-1 { top: 0px; left: 0px; } #player-2 { top: -444px; left: 390px; } .your-play { text-decoration: blink; } '
ticCss ^ ' h1 { font-size: 150%; } #tictactoe { font-family: Verdana; font-size: small; } #field { margin-top: 50px; } #field h1 { text-align: center; } .box { position: relative; border: 1px solid black; height: 220px; } '
toeCss ^ ' #board { top: -222px; left: 180px; background-color: lightgreen; width: 200px; } #board table { margin-left: auto; margin-right: auto; border-collapse: collapse; border-spacing: 0px; } .busy { font-size: x-large; font-weight: bold; text-align: center; margin-left: auto; margin-right: auto; } td { border: 3px red solid; height: 50px; width: 40px; margin: 0; padding: 0; } img { border: none; } '
</methods> <methods> Seaside.WATicTacToeLibrary <category>accessing</category>
selectorsToInclude ^#( #ticCss tacCss #toeCss )
</methods> <methods> Seaside.WATicTacToe <category>accessing</category>
currentPlayer ^currentPlayer
p1 ^p1
p1: aPlayer p1 := aPlayer. p1 game: self.
p2 ^p2
p2: aPlayer p2 := aPlayer. p2 game: self.
</methods> <methods> Seaside.WATicTacToe <category>play</category>
giveUp self nextTurn. self setWinner. self answer: winner.
nextTurn board hasWon ifTrue: [self setWinner] ifFalse: [board isFull ifTrue: [self setNoWinner]]. self isFinished ifTrue: [^self]. currentPlayer := currentPlayer ifNil: [p1] ifNotNil: [currentPlayer = p1 ifTrue: [p2] ifFalse: [p1]].
setNoWinner winner := nil. currentPlayer := nil.
setWinner winner := currentPlayer. currentPlayer := nil. winner win.
</methods> <methods> Seaside.WATicTacToe <category>testing</category>
isFinished ^ board hasWon or: [board isFull].
</methods> <methods> Seaside.WATicTacToe <category>initialize-release</category>
initialize "Initialize a newly created instance. This method must answer the receiver." super initialize. board := WATicTacToeBoard new game: self. self session registerObjectForBacktracking: board. self session registerObjectForBacktracking: self. ^self
</methods> <methods> Seaside.WATicTacToe <category>rendering</category>
children ^ Array with: p1 with: p2 with: board
renderBoardAndPlayersOn: html ^(html div) id: #field; with: [(html div) class: #player; class: #box; id: #'player-1'; with: p1. (html div) class: #box; id: #board; with: board. (html div) class: #player; class: #box; id: #'player-2'; with: p2]
renderContentOn: html (html div) id: #tictactoe; with: [self isFinished ifFalse: [html heading: 'Probably the best tic tac toe in the world'. html paragraph: [html strong: 'Note: '. html text: 'Players can undo their play by using the back button']] ifTrue: [html heading: 'Game over']. self isFinished ifFalse: [(html anchor) callback: [self giveUp]; with: currentPlayer name , ' gives up!'] ifTrue: [(html anchor) callback: [self answer: winner]; with: 'OK']. self renderBoardAndPlayersOn: html]
</methods> <methods> Seaside.WATicTacToe class <category>instance creation</category>
player: aPlayer playsWith: anotherPlayer ^ (self new) p1: aPlayer; p2: anotherPlayer; nextTurn; yourself
</methods> <methods> Seaside.WATicTacToeBoard <category>accessing</category>
board ^board
board: anObject board := anObject
combos ^combos
combos: anObject combos := anObject
game ^game
game: anObject game := anObject
</methods> <methods> Seaside.WATicTacToeBoard <category>testing</category>
hasWon ^ self board asSet anySatisfy: [:player | self hasWon: player].
hasWon: player ^ combos anySatisfy: [:combo | combo allSatisfy: [:cell | (board at: cell) = player]]
isFull ^ board noneSatisfy: [:cell | cell isNil]
</methods> <methods> Seaside.WATicTacToeBoard <category>rendering</category>
renderCells: cells on: html cells do: [:cell | | aPlayer | aPlayer := board at: cell. html tableData: [aPlayer ifNil: [game isFinished ifFalse: [(html anchor) callback: [board at: cell put: game currentPlayer. game nextTurn]; with: [html image form: self defaultPicture]]] ifNotNil: [(html div) class: #busy; with: aPlayer symbol]]]
renderContentOn: html html heading: 'Board'. html table: [ html tableRow: [self renderCells: (1 to: 3) on: html]; tableRow: [self renderCells: (4 to: 6) on: html]; tableRow: [self renderCells: (7 to: 9) on: html]].
</methods> <methods> Seaside.WATicTacToeBoard <category>constants</category>
cellSize ^ 40
defaultPicture "Cache it so that the web browsers can cache it too" DefaultPicture isNil ifTrue: [DefaultPicture := Form extent: self cellSize @ self cellSize]. ^DefaultPicture.
</methods> <methods> Seaside.WATicTacToeBoard <category>initialize-release</category>
initialize "Initialize a newly created instance. This method must answer the receiver." super initialize. board := Array new: 9. combos := #( (1 2 3) (4 5 6) (7 8 9) (1 4 7) (2 5 8) (3 6 9) (1 5 9) (3 5 7) ). self session registerObjectForBacktracking: board. ^self
</methods> <methods> Seaside.WATicTacToePlayer <category>accessing</category>
bored ^bored
game ^game
game: anObject game := anObject
name ^name
name: anObject name := anObject
symbol ^symbol
symbol: anObject symbol := anObject
</methods> <methods> Seaside.WATicTacToePlayer <category>winning</category>
win score := score + 1
</methods> <methods> Seaside.WATicTacToePlayer <category>initialize-release</category>
initialize "Initialize a newly created instance. This method must answer the receiver." super initialize. name := 'no name'. score := 0. bored := false. self session registerObjectForBacktracking: self. ^self
</methods> <methods> Seaside.WATicTacToePlayer <category>rendering</category>
renderContentOn: html html heading: 'Player ' , (String with: symbol). html text: 'Name : '; text: name. html horizontalRule. html text: 'Score : '; text: score. html horizontalRule. (html anchor) callback: [bored := bored not]; with: 'Are you bored ?'. html break. html text: 'Currently : '; text: bored. html horizontalRule. self game currentPlayer == self ifTrue: [(html heading) class: #'your-play'; level: 2; with: 'Your play']
</methods> <methods> Seaside.WATicTacToePlayer class <category>instance creation</category>
named: playerName symbol: aChar ^self new name: playerName; symbol: aChar; yourself.
</methods> <methods> Seaside.WATicTacToeTask <category>task</category>
go | n1 n2 p1 p2 winner swap | n1 := self request: 'Player 1, enter you name : ' label: 'play' default: 'Oliver'. self inform: 'Hello ' , n1 , ', you will play with O'. n2 := self request: 'Player 2, enter your name :' label: 'play' default: 'Xavier'. self inform: 'Hello ' , n2 , ', you will play with X'. p1 := WATicTacToePlayer named: n1 symbol: $O. p2 := WATicTacToePlayer named: n2 symbol: $X. [p1 bored or: [p2 bored]] whileFalse: [ winner := self call: (WATicTacToe player: p1 playsWith: p2). winner ifNil: [self inform: 'This was a draw'] ifNotNil: [self inform: winner name, ' won !']. swap := p1. p1 := p2. p2 := swap]. self inform: 'Bye !'.
</methods> <methods> Seaside.WATicTacToeTask class <category>initialize-release</category>
canBeRoot ^ true
description ^'Probably the best tic tac toe in the world (backtracking demo)'
initialize (self registerAsApplication: 'games/tictactoe') addLibrary: WATicTacToeLibrary
</methods> <methods> Form <category>seaside</category>
asMIMEDocumentType: mimeType ^self asMIMEDocument
</methods> <initialize> Seaside.WATicTacToeTask </initialize> "Imported Classes:" self error: 'Attempting to file-in parcel imports. Choose terminate or close' <class> <name>WAFileLibrary</name> <environment>Seaside</environment> <super>Seaside.WALibrary</super> <private>false</private> none default <imports></imports> <category>Seaside-Libraries</category> <attributes> <package>Seaside-Libraries</package> </attributes> </class> <class> <name>Form</name> <environment>Smalltalk</environment> <super>Core.Object</super> <private>false</private> none image transparentColor <imports></imports> <category>Seaside/VW Support</category> <attributes> <package>Seaside/VW Support</package> </attributes> </class> <class> <name>WAComponent</name> <environment>Seaside</environment> <super>Seaside.WAPresenter</super> <private>false</private> none decoration <imports></imports> <category>Seaside-Component</category> <attributes> <package>Seaside-Component</package> </attributes> </class> <class> <name>WATask</name> <environment>Seaside</environment> <super>Seaside.WAComponent</super> <private>false</private> none <imports></imports> <category>Seaside-Component</category> <attributes> <package>Seaside-Component</package> </attributes> </class>