Life

Started by cormullion, July 21, 2007, 10:51:42 AM

Previous topic - Next topic

cormullion

My first attempt at something longer than a clock...:-)  Improvements and corrections welcomed!


#!/usr/bin/newlisp

(set 'rows 30 'cols 30 'cell-size 20 'cell-radius 10)

(define (new-world)
(seed (date-value))
(set '*world* (array rows cols (rand 2 124)))
(set '*generation-counter* 0))

(define (cell-lives? r c)
(and
(< r rows)
(< c cols)
(not (< r 0)) ; fool the forum software
(not (< c 0)) ; which doesn't like certain angle brackets
(> (*world* r c) 0)))

(define (generation)
(let
((next-world (array rows cols '(0)))
(changed nil)
(r 0)
(c 0)
(neighbours 0)
(old-state 0)
(new-state 0))
(for (r 0 (- rows 1))
(for (c 0 (- cols 1))
(set 'neighbours 0)
(if (cell-lives? (- r 1)   (- c 1)) (inc 'neighbours))
(if (cell-lives? (- r 1)  c) (inc 'neighbours))
(if (cell-lives? (- r 1) (+ c 1)) (inc 'neighbours))
(if (cell-lives? r (- c 1)) (inc 'neighbours))
(if (cell-lives? r (+ c 1)) (inc 'neighbours))
(if (cell-lives? (+ r 1)   (- c 1)) (inc 'neighbours))
(if (cell-lives? (+ r 1) c) (inc 'neighbours))
(if (cell-lives? (+ r 1)   (+ c 1)) (inc 'neighbours))
(set 'old-state (*world* r c))
(set 'new-state
(or
(and (= old-state 0) (= neighbours 3))
(and (= old-state 1 ) (or (= neighbours 2) (= neighbours 3)))))
(if new-state (set 'new-state 1) (set 'new-state 0))
(if (and
(= changed nil)
(!= new-state old-state))
(set 'changed true))
(nth-set (next-world r c) new-state)) ; cols
) ; rows
(set '*world* next-world)
(set 'next-world '())
changed)
)

(if (= ostype "Win32")
    (load (string (env "PROGRAMFILES") "/newlisp/guiserver.lsp"))
    (load "/usr/share/newlisp/guiserver.lsp")
)

(define (draw-world)
(let ((r 0)
(c 0))
(for (r 0 (- rows 1))
(for (c 0 (- cols 1))
(if (= (*world* r c) 0)
(gs:hide-tag (string Cell r c))
(gs:show-tag (string Cell r c))
)))))

(gs:init)
(gs:frame 'ConwayLife 100 100 640 640 "Life")
(gs:set-border-layout 'ConwayLife )
(gs:canvas 'MyCanvas 'ConwayLife)
(gs:panel 'Panel)
(gs:label 'T " ")
(gs:button 'Restart 'restart-button-action "restart")

(gs:add-to 'Panel 'Restart 'T)
(gs:add-to 'ConwayLife 'MyCanvas "center" 'Panel "south")

(gs:set-background 'MyCanvas '(.8 .9 .7 .8))
(gs:set-anti-aliasing true)
(gs:set-visible 'ConwayLife true)

; move down so that you can see the blobs properly

(gs:set-translation (/ cell-size 2) (/ cell-size 2) )

(new-world)

(for (r 0 (- rows 1))
(for (c 0 (- cols 1))
(gs:fill-circle (string Cell r c)
(* c cell-size)
(* r cell-size)
cell-radius
'(.2 .5 .4 ))))

(define (restart-button-action)
(new-world))

(while (gs:check-event 10000)
(draw-world)
(generation)
(gs:set-text 'T (string {generation } (inc '*generation-counter*))))

(exit)




There are some places where odd (probably wrong) things happen. I don't mind this, because it makes life more interesting but purists may want to find and fix the mistakes!

Lutz

#1
... copy/pasted it in, hit run ... beautiful,



Lutz

cormullion

#2
Is this the code for opening an image in a frame chosen from a dialog? I can't find enough examples to get it working ... :-)


(gs:init)

(map set '(width height) (gs:get-screen))
(set 'window-width 1000 'window-height 600)

(gs:window 'Screen 0 50 window-width window-height)
(gs:set-background 'Screen 0 0 0 0)

(gs:frame 'Dialog 40 40 300 300)
(gs:set-border-layout 'Dialog 0 0)
(gs:add-to 'Screen 'Dialog)

(define (openfile-action id op file)
(if file
(begin
(set 'current-path (base64-dec file))
(gs:draw-image 'I current-path 0 0 window-width window-height)
)
)
)

(gs:open-file-dialog 'Dialog 'openfile-action)

(gs:listen)






sorry posted in wrong topic again... :-)

m i c h a e l

#3
Hi cormullion!



Two observations to get you pointed in the right direction:



1. gs:draw-image is used to draw onto a gs:canvas.



2. gs:draw-image is being applied to 'I, which is undefined.



m i c h a e l

cormullion

#4
thanks! got it working now.



Also, I tried making the window visible! (;-) I've been forgetting that windows are invisible by default.



for the record, the code is now:


(gs:init)
(map set '(width height) (gs:get-screen))
(gs:frame 'Screen 0 50 width height)
(gs:canvas 'MyCanvas)
(gs:frame 'Dialog 40 40 300 300)
(gs:open-file-dialog 'Dialog 'openfile-action (env "$HOME") ".jpg .png" "Image files")
(gs:add-to 'Screen 'Dialog 'MyCanvas)
(gs:set-visible 'Screen true)
(define
  (openfile-action id op file)
  (if file
    (begin
      (set 'current-path
        (base64-dec file))
      (gs:draw-image 'I current-path 0 0 width height))))
(gs:listen)


The main problem now is the non-proportional scaling of the image - I'll have to scale it either to full width or full height. I'm going to have to think about this after another cup of coffee...