From: david
Subject: please review my code
Date: 
Message-ID: <aafc3418-927c-49c7-9fbd-90b757b52483@b16g2000yqb.googlegroups.com>
not quite there yet, but no more global variables :)
thanks, david

;;;; get a legal chess position with white king, knight, and bishop
;;;; and black king.

(defclass chessboard ()
  ((board-position :accessor state
	           :initform (make-array '(8 8) :initial-element '0))))

(defmethod put-piece ((board chessboard) x y p)
  (setf (aref (state board) x y) p))

(defun get-four-unique-random-numbers ()
  (loop
     :with results = '()
     :for alea = (random 64)
     :while (< (length results) 4)
     :do (pushnew alea results)
     :finally (return results)))

(defun rank-file (position)
  (multiple-value-bind (quotient remainder)
                       (truncate position 8)
    (list  quotient  remainder)))

(defun reverse-rank-file (lst)
  (let ((x (first lst))
	(y (second lst)))
    (+ y (* 8 x))))

(defun get-positions ()
  (mapcar #'rank-file (get-four-unique-random-numbers )))

(defun neighbor (x)
  (list (1- x) x (1+x)))

(defun bad-squares (wk)
  (let ((bad-squares (loop for x in (neighbor (first wk))
		      append (loop for y in (neighbor (second wk))
				collect (list x y)))))
   badsquares))

(defun illegalp (wk bk)
  (member (reverse-rank-file bk)
	  (mapcar #'reverse-rank-file (bad-squares wk))))

From: William James
Subject: Re: please review my code
Date: 
Message-ID: <godvkg0rri@enews4.newsguy.com>
david wrote:

> 
> (defun get-four-unique-random-numbers ()
>   (loop
>      :with results = '()
>      :for alea = (random 64)
>      :while (< (length results) 4)
>      :do (pushnew alea results)
>      :finally (return results)))

Do you pride yourself on your verbosity?  On your pompous,
pretentious prolixity?  Do you aspire to be a politician?
Then you have surely picked the right language:
COBOL LISP!  Congratulations!


Clojure:

(defn four-rand [] (take 4 (distinct (repeatedly rand))))


A purely functional approach in OCaml:

open List

let rec four_rand list =
  if (length list) = 4  then  list
  else  let rnd = (Random.float 1.0) in
    four_rand (if (mem rnd list)  then  list
      else  (rnd :: list)) ;;
From: ·········@yahoo.com
Subject: Re: please review my code
Date: 
Message-ID: <a1dad89f-2037-49b1-be3e-2b761091ef0a@y13g2000yqn.googlegroups.com>
On Mar 1, 6:38 am, "William James" <·········@yahoo.com> wrote:

> Clojure:
>
> (defn four-rand [] (take 4 (distinct (repeatedly rand))))

(defn four-rand [] (take 4 (distinct (repeatedly #(rand-int 64)))))
From: Kenneth Tilton
Subject: Re: please review my code
Date: 
Message-ID: <49aab959$0$5925$607ed4bc@cv.net>
William James wrote:
> david wrote:
> 
>> (defun get-four-unique-random-numbers ()
>>   (loop
>>      :with results = '()
>>      :for alea = (random 64)
>>      :while (< (length results) 4)
>>      :do (pushnew alea results)
>>      :finally (return results)))
> 
> Do you pride yourself on your verbosity?  On your pompous,
> pretentious prolixity?  ....

Niiiice demonstration of self-reference. But you have homework to do, 
ruby biatch. Get your sorry ass over to 23b and get to work.

hth,kenny
From: William James
Subject: Re: please review my code
Date: 
Message-ID: <goe3i40u8e@enews4.newsguy.com>
david wrote:

> (defun rank-file (position)
>   (multiple-value-bind (quotient remainder)
>                        (truncate position 8)
>     (list  quotient  remainder)))

The abililty to puff up a trivial task into such
grandiose proportions must give one a very pleasant
sense of self-satisfaction.  My hat's off to COBOL-LISP
and its revered, august, and sainted sires.


Ruby:

def rank_file position
  position.divmod 8
end
    ==>nil
rank_file 23
    ==>[2, 7]
From: david
Subject: Re: please review my code
Date: 
Message-ID: <e5a8cc19-60ca-4252-b383-b7b789a96407@b16g2000yqb.googlegroups.com>
On Mar 1, 7:45 am, "William James" <·········@yahoo.com> wrote:
> Ruby:
>
> def rank_file position
>   position.divmod 8
> end
>     ==>nil
> rank_file 23
>     ==>[2, 7]

here is my entire program in fruitloopio, a powerful
symfunctional, cross-paradigmatic, all-purpose, self-
rising language of my own devising.

(d0 #9 for ok..

(ok this actually implements 4d chess, like on star wars.)
notice the incredible expressive power of fruitloopio.
only twelve characters!
alas, i am trying to write a program in common lisp, which
is a completely different language. thanks anyhows.

-david
From: William James
Subject: Re: please review my code
Date: 
Message-ID: <goe4240uki@enews4.newsguy.com>
david wrote:

> (defun get-positions ()
>   (mapcar #'rank-file (get-four-unique-random-numbers )))

What the #' is that #' for?
What spiky, bristly, hideous cacti!


Clojure:

(defn get-positions [] (map rank-file (four-rand)))
From: Thomas Munro
Subject: Re: please review my code
Date: 
Message-ID: <c941bea1-800f-41f9-a0da-00a847652513@r27g2000vbp.googlegroups.com>
On Mar 1, 1:54 pm, "William James" <·········@yahoo.com> wrote:
> david wrote:
> > (defun get-positions ()
> >   (mapcar #'rank-file (get-four-unique-random-numbers )))
>
> What the #' is that #' for?
> What spiky, bristly, hideous cacti!

http://www.dreamsongs.com/Separation.html

Short version: Lisp dialects whose creators wanted backward
compatibility with a chain of dialects that started with LISP1.5 have
'function' cells which are distinct from 'value' cells, and therefore
need special evaluation rules for operators, and FUNCALL.  The rest
(for example Scheme, Clojure and Arc) don't bother with the cacti.
After initially reacting the same way as you, this 21st century Lisp
arriviste decided it was worth accepting in order to use SBCL and
Emacs since they kick ass.

Although I suspect you already knew that.

Are there any non-Lisp functional languages that have a separate
function namespace?
From: Pascal Costanza
Subject: Re: please review my code
Date: 
Message-ID: <70vvhnFip6beU1@mid.individual.net>
Thomas Munro wrote:
> On Mar 1, 1:54 pm, "William James" <·········@yahoo.com> wrote:
>> david wrote:
>>> (defun get-positions ()
>>>   (mapcar #'rank-file (get-four-unique-random-numbers )))
>> What the #' is that #' for?
>> What spiky, bristly, hideous cacti!
> 
> http://www.dreamsongs.com/Separation.html
> 
> Short version: Lisp dialects whose creators wanted backward
> compatibility with a chain of dialects that started with LISP1.5 have
> 'function' cells which are distinct from 'value' cells, and therefore
> need special evaluation rules for operators, and FUNCALL.  The rest
> (for example Scheme, Clojure and Arc) don't bother with the cacti.
> After initially reacting the same way as you, this 21st century Lisp
> arriviste decided it was worth accepting in order to use SBCL and
> Emacs since they kick ass.
> 
> Although I suspect you already knew that.
> 
> Are there any non-Lisp functional languages that have a separate
> function namespace?

I heard that Erlang has separate namespaces (but don't know for sure).


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: William James
Subject: Re: please review my code
Date: 
Message-ID: <gofanf02f34@enews2.newsguy.com>
Having separate "value cells" and "function cells" (to use the "street
language" way of saying it) was one of the most unfortuanate issues.
We did not want to break pre-existing programs that had a global
variable named "foo" and a global function named "foo" that were
distinct.  We at Symbolics were forced to insist on this, in the face
of everyone's knowing that it was not what we would have done absent
compatibility constraints. It's hard for me to remember all the
specific things like this, but if we had had fewer compatibility
issues, I think it would have come out looking more like Scheme in
general.  ---  Daniel Weinreb, 24 Feb 2003
From: William James
Subject: Re: please review my code
Date: 
Message-ID: <goe4720un0@enews4.newsguy.com>
david wrote:

> (defun neighbor (x)
>   (list (1- x) x (1+x)))

Before you proudly preen and post your code, do you
ever think of testing it at least once?
From: david
Subject: Re: please review my code
Date: 
Message-ID: <05cb99e5-cf2c-48c4-820f-42bc7af9fb31@l39g2000yqn.googlegroups.com>
On Mar 1, 7:56 am, "William James" <·········@yahoo.com> wrote:
> david wrote:
> > (defun neighbor (x)
> >   (list (1- x) x (1+x)))
>
> Before you proudly preen and post your code, do you
> ever think of testing it at least once?

it was working (sort of) when i posted it.
i blame the google for mangling my code.
i am not proud.
From: William James
Subject: Re: please review my code
Date: 
Message-ID: <goe54g0v9l@enews4.newsguy.com>
david wrote:

> (defun bad-squares (wk)
>   (let ((bad-squares (loop for x in (neighbor (first wk))
> 		      append (loop for y in (neighbor (second wk))
> 				collect (list x y)))))
>    badsquares))

"badsquares" is defined nowhere.

Untested code.
From: Marco Antoniotti
Subject: Re: please review my code
Date: 
Message-ID: <385ae6f2-ea6b-436f-8673-b90cf25e8b66@j8g2000yql.googlegroups.com>
On Mar 1, 3:12 pm, "William James" <·········@yahoo.com> wrote:
> david wrote:
> > (defun bad-squares (wk)
> >   (let ((bad-squares (loop for x in (neighbor (first wk))
> >                  append (loop for y in (neighbor (second wk))
> >                            collect (list x y)))))
> >    badsquares))
>
> "badsquares" is defined nowhere.
>
> Untested code.

It is not working because of assumptions on the underlying "Java
multidimensional arrays".
But, as Kenny said...  aren't you behind your homework?

cl-prompt> (take 4 (distinct (repeatedly 'random 64)))

works like a charm.  We still have not seen the correct Ruby version,
not to speak of your (clojure or F#: your pick) second assignment :)

Cheers
--
Marco
From: William James
Subject: Re: please review my code
Date: 
Message-ID: <goepvu01ilf@enews4.newsguy.com>
david wrote:

> (defun neighbor (x)
>   (list (1- x) x (1+x)))
> 
> (defun bad-squares (wk)
>   (let ((bad-squares (loop for x in (neighbor (first wk))
> 		      append (loop for y in (neighbor (second wk))
> 				collect (list x y)))))
>    badsquares))
> 
> (defun illegalp (wk bk)
>   (member (reverse-rank-file bk)
> 	  (mapcar #'reverse-rank-file (bad-squares wk))))

Clojure:

(defn abs [n] (if (< n 0) (- n) n))

(defn illegal? [w b]
  (every? #(< (abs %) 2) (map - w b) ))
From: Thomas A. Russ
Subject: Re: please review my code
Date: 
Message-ID: <ymiy6vnlqhn.fsf@blackcat.isi.edu>
david <······@gmail.com> writes:

> not quite there yet, but no more global variables :)
> thanks, david
> 
> ;;;; get a legal chess position with white king, knight, and bishop
> ;;;; and black king.
> 
> (defclass chessboard ()
>   ((board-position :accessor state
> 	           :initform (make-array '(8 8) :initial-element '0))))

Minor nit:  I would probably call this BOARD rather than BOARD-POSITION,
since it is an array representing the entire chessboard.  I would likely
also want to call the accessor board.

...
> (defun rank-file (position)
>   (multiple-value-bind (quotient remainder)
>                        (truncate position 8)
>     (list  quotient  remainder)))

Simpler:

(defun rank-file (position)
   (multiple-value-list (truncate position 8)))

But you might just want to instead have it return multiple values
instead of a list, which you then end up destructuring again in the next
function.  But since you have other uses, this may be 

> (defun reverse-rank-file (lst)
>   (let ((x (first lst))
> 	(y (second lst)))
>     (+ y (* 8 x))))
> 
> (defun get-positions ()
>   (mapcar #'rank-file (get-four-unique-random-numbers )))
...

> (defun neighbor (x)
>   (list (1- x) x (1+ x)))

To be more general-purpose, this should exclude values that are off the
edges of the board.

You could also make it more general by having it take an x,y board
position and generate all adjacent squares.


> (defun bad-squares (wk)
>   (let ((bad-squares (loop for x in (neighbor (first wk))
> 		      append (loop for y in (neighbor (second wk))
> 				collect (list x y)))))
>    badsquares))

Here you could simplify by eliminating the let block, since you don't do
anything with the variable except immediately return it.  You 

(defun bad-squares (wk)
    (loop for x in (neighbor (first wk))
          append (loop for y in (neighbor (second wk))
                      collect (list x y)))))

Also, recomputing the neigborhood each time in the inner loop seems a
bit wasteful.  So perhaps putting at least that part out of 

(defun bad-squares (wk)
  (let ((column-neighbors (neighbor (second wk))))
    (loop for x in (neighbor (first wk))
          append (loop for y in column-neighbors
                      collect (list x y)))))


But this also gives you an opportunity to generalize this based on the
piece, because what you are really trying to compute is a set of
threatened squares.  This would then be determined by the type of piece,
so perhaps a signature like

(defgeneric threatened-squares (piece side row column)
  "Returns a list of the square coordinates threatened by a piece in the
  given row and column.  Side is needed for computing the direction of
  threat for pawns and is ignored by all other pieces.")



(defmethod threatened-squares ((piece :king) side row column)
  "Returns all adjacent squares, since that is what a king threatens.
  (declare (ignore side))
  (adjacent-squares row column))

(defmethod threatened-squares ((piece :bishop) side row column)
  "Returns all diagonal squares, since that is what a king threatens.
  (declare (ignore side))
  (append (primary-diagonal row column)
          (secondary-diagonal row column)))

etc.

For fancier setups, you would need to take into account blocking of the
reach of rooks, bishops and queens.

> (defun illegalp (wk bk)
>   (member (reverse-rank-file bk)
> 	  (mapcar #'reverse-rank-file (bad-squares wk))))

Is it really this complicated?  Why not just check to make sure the
coordinates for BK is not in the BAD-SQUARES?  Why isn't it as simple as 

  (member (rank-file bk) (bad-squares wk))



-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: david
Subject: Re: please review my code
Date: 
Message-ID: <9617a1d7-3856-4076-a019-8189740b968f@33g2000yqm.googlegroups.com>
On Mar 2, 12:38 pm, ····@sevak.isi.edu (Thomas A. Russ) wrote:
> Is it really this complicated?  Why not just check to make sure the
> coordinates for BK is not in the BAD-SQUARES?  Why isn't it as simple as
>
>   (member (rank-file bk) (bad-squares wk))
>
> --
> Thomas A. Russ,  USC/Information Sciences Institute


CL-USER> (member (rank-file 0)(bad-squares '(0 0)))
NIL

it was returning nil no matter what. maybe that equality test
you mentioned elsewhere is the problem. thanks for all your
help. i will keep all these improvements and generalizations
on the to-do for my program. another idea i had was that
legal-position sometimes will compute nil before it returns
a position. it would be nice if it could report how many
nils it went through.

(defun get-four-unique-random-numbers ()
  (loop
     :with results = '()
     :for alea = (random 64)
     :while (< (length results) 4)
     :do (pushnew alea results)
     :finally (return results)))

(defun rank-file (position)
  (multiple-value-bind (quotient remainder)
                       (truncate position 8)
    (list  quotient  remainder)))

(defun reverse-rank-file (lst)
  (let ((x (first lst))
	(y (second lst)))
    (+ y (* 8 x))))

(defun get-positions ()
  (mapcar #'cons '(wk wn wb bk) (get-four-unique-random-numbers)))

(defun neighbor (x)
  (list (1- x) x (1+ x)))

(defun bad-squares (wk)
"bad-squares is bad because it doesn't care about edge cases."
  (let ((column-neighbors (neighbor (second wk))))
    (loop for x in (neighbor (first wk))
          append (loop for y in column-neighbors
                      collect (list x y)))))

(defun legal-position()
  (let* ((lst (get-positions))
	 (wk (rank-file (cdr (assoc 'wk lst))))
	 (bk (rank-file (cdr (assoc 'bk lst)))))
    (if (not (member (reverse-rank-file bk)
		     (mapcar #'reverse-rank-file (bad-squares wk))))
	lst (legal-position))))