Created
August 21, 2019 09:46
-
-
Save KazunoriUeda/5fb8be0a6b69001f19d047e9bf23b695 to your computer and use it in GitHub Desktop.
SmalltalkJenga.st v1.0.2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'From Pharo8.0.0 of 8 July 2019 [Build information: Pharo-8.0.0+build.450.sha.e47b98dafd309b7ce3e20a7660a4bddbbc5ec789 (64 Bit)] on 31 July 2019 at 9:00:02.084138 pm'! | |
RSGridLayout subclass: #RSJengaLayout | |
instanceVariableNames: 'maxLineWidth' | |
classVariableNames: '' | |
package: 'SmalltalkJenga'! | |
!RSJengaLayout methodsFor: 'accessing' stamp: 'KazunoriUeda 7/31/2019 19:44'! | |
maxLineWidth: anObject | |
maxLineWidth := anObject! ! | |
!RSJengaLayout methodsFor: 'accessing' stamp: 'KazunoriUeda 7/31/2019 19:44'! | |
maxLineWidth | |
^ maxLineWidth ifNil: [ maxLineWidth := self defaultMaxLineWidth ]! ! | |
!RSJengaLayout methodsFor: 'defaults' stamp: 'KazunoriUeda 7/31/2019 20:26'! | |
defaultMaxLineWidth | |
^ 2000! ! | |
!RSJengaLayout methodsFor: 'hook' stamp: 'KazunoriUeda 7/31/2019 20:30'! | |
doExecute: elements | |
| pointer maxLastLineHeight originalGapLeft originalGapTop currentLineWidth | | |
originalGapLeft := 0. | |
originalGapTop := 0. | |
pointer := originalGapLeft @ originalGapTop. | |
maxLastLineHeight := 0. | |
currentLineWidth := pointer x. | |
elements | |
do: [ :element | | |
translator translateTopLeftOf: element to: pointer. | |
currentLineWidth := (currentLineWidth + element width + self gapSize). | |
pointer := (pointer x + element width + self gapSize) @ pointer y. | |
maxLastLineHeight := maxLastLineHeight max: element height. | |
currentLineWidth >= self maxLineWidth | |
ifTrue: [ | |
pointer := originalGapLeft @ (pointer y + (self gapSize) + maxLastLineHeight). | |
currentLineWidth := pointer x. | |
maxLastLineHeight := 0. | |
translator translateTopLeftOf: element to: pointer. | |
currentLineWidth := (currentLineWidth + element width + self gapSize). | |
pointer := (pointer x + element width + self gapSize) @ pointer y. | |
maxLastLineHeight := maxLastLineHeight max: element height. | |
currentLineWidth >= self maxLineWidth | |
]. | |
self step ]. | |
! ! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'From Pharo8.0.0 of 8 July 2019 [Build information: Pharo-8.0.0+build.450.sha.e47b98dafd309b7ce3e20a7660a4bddbbc5ec789 (64 Bit)] on 31 July 2019 at 8:59:56.782315 pm'! | |
Object subclass: #SmalltalkJenga | |
instanceVariableNames: 'random turn score mode view elements' | |
classVariableNames: '' | |
package: 'SmalltalkJenga'! | |
!SmalltalkJenga methodsFor: 'testing' stamp: 'KazunoriUeda 7/18/2019 18:42'! | |
isPlayMode | |
^ self mode = 'play'! ! | |
!SmalltalkJenga methodsFor: 'testing' stamp: 'KazunoriUeda 7/18/2019 18:42'! | |
isReplayMode | |
^ self mode = 'replay'! ! | |
!SmalltalkJenga methodsFor: 'actions' stamp: 'KazunoriUeda 7/10/2019 18:59'! | |
finish | |
DialogWindow new title: 'Awesome!! All classes are deleted!!!!!!'; openModal! ! | |
!SmalltalkJenga methodsFor: 'actions' stamp: 'KazunoriUeda 7/12/2019 19:06'! | |
play | |
self chooseAndDeleteFrom: (self randomList: 10)! ! | |
!SmalltalkJenga methodsFor: 'actions' stamp: 'KazunoriUeda 7/18/2019 18:47'! | |
chooseAndDeleteFrom: aList | |
(0 < self listSize) | |
ifTrue: [ | |
| target | | |
self turn: (self turn) + 1. | |
target := self chooseTargetFrom: aList. | |
target ifNil: [ self turn: (self turn) - 1. ^self ]. | |
self delete: target. | |
] | |
ifFalse: [ self finish ]! ! | |
!SmalltalkJenga methodsFor: 'actions' stamp: 'KazunoriUeda 7/18/2019 18:37'! | |
playMode | |
self mode: 'play'! ! | |
!SmalltalkJenga methodsFor: 'actions' stamp: 'KazunoriUeda 12/19/2018 18:00'! | |
playAll | |
[ self play ] doWhileTrue: [ 0 < (self listSize) ]. | |
! ! | |
!SmalltalkJenga methodsFor: 'actions' stamp: 'KazunoriUeda 7/10/2019 19:03'! | |
chooseTarget | |
^ PopupChoiceDialogWindow chooseFrom: (self randomList: 10) | |
lines: #() | |
title: ('Turn {1} (classes: {2}, score: {3})' format: {self turn asString. self classList size asString. self score asString})! ! | |
!SmalltalkJenga methodsFor: 'actions' stamp: 'KazunoriUeda 7/10/2019 19:01'! | |
addScore: anInteger | |
self score: (self score) + anInteger.! ! | |
!SmalltalkJenga methodsFor: 'actions' stamp: 'KazunoriUeda 7/18/2019 18:37'! | |
replayMode | |
self mode: 'replay'! ! | |
!SmalltalkJenga methodsFor: 'actions' stamp: 'KazunoriUeda 7/18/2019 19:09'! | |
flashOnDelete | |
3 timesRepeat: [ Display flash: (0@0 corner: 3000@2000) andWait: 100 ] | |
! ! | |
!SmalltalkJenga methodsFor: 'actions' stamp: 'KazunoriUeda 7/31/2019 20:59'! | |
playWithRoassal | |
| boxShape clickableBoxShape| | |
self view: RSView new. | |
boxShape := RSShapeBuilder rectangle | |
color: [ :cls | | |
| val | | |
val := 1 / ((cls methodDict size * 0.05) + 1). | |
Color lightBrown alphaMixed: val with: Color red ]; | |
width: [ :cls | (((cls allSubclasses size) / 20) * 2) max: 50 ]; | |
height: 40. | |
clickableBoxShape := RSShapeBuilder composite | |
interactionDo: #popup; | |
shapes: [ :aClass | | |
| element group | | |
group := TSGroup new. | |
element := (boxShape elementOn: aClass). | |
element when: TSMouseClick do: [ :e | self chooseAndDeleteFrom: { aClass } ]. | |
group add: element. | |
group | |
]. | |
self elements: (clickableBoxShape elementsOn: self classList). | |
self view addAll: self elements. | |
RSJengaLayout on: self elements. | |
self view @ RSControlsView. | |
self view open! ! | |
!SmalltalkJenga methodsFor: 'actions' stamp: 'KazunoriUeda 7/18/2019 18:47'! | |
delete: target | |
| deletionScore deleteClassName | | |
deletionScore := '-'. | |
self isReplayMode ifTrue: [ | |
deletionScore := self class calculateDeletionScoreOf: target. | |
Transcript cr; show: deletionScore asString. | |
self addScore: deletionScore. ]. | |
self flashOnDelete. | |
deleteClassName := target asString. | |
self deleteRecursive: target. | |
DialogWindow new title: ('The class {1} has deleted!! (deletion score:{2}) ' format: {deleteClassName. deletionScore asString}); openModal. | |
! ! | |
!SmalltalkJenga methodsFor: 'actions' stamp: 'KazunoriUeda 7/12/2019 19:04'! | |
chooseTargetFrom: aList | |
^ PopupChoiceDialogWindow chooseFrom: aList | |
lines: #() | |
title: ('Turn {1} (classes: {2}, score: {3})' format: {self turn asString. self classList size asString. self score asString})! ! | |
!SmalltalkJenga methodsFor: 'actions' stamp: 'KazunoriUeda 7/18/2019 19:07'! | |
deleteRecursive: aClass | |
| classList | | |
classList := { aClass asString } asOrderedCollection. | |
aClass allSubclassesDo: [ :subclass | classList add: subclass asString. | |
self view ifNotNil: [ :v | | |
(self elementBy: subclass) ifNotNil: [ :e | v removeElement: e ]. | |
]. | |
]. | |
self view ifNotNil: [ :v | | |
(self elementBy: aClass) ifNotNil: [ :e | v removeElement: e ]. | |
]. | |
"aClass asString removeFromSystem." | |
^ classList | |
! ! | |
!SmalltalkJenga methodsFor: 'actions' stamp: 'KazunoriUeda 7/12/2019 19:05'! | |
play: candidateList | |
(0 < self listSize) | |
ifTrue: [ | |
| target | | |
self turn: (self turn) + 1. | |
target := self chooseTargetFrom: candidateList. | |
target ifNil: [ self turn: (self turn) - 1. ^self ]. | |
self delete: target. | |
] | |
ifFalse: [ self finish ]! ! | |
!SmalltalkJenga methodsFor: 'initialize' stamp: 'KazunoriUeda 7/18/2019 18:46'! | |
initialize | |
random := nil. | |
turn := 0. | |
score := 0. | |
view := nil. | |
elements := nil. | |
self playMode.! ! | |
!SmalltalkJenga methodsFor: 'accessing' stamp: 'KazunoriUeda 12/19/2018 18:00'! | |
random: anObject | |
random := anObject! ! | |
!SmalltalkJenga methodsFor: 'accessing' stamp: 'KazunoriUeda 7/18/2019 18:00'! | |
elements: anObject | |
elements := anObject! ! | |
!SmalltalkJenga methodsFor: 'accessing' stamp: 'KazunoriUeda 12/19/2018 18:00'! | |
turn | |
^ turn! ! | |
!SmalltalkJenga methodsFor: 'accessing' stamp: 'KazunoriUeda 12/19/2018 18:00'! | |
listSize | |
^ self classList size! ! | |
!SmalltalkJenga methodsFor: 'accessing' stamp: 'KazunoriUeda 7/10/2019 18:57'! | |
score | |
^ score! ! | |
!SmalltalkJenga methodsFor: 'accessing' stamp: 'KazunoriUeda 7/18/2019 18:36'! | |
mode: anObject | |
mode := anObject! ! | |
!SmalltalkJenga methodsFor: 'accessing' stamp: 'KazunoriUeda 6/11/2019 09:29'! | |
randomIndex | |
^ self randomIndex: self listSize! ! | |
!SmalltalkJenga methodsFor: 'accessing' stamp: 'KazunoriUeda 7/10/2019 13:44'! | |
classList | |
^ Smalltalk globals allClasses reject: [ :each | each = self class ]! ! | |
!SmalltalkJenga methodsFor: 'accessing' stamp: 'KazunoriUeda 12/19/2018 18:00'! | |
turn: anObject | |
turn := anObject! ! | |
!SmalltalkJenga methodsFor: 'accessing' stamp: 'KazunoriUeda 7/10/2019 18:57'! | |
score: anObject | |
score := anObject! ! | |
!SmalltalkJenga methodsFor: 'accessing' stamp: 'KazunoriUeda 7/18/2019 18:14'! | |
elementBy: aClass | |
^ self elements detect: [ :e | e model = aClass ] ifNone: [ ]! ! | |
!SmalltalkJenga methodsFor: 'accessing' stamp: 'KazunoriUeda 7/18/2019 18:00'! | |
elements | |
^ elements! ! | |
!SmalltalkJenga methodsFor: 'accessing' stamp: 'KazunoriUeda 7/12/2019 19:02'! | |
randomList: anInteger | |
| resultList tmpList | | |
resultList := OrderedCollection new. | |
tmpList := self classList deepCopy. | |
(anInteger min: tmpList size) | |
timesRepeat: [ resultList add: (tmpList removeAt: (self randomIndex: tmpList size)) ]. | |
^ resultList! ! | |
!SmalltalkJenga methodsFor: 'accessing' stamp: 'KazunoriUeda 7/18/2019 18:00'! | |
view: anObject | |
view := anObject! ! | |
!SmalltalkJenga methodsFor: 'accessing' stamp: 'KazunoriUeda 7/18/2019 18:36'! | |
mode | |
^ mode! ! | |
!SmalltalkJenga methodsFor: 'accessing' stamp: 'KazunoriUeda 12/19/2018 18:00'! | |
random | |
^ random ifNil: [ random := Random seed: (DateAndTime now asUnixTime) ]! ! | |
!SmalltalkJenga methodsFor: 'accessing' stamp: 'KazunoriUeda 6/11/2019 09:28'! | |
randomIndex: anInteger | |
^ self random nextInt: anInteger! ! | |
!SmalltalkJenga methodsFor: 'accessing' stamp: 'KazunoriUeda 7/18/2019 18:00'! | |
view | |
^ view! ! | |
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! | |
SmalltalkJenga class | |
instanceVariableNames: 'default'! | |
!SmalltalkJenga class methodsFor: 'class initialization' stamp: 'KazunoriUeda 12/19/2018 18:00'! | |
initialize | |
default := nil! ! | |
!SmalltalkJenga class methodsFor: 'calculating' stamp: 'KazunoriUeda 7/17/2019 16:34'! | |
calculateDeletionScoreOf: aClass | |
| locScore instVarScore instMethodScore classVarScore classMethodScore refScore subClassesScore deletionScore | | |
locScore := aClass linesOfCode. | |
instVarScore := aClass instVarNames size. | |
instMethodScore := aClass methodDict size. | |
classVarScore := aClass classVariables size. | |
classMethodScore := aClass classClass methodDict size. | |
refScore := ((aClass allInstances collect: [ :e | e pointersTo size ]) sumNumbers) + (aClass pointersTo size). | |
subClassesScore := (aClass subclasses collect: [ :subClass | self calculateDeletionScoreOf: subClass ]) sumNumbers. | |
Transcript cr | |
; show: ('Class Name : {1}' format: { aClass asString }); cr | |
; show: ('LOC : {1}' format: { aClass linesOfCode asString }); cr | |
; show: ('Instance Variables : {1}' format: { aClass instVarNames size asString }); cr | |
; show: ('Instance Methods : {1}' format: { aClass methodDict size asString }); cr | |
; show: ('Class Variables : {1}' format: { aClass classVariables size asString }); cr | |
; show: ('Class Methods : {1}' format: { aClass classClass methodDict size asString}); cr | |
; show: ('Instance Refs : {1}' format: { (aClass allInstances collect: [ :e | e pointersTo size ]) sumNumbers asString }); cr | |
; show: ('Class Refs : {1}' format: { aClass pointersTo size asString }); cr | |
; show: ('Subclasses : {1}' format: { aClass subclasses size asString }); cr | |
. | |
deletionScore := | |
(locScore * 1) | |
+ (instVarScore * 2) | |
+ (instMethodScore * 3) | |
+ (classVarScore * 4) | |
+ (classMethodScore * 6) | |
+ (refScore * 10) | |
+ (subClassesScore * 1) | |
. | |
^ deletionScore! ! | |
!SmalltalkJenga class methodsFor: 'instance creation' stamp: 'KazunoriUeda 12/19/2018 18:00'! | |
default | |
default ifNil: [default := self new]. | |
^default! ! | |
!SmalltalkJenga class methodsFor: 'actions' stamp: 'KazunoriUeda 7/18/2019 18:49'! | |
playMode | |
self default playMode! ! | |
!SmalltalkJenga class methodsFor: 'actions' stamp: 'KazunoriUeda 7/16/2019 10:20'! | |
playWithRoassal | |
<script> | |
self default playWithRoassal! ! | |
!SmalltalkJenga class methodsFor: 'actions' stamp: 'KazunoriUeda 7/16/2019 10:20'! | |
playAll | |
<script> | |
self default playAll! ! | |
!SmalltalkJenga class methodsFor: 'actions' stamp: 'KazunoriUeda 7/16/2019 10:21'! | |
play | |
<script> | |
self default play! ! | |
!SmalltalkJenga class methodsFor: 'actions' stamp: 'KazunoriUeda 7/18/2019 18:49'! | |
replayMode | |
self default replayMode! ! | |
SmalltalkJenga initialize! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment