BlockClosure extend [ valueWithExit [ self value: [^self] ] ]
Integer extend [
<< x [ ^ self bitShift: x ]
>> x [ ^ self bitShift: x negated ]
]
| readline player board pattern |
readline := [
| ax a |
ax := stdin nextLine. ax displayNl.
a := 0.
(ax ~= nil and: [ax size = 1]) ifTrue: [a := '123' indexOf: ax first].
a
].
player := 0.
board := 0.
pattern := #(86016 1344 21 66576 16644 4161 65793 4368).
[:exit | [((board radix: 2) count: [:x | x = $1]) < 9] whileTrue: [
| pnt point |
('[', player printString, ' turn]') displayNl.
8 to: 0 by: -1 do: [:i |
('.ox' at: ((board >> (i * 2)) bitAnd: 2r11) + 1) display. "2r00 = $. / 2r01 = $o / 2r11 = $x"
i \\ 3 = 0 ifTrue: ['' displayNl].
].
pnt := 0 @ 0.
[pnt x < 1] whileTrue: ['x?' display. pnt := readline value @ pnt y].
[pnt y < 1] whileTrue: ['y?' display. pnt := pnt x @ readline value].
point := (2r1 << (6 * (3 - pnt y)) << ((3 - pnt x) * 2)) << player.
((board bitAnd: point) = 0 and: [(board >> (1 - player) bitAnd: point >> player) = 0]) ifTrue: [
board := board bitOr: point.
(pattern findFirst: [:x | (x bitAnd: (board >> player)) = x]) ~= 0 ifTrue: [('', player printString, ' won!') displayNl. exit value].
player := player bitXor: 1
]
]] valueWithExit.
'game end' displayNl
QmxvY2tDbG9zdXJlIGV4dGVuZCBbIHZhbHVlV2l0aEV4aXQgWyBzZWxmIHZhbHVlOiBbXnNlbGZdIF0gXQoKSW50ZWdlciBleHRlbmQgWwogICA8PCB4IFsgXiBzZWxmIGJpdFNoaWZ0OiB4IF0KICAgPj4geCBbIF4gc2VsZiBiaXRTaGlmdDogeCBuZWdhdGVkIF0KXQoKfCByZWFkbGluZSBwbGF5ZXIgYm9hcmQgcGF0dGVybiB8CgpyZWFkbGluZSA6PSBbCiAgIHwgYXggYSB8CiAgIGF4IDo9IHN0ZGluIG5leHRMaW5lLiBheCBkaXNwbGF5TmwuCiAgIGEgOj0gMC4KICAgKGF4IH49IG5pbCBhbmQ6IFtheCBzaXplID0gMV0pIGlmVHJ1ZTogW2EgOj0gJzEyMycgaW5kZXhPZjogYXggZmlyc3RdLgogICBhCl0uCgpwbGF5ZXIgOj0gMC4KYm9hcmQgOj0gMC4KcGF0dGVybiA6PSAjKDg2MDE2IDEzNDQgMjEgNjY1NzYgMTY2NDQgNDE2MSA2NTc5MyA0MzY4KS4KCls6ZXhpdCB8IFsoKGJvYXJkIHJhZGl4OiAyKSBjb3VudDogWzp4IHwgeCA9ICQxXSkgPCA5XSB3aGlsZVRydWU6IFsKICAgfCBwbnQgcG9pbnQgfAogICAoJ1snLCBwbGF5ZXIgcHJpbnRTdHJpbmcsICcgdHVybl0nKSBkaXNwbGF5TmwuCgogICA4IHRvOiAwIGJ5OiAtMSBkbzogWzppIHwKICAgICAgKCcub3gnIGF0OiAoKGJvYXJkID4+IChpICogMikpIGJpdEFuZDogMnIxMSkgKyAxKSBkaXNwbGF5LiAiMnIwMCA9ICQuIC8gMnIwMSA9ICRvIC8gMnIxMSA9ICR4IgogICAgICBpIFxcIDMgPSAwIGlmVHJ1ZTogWycnIGRpc3BsYXlObF0uCiAgIF0uCgogICBwbnQgOj0gMCBAIDAuCiAgIFtwbnQgeCA8IDFdIHdoaWxlVHJ1ZTogWyd4PycgZGlzcGxheS4gcG50IDo9IHJlYWRsaW5lIHZhbHVlIEAgcG50IHldLgogICBbcG50IHkgPCAxXSB3aGlsZVRydWU6IFsneT8nIGRpc3BsYXkuIHBudCA6PSBwbnQgeCBAIHJlYWRsaW5lIHZhbHVlXS4KCiAgIHBvaW50IDo9ICgycjEgPDwgKDYgKiAoMyAtIHBudCB5KSkgPDwgKCgzIC0gcG50IHgpICogMikpIDw8IHBsYXllci4KICAgKChib2FyZCBiaXRBbmQ6IHBvaW50KSA9IDAgYW5kOiBbKGJvYXJkID4+ICgxIC0gcGxheWVyKSBiaXRBbmQ6IHBvaW50ID4+IHBsYXllcikgPSAwXSkgaWZUcnVlOiBbCiAgICAgIGJvYXJkIDo9IGJvYXJkIGJpdE9yOiBwb2ludC4KICAgICAgKHBhdHRlcm4gZmluZEZpcnN0OiBbOnggfCAoeCBiaXRBbmQ6IChib2FyZCA+PiBwbGF5ZXIpKSA9IHhdKSB+PSAwIGlmVHJ1ZTogWygnJywgcGxheWVyIHByaW50U3RyaW5nLCAnIHdvbiEnKSBkaXNwbGF5TmwuIGV4aXQgdmFsdWVdLgogICAgICBwbGF5ZXIgOj0gcGxheWVyIGJpdFhvcjogMQogICBdCl1dIHZhbHVlV2l0aEV4aXQuCgonZ2FtZSBlbmQnIGRpc3BsYXlObAo=