程序代写代做代考 game chain algorithm C Java cache Smalltalk Lecture 8

Smalltalk Lecture 8
1

Snakes and Ladders game
http://en.wikipedia.org/wiki/Snakes_and_ladders
2

Smalltalk example code
We need a way to:
— Construct the board — Add some players — Play the game
The example script helps us to identify some classes and needed methods
SnakesAndLadders class>>example “self example playToEnd”
^ (self new)
add: FirstSquare new;
add: (LadderSquare forward: 4); add: BoardSquare new;
add: BoardSquare new;
add: BoardSquare new;
add: BoardSquare new;
add: (LadderSquare forward: 2); add: BoardSquare new;
add: BoardSquare new;
add: BoardSquare new;
add: (SnakeSquare back: 6);
add: BoardSquare new;
join: (GamePlayer named: ‘Jack’); join: (GamePlayer named: ‘Jill’); yourself
3

Cascade
How do you format multiple messages to the same receiver?
> Use a Cascade.
> Separate the messages with a semicolon.
> Put each message on its own line and indent one tab.
> For readability, usually it’s better to only use Cascades for messages with zero or one argument.
4

Yourself
How can you use the value of a Cascade if the last message doesn’t return the receiver of the message?
> Append the message yourself to the Cascade.
5

About yourself
> The effect of a cascade is to send all messages to the receiver of the first message in the cascade
— self new add: FirstSquare new; …
> But the value of the cascade is the value returned by the
last message sent
(OrderedCollection with: 1) add: 25; add: 35
> To get the receiver as a result we must send the additional message yourself
(OrderedCollection with: 1) add: 25; add: 35; yourself
an OrderedCollection(1 25 35)
35
6

Yourself implementation
> The implementation of yourself is trivial, and occurs just once in the system:
Object>>yourself ^ self
7

Inheritance in Smalltalk
> Single inheritance
> Static for the instance variables
— Instance variables are collected from the class and its direct and indirect superclasses.
> Dynamic for the methods
— Methods are looked up at run-time depending on the dynamic type of the receiver.
8

Creating classes
> A class is created by sending a message to its superclass
Object subclass: #SnakesAndLadders
SnakesAndLadders instanceVariableNames:
‘players squares turn die over’
9

Named Instance Variables
> Instance variables:
— Beginwithalowercaseletter
— Mustbeexplicitlydeclared:alistofinstancevariables
— Nameshouldbeuniqueintheinheritancechain
— Defaultvalueofinstancevariableisnil
— Privatetotheinstance,nottheclass(incontrasttoJava)
— Canbeaccessedbyallthemethodsoftheclassanditssubclasses — Instancevariablescannotbeaccessedbyclassmethods.
— Theclientsmustuseaccessorstoaccessaninstancevariable.
Design Hint:
— Donotdirectlyaccessinstancevariables of a superclass from subclass methods. This way classes are not strongly linked.
10

Problem — how to initialize objects?
Problem
> To create a new instance of a class, the message new must be sent to the class
— But the class (an object) cannot access the instance variables of the new object (!)
— So how can the class establish the invariant of the new object?
Solution
> Provide instance-side initialization methods in the protocol initialize-release that can be used to create a valid instance
11

Explicit Initialization
How do you initialize instance variables to their default values?
> Implement a method initialize that sets all the values explicitly.
—Override the class message new to invoke it on new instances
SnakesAndLadders>>initialize
super initialize.
die := Die new.
squares := OrderedCollection new. players := OrderedCollection new. turn := 1.
over := false.
12

Who calls initialize?
> Override the class message new to invoke initialize on new instances.
SnakesAndLadders class>>new ^ self basicNew initialize
> NB: You can override new, but you should never override basicNew!
13

Ordered Collection
How do you code Collections whose size can’t be determined when they are created?
> Use an OrderedCollection as your default dynamically sized Collection.
14

Super
How can you invoke superclass behaviour?
> Invoke code in a superclass explicitly by sending a message to super instead of self.
— The method corresponding to the message will be found in the superclass of the class implementing the sending method.
— Alwayscheckcodeusingsupercarefully.Changesuperto self if doing so does not change how the code executes!
15

Extending Super
How do you add to the implementation of a method inherited from a superclass?
> Override the method and send a message to super in the overriding method.
16

A closer look at super
> Suppose SnakeSquare and LadderSquare are two subclasses of BoardSquare class
> SnakeSquare and LadderSquare both extend the printOn: method of their superclass
BoardSquare>>printOn: aStream aStream nextPutAll:
‘[‘, position printString, self contents, ‘]’
LadderSquare>>printOn: aStream
super printOn: aStream.
aStream nextPutAll: forward asString, ‘+>’
SnakeSquare>>printOn: aStream
aStream nextPutAll: ‘<-', back asString. super printOn: aStream. 17 Normal method lookup Two step process: — Lookup starts in the class of the receiver (an object) 1. If the method is defined in the method dictionary, it is used 2. Else, the search continues in the superclass — If no method is found, this is an error ... 18 Message not understood When method lookup fails, an error message is sent to the object and lookup starts again with this new message. NB: The default implementation of doesNotUnderstand: may be overridden by any class. 19 Super > Super modifies the usual method lookup to start in the superclass of the class whose method sends to super
— NB: lookup does not start in the superclass of the receiver! – Cf. C new bar on next slide
— Super is not the superclass!
20

Super sends
‘Abar’
‘Abar & Afoo’
‘Abar & Cfoo’
‘Abar & Cfoo & Cfoo’ ‘Abar & Efoo & Cfoo’
A new bar
B new bar
C new bar
D new bar
E new bar
NB: It is usually a mistake to super-send to a different method. D>>bar should probably do self foo, not super foo!
21

Self and super
Sending to self is always dynamic. Sending to super is always static.
22

Getting Method
How do you provide access to an instance variable?
> Provide a method that returns the value of the variable.
— Give it the same name as the variable.
– NB: doesn’t need to be called “get…”
LoadedDie>>roll
self assert: roll notNil. ^ roll
23

Setting Method
How do you change the value of an instance variable?
> Provide a method with the same name as the variable.
— Have it take a single parameter, the value to be set.
– NB: doesn’t need to be called “set…”
LoadedDie>>roll: aNumber
self assert: ((1 to: 6) includes: aNumber). roll := aNumber.
24

Decomposing into Methods
How do you divide a program into methods?
> Divide your program into methods that perform one identifiable task.
— Keep all of the operations in a method at the same level of abstraction.
— This will naturally result in programs with many small methods, each a few lines long.
25

Method size
> Most methods will be small and self-documenting
— Fewexceptions:
– Complex algorithms
– Scripts (configurations)
– Tests
SnakesAndLadders>>playOneMove | result |
self assert: self invariant.
^ self isOver
ifTrue: [‘The game is over’] ifFalse: [
result :=
(self currentPlayer moveWith: die), self checkResult.
self upDateTurn.
result ]
26

Intention Revealing Message
How do you communicate your intent when the implementation is simple?
> Name the message so it communicates what is to be done rather than how it is to be done.
> Code a simple method for the message.
> Send a message to self.
SnakesAndLadders>>currentPlayer ^ players at: turn
SnakesAndLadders>>move …
self currentPlayer printNl.

27

Intention Revealing Selector
What do you name a method?
> Name methods after what they accomplish.
— Well-named methods can eliminate the need for most comments
SnakesAndLadders>>updateTurn
turn := 1 + (turn\\players size).
28

Some Naming Conventions
> Use imperative verbs for methods performing an action — moveTo:, leaveCurrentSquare, playOneMove
> Prefix testing methods (i.e., that return a boolean) with “is” or “has”
— isNil, isNotOver, isOccupied
> Prefix converting methods with “as” — asString
29

Message Comment
How do you comment methods?
> Communicate important information that is not obvious from the code in a comment at the beginning of the method.
— Method dependencies — To-do items
— Sample code to execute
SnakesAndLadders>>playToEnd “SnakesAndLadders example playToEnd” …
Hint: too many comments may indicate problems in the source code! — Try to refactor code and rename methods to get rid of comments!
30

Slow Fibonacci
Object subclass: #Fibs.
Fibs extend [
at: anIndex [
anIndex = 1 ifTrue: [ ^ 1 ].
anIndex = 2 ifTrue: [ ^ 1 ].
^ (self at: anIndex – 1) + (self at: anIndex – 2)
] ].
Fibs new at: 40 102334155
Takes about 10 seconds.
Forget about much larger values!
31

Cacheing Fibonacci
Object subclass: #Fibs.
Fibs instanceVariableNames: ‘cache’.
Fibs extend [
]
initialize [ cache := Dictionary new ]
Introduce the cache …
32

Cacheing Fibonacci
Now we introduce the lookup method, and redirect all accesses to use the cache lookup
Fibs extend [
at: anIndex [
anIndex = 1 ifTrue: [ ^ 1 ].
anIndex = 2 ifTrue: [ ^ 1 ].
^ (self lookup: anIndex – 1) + (self lookup: anIndex – 2)
]
lookup: anIndex [
^ cache at: anIndex ifAbsentPut: [ self at: anIndex ] ]
].
Fibs new initialize ; at: 100 354224848179261915075 … is virtually instantaneous!
33

Comparing Method
How do you order objects with respect to each other?
> Implement <= to return true if the receiver should be ordered before the argument — <,<=,>,>= are defined for Magnitude and its subclasses.
34

Sorted Collection
How do you sort a collection?
>
Use a Sorted Collection.
— Set its sort block if you want to sort by some criterion other than <= #( 'Snakes' 'Ladders' ) asSortedCollection a SortedCollection('Ladders' 'Snakes') #( 'Snakes' 'Ladders' ) asSortedCollection: [:a :b | b<=a ] a SortedCollection('Snakes' 'Ladders') a SortedCollection('Snakes' 'Ladders') #( 'Snakes' 'Ladders' ) asSortedCollection sortBlock: [:a :b | b<=a ] 35 Interval How do you code a collection of numbers in a sequence? > Use an Interval with start, stop and optional step value.
— Use the Shortcut Constructor methods Number>>to: and Number>>to:by: to build intervals
1 to: 5
(1 to: 5) asSet
(10 to: 100 by: 20) asOrderedCollection
(1 to: 5)
a Set(1 2 3 4 5)
an OrderedCollection(10 30 50 70 90)
36

Duplicate Removing Set
How do you remove the duplicates from a Collection?
> Send asSet to the collection
‘hello world’ asSet
a Set(Character space $r $d $e $w $h $l $o)
37

Searching Literal
How do you test if an object is equal to one of several literal values?
> Ask a literal Collection if it includes the element you seek
char = $a | char = $e | char = $i | char = $o | char = $u | char = $A | char = $E | char = $I | char = $O | char = $U
‘aeiou’ includes: char asLowercase
38

Concatenation
How do you put two collections together?
> Send “,” to the first with the second as argument
(1 to: 3), (4 to: 6)
#(1 2 3 4 5 6)
(Dictionary newFrom: { #a -> 1}), (Dictionary newFrom: { #b -> 2})
a Dictionary(#a->1 #b->2 )
39