Morph subclass: #HanoiDisk instanceVariableNames: 'nom pile rectangle' classVariableNames: 'Epaisseur Largeur LesPiles Separation' poolDictionaries: '' category: 'Cours-Smalltalk-Hanoi'! !HanoiDisk commentStamp: '' prior: 0! Chaque Disque est representee comme une instance de HanoiDisk Elle possede 4 variables d'instances: nom - le nom du disque largeur - la largeur (1 est la plus petit disque) pile - un nombre indiquant sur quel mat elle se trouve rectangle - le rectangle que le disque occupe sur l'ecran Les variables de classe: LesPiles - contient les 3 piles Epaisseur - l'epaisseur d'un disque Separation - l'espace separant deux disques! !HanoiDisk methodsFor: 'class initialisation' stamp: 'hw 5/9/2007 11:33'! whichTowers: unTourHanoi LesPiles := unTourHanoi. Largeur := 14. Epaisseur := 14. Separation := 2! ! !HanoiDisk methodsFor: 'class initialisation' stamp: 'hw 5/9/2007 16:28'! whichTowers: unTourHanoi combien: combien LesPiles := unTourHanoi. Largeur := ((unTourHanoi extent x - 100) / combien / 3 - 5). Epaisseur := ((unTourHanoi extent y - 20) / combien - 10) min: 14. Separation := 2. "self halt."! ! !HanoiDisk methodsFor: 'deplacements' stamp: 'hw 5/8/2007 12:12'! bougeSur: destination pile := destination pile. "enleve l'ancien image" self invert. "reposition" rectangle center: destination center - (0 @ (Epaisseur + Separation)). "et l'afficher" self invert. (Delay forMilliseconds: 300) wait! ! !HanoiDisk methodsFor: 'initialize' stamp: 'hw 5/9/2007 13:21'! width: size pole: pole | ou y | self pile: pole. size >= 1000 ifFalse: ["un disque normal" self nom: (Character value: ($A asciiValue) + size - 1). y := 300 - ((LesPiles combien - size)*(Epaisseur + Separation)). ou := 100@y] ifTrue:[self nom: $m. ou := (100*pole)@(300+Epaisseur + Separation)]. self rectangle: (0@0 extent: (size*14)@Epaisseur). self rectangle center: ou! ! !HanoiDisk methodsFor: 'accessing' stamp: 'hw 4/24/2007 15:33'! center ^self rectangle center! ! !HanoiDisk methodsFor: 'accessing' stamp: 'hw 4/24/2007 14:55'! invert Display reverse: rectangle! ! !HanoiDisk methodsFor: 'accessing' stamp: 'hw 4/24/2007 14:37'! nom "Answer the value of nom" ^ nom! ! !HanoiDisk methodsFor: 'accessing' stamp: 'hw 4/24/2007 14:37'! nom: anObject "Set the value of nom" nom _ anObject! ! !HanoiDisk methodsFor: 'accessing' stamp: 'hw 4/24/2007 14:37'! pile "Answer the value of pile" ^ pile! ! !HanoiDisk methodsFor: 'accessing' stamp: 'hw 4/24/2007 14:37'! pile: anObject "Set the value of pile" pile _ anObject! ! !HanoiDisk methodsFor: 'accessing' stamp: 'hw 4/24/2007 14:37'! rectangle "Answer the value of rectangle" ^ rectangle! ! !HanoiDisk methodsFor: 'accessing' stamp: 'hw 4/24/2007 14:37'! rectangle: anObject "Set the value of rectangle" rectangle _ anObject! ! HanoiDisk subclass: #HanoiDiskMorph instanceVariableNames: 'path' classVariableNames: '' poolDictionaries: '' category: 'Cours-Smalltalk-Hanoi'! !HanoiDiskMorph methodsFor: 'mouvements' stamp: 'hw 5/9/2007 12:39'! bougeSur: destination (Delay forMilliseconds: 300) wait. pile := destination pile. rectangle center: destination center - (0 @ (Epaisseur + Separation)). self position: LesPiles position + (destination center - (self extent x / 2 @ (Epaisseur / 2 + Separation))). ! ! !HanoiDiskMorph methodsFor: 'initalisation' stamp: 'hw 5/8/2007 14:02'! initialize super initialize. path := OrderedCollection new! ! !HanoiDiskMorph methodsFor: 'initalisation' stamp: 'hw 5/9/2007 13:23'! width: size pole: pole | ou y | self pile: pole. size >= 1000 ifTrue: [self nom: $m. ou := LesPiles extent x - 100 / 3 * pole - 50 @ (LesPiles extent y - Epaisseur)] ifFalse: ["un disque normal" self nom: (Character value: $A asciiValue + size - 1). y := LesPiles extent y - (LesPiles combien - size + 1 * (Epaisseur + Separation)). ou := LesPiles extent x - 100 / 3 - 50 @ y]. self rectangle: (0 @ 0 extent: size * Largeur @ Epaisseur). self rectangle center: ou. self extent: Largeur * size @ Epaisseur; position: LesPiles position x + ou x - (size * (Largeur / 2)) @ (LesPiles position y + ou y - (Epaisseur / 2 + Separation)) ! ! BorderedMorph subclass: #TourDeHanoi instanceVariableNames: 'piles' classVariableNames: '' poolDictionaries: '' category: 'Cours-Smalltalk-Hanoi'! !TourDeHanoi commentStamp: '' prior: 0! piles est un tableau de piles. chaque pile est une collection ordonnee. les objets qu'on met sur la pile sont des caracteres A est le disque le plus petit, B est plus large, etc addfirst: est le message d'empliement removeFirst est le message de depilement! !TourDeHanoi methodsFor: 'deplacements' stamp: 'hw 4/24/2007 13:17'! deplaceDisque: depart vers: arrivee "deplace un disque et montre le resultat dans le Transcript" | disque | disque := (piles at: depart) removeFirst. (piles at: arrivee) addFirst: disque. Transcript cr; show: 'disque ' , disque printString , ' de ' , depart printString , ' vers ' , arrivee printString.! ! !TourDeHanoi methodsFor: 'deplacements' stamp: 'hw 4/24/2007 13:19'! deplaceTour: hauteur de: depart vers: arrivee utilisant: intermediaire (hauteur > 0) ifTrue: [ self deplaceTour: hauteur - 1 de: depart vers: intermediaire utilisant: arrivee. self deplaceDisque: depart vers: arrivee. self deplaceTour: hauteur - 1 de: intermediaire vers: arrivee utilisant: depart]! ! !TourDeHanoi methodsFor: 'creation' stamp: 'hw 4/24/2007 14:21'! hanoi "TourDeHanoi new hanoi" | uneChaine | uneChaine := FillInTheBlank request: 'SVP, donnez le nombre de disques formant la tour'. uneChaine isEmpty ifTrue: [^nil]. Transcript cr; show: 'La tour de Hanoi pour ' , uneChaine , ' disques:'; cr. piles := (Array new: 3) collect: [:each | OrderedCollection new]. (uneChaine asNumber to: 1 by: -1) do: [:each | (piles at: 1) addFirst: (Character value: $A asciiValue + each - 1)]. self deplaceTour: uneChaine asNumber de: 1 vers: 3 utilisant: 2! ! TourDeHanoi subclass: #TourDeHanoiAnime instanceVariableNames: 'combien disquesVirtuels' classVariableNames: '' poolDictionaries: '' category: 'Cours-Smalltalk-Hanoi'! !TourDeHanoiAnime commentStamp: '' prior: 0! combien - le nombre de disques disquesVirtuels - un tableau de disques inexistants (quand un disque se deplace vers une pile vide, elle se pose sur un disque virtuel)! !TourDeHanoiAnime methodsFor: 'initialisation' stamp: 'hw 4/24/2007 15:09'! initialiseDisques | disk displayBox | HanoiDisk new whichTowers: self. displayBox := 20@100 corner: 380@320. Display fillWhite: displayBox. Display border: displayBox width: 2. piles := (Array new: 3) collect: [:each| OrderedCollection new]. combien to: 1 by: -1 do: [:size | disk := HanoiDisk new width: size pole: 1. (piles at: 1) addFirst: disk. disk invert]. disquesVirtuels := Array new: 3. 1 to: 3 do: [:each| disquesVirtuels at: each put: (HanoiDisk new width: 1000 pole: each)] ! ! !TourDeHanoiAnime methodsFor: 'deplacements' stamp: 'hw 4/24/2007 15:42'! deplaceDisque: depart vers: arrivee | disque support | support := (piles at: arrivee) isEmpty ifFalse: [(piles at: arrivee) first] ifTrue:[disquesVirtuels at: arrivee]. disque := (piles at: depart) removeFirst. (piles at: arrivee) addFirst: disque. disque bougeSur: support. Transcript cr; show: 'disque ' , disque nom printString , ' de ' , depart printString , ' vers ' , arrivee printString.! ! !TourDeHanoiAnime methodsFor: 'deplacements' stamp: 'hw 4/24/2007 15:35'! hanoi "TourDeHanoiAnime new hanoi" | uneChaine | uneChaine := FillInTheBlank request: 'SVP, donnez le nombre de disques formant la tour'. uneChaine isEmpty ifTrue: [^nil]. Transcript cr; show: 'La tour de Hanoi pour ' , uneChaine , ' disques:'. combien := uneChaine asNumber. self initialiseDisques. Display restoreAfter:[ self deplaceTour: combien de: 1 vers: 3 utilisant: 2].! ! !TourDeHanoiAnime methodsFor: 'accessing' stamp: 'hw 4/24/2007 14:37'! combien "Answer the value of combien" ^ combien! ! !TourDeHanoiAnime methodsFor: 'accessing' stamp: 'hw 4/24/2007 14:37'! combien: anObject "Set the value of combien" combien _ anObject! ! !TourDeHanoiAnime methodsFor: 'accessing' stamp: 'hw 4/24/2007 14:37'! disquesVirtuels "Answer the value of disquesVirtuels" ^ disquesVirtuels! ! !TourDeHanoiAnime methodsFor: 'accessing' stamp: 'hw 4/24/2007 14:37'! disquesVirtuels: anObject "Set the value of disquesVirtuels" disquesVirtuels _ anObject! ! TourDeHanoiAnime subclass: #TourDeHanoiAnimeMorph instanceVariableNames: 'menu' classVariableNames: '' poolDictionaries: '' category: 'Cours-Smalltalk-Hanoi'! !TourDeHanoiAnimeMorph methodsFor: 'initialisation' stamp: 'hw 5/8/2007 20:45'! defaultBorderColor ^ Color red ! ! !TourDeHanoiAnimeMorph methodsFor: 'initialisation' stamp: 'hw 5/8/2007 20:45'! defaultBorderWidth ^ 2 ! ! !TourDeHanoiAnimeMorph methodsFor: 'initialisation' stamp: 'hw 5/8/2007 20:46'! defaultBounds ^ (0 @ 0 corner: 400 @ 300). ! ! !TourDeHanoiAnimeMorph methodsFor: 'initialisation' stamp: 'hw 5/8/2007 21:06'! defaultColor ^ Color white! ! !TourDeHanoiAnimeMorph methodsFor: 'initialisation' stamp: 'hw 5/8/2007 19:13'! handlesMouseDown: evt ^evt yellowButtonPressed! ! !TourDeHanoiAnimeMorph methodsFor: 'initialisation' stamp: 'hw 5/9/2007 12:35'! initialiseDisques | disk | self removeAllMorphs. HanoiDiskMorph new whichTowers: self combien: combien. piles := (Array new: 3) collect: [:each| OrderedCollection new]. combien to: 1 by: -1 do: [:size | disk := HanoiDiskMorph new. self addMorph: disk. disk width: size pole: 1. (piles at: 1) addFirst: disk. ]. disquesVirtuels := Array new: 3. 1 to: 3 do: [:each| disk := HanoiDiskMorph new. "disk whichTowers: self." disquesVirtuels at: each put: (disk width: 1000 pole: each)]. ! ! !TourDeHanoiAnimeMorph methodsFor: 'initialisation' stamp: 'hw 5/8/2007 20:50'! initialize super initialize. self openInWorld ! ! !TourDeHanoiAnimeMorph methodsFor: 'menu' stamp: 'hw 5/8/2007 21:11'! mouseDown: evt menu := MenuMorph new defaultTarget: self. menu addTitle: 'La tour de Hanoi'; add: 'nombre de disques' action: #hanoi; addLine; add: 'inspect' action: #inspect; add: 'suicide' action: #suicide; addStayUpItem; popUpAt: Sensor cursorPoint forHand: evt hand in: self world! ! !TourDeHanoiAnimeMorph methodsFor: 'menu' stamp: 'hw 5/8/2007 16:08'! suicide self delete. ^true! ! !TourDeHanoiAnimeMorph methodsFor: 'lancement' stamp: 'hw 5/9/2007 13:30'! hanoi "TourDeHanoiAnimeMorph new " | uneChaine | uneChaine := FillInTheBlank request: 'SVP, donnez le nombre de disques formant la tour' initialAnswer: '4'. uneChaine isEmpty ifTrue: [^nil]. Transcript cr; show: 'La tour de Hanoi pour ' , uneChaine , ' disques:'. combien := uneChaine asNumber. self initialiseDisques. self comeToFront. self deplaceTour: combien de: 1 vers: 3 utilisant: 2 ! ! !Rectangle methodsFor: 'pour Hanoi' stamp: 'hw 4/24/2007 14:48'! center: unPoint | extent | extent := corner - origin. origin := unPoint - (extent // 2). corner := origin + extent! !