Skip to content

Instantly share code, notes, and snippets.

@KazunoriUeda
Created August 21, 2019 09:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KazunoriUeda/5fb8be0a6b69001f19d047e9bf23b695 to your computer and use it in GitHub Desktop.
Save KazunoriUeda/5fb8be0a6b69001f19d047e9bf23b695 to your computer and use it in GitHub Desktop.
SmalltalkJenga.st v1.0.2
'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 ].
! !
'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