one program please can someone help me

Discussion of Common Lisp

one program please can someone help me

Postby MaraPatisia » Thu Mar 19, 2009 8:04 am

i ve got a problem with this program, is about a robot which can move one position right (MR) in a 4x4 table. movements left(ML) down(MD) or up(MU) are not allowed.The pr_move is the position that came from, move is the position tha we want to go right(MR).x is the row that is the row and y is the coloumn. it cant move diagonial. the code has a problem and it cant run. if someone can help me i would appreciate

(defun move_robot (move '('pr_move x y))
(cond ((eq move 'ML) ('NO_MOVE))
((eq move 'MU) ('NO_MOVE))
((eq move 'MD) ('NO_MOVE))
((eq move 'MR) (cond ((eq pr_move 'ML) (princ ('ML x (+ y 1))))
((eq pr_move 'MR) (princ ('MR x (+ y 1))))
((eq pr_move 'MU) (princ ('MU x (+ y 1))))
((eq pr_move 'MD) (princ ('MD x (+ y 1))))
)

)
)
)
MaraPatisia
 
Posts: 2
Joined: Thu Mar 19, 2009 4:22 am

Re: one program please can someone help me

Postby Paul Donnelly » Thu Mar 19, 2009 1:25 pm

If you use code tags you can preserve your indentation.
Code: Select all
(defun move_robot (move '('pr_move x y))
  (cond ((eq move 'ML) ('NO_MOVE))
        ((eq move 'MU) ('NO_MOVE))
        ((eq move 'MD) ('NO_MOVE))
        ((eq move 'MR) (cond ((eq pr_move 'ML) (princ ('ML x (+ y 1))))
                             ((eq pr_move 'MR) (princ ('MR x (+ y 1))))
                             ((eq pr_move 'MU) (princ ('MU x (+ y 1))))
                             ((eq pr_move 'MD) (princ ('MD x (+ y 1))))))))

You've got a quoted list of some values sitting in the arguement list. This isn't valid Lisp code, what is it doing there?

Since 'NO_MOVE is not a function, you should not put it in parentheses, because this is how you call functions. You just want to type the symbol itself there. Likewise, in your call to PRINC, you can't type "('ML ...", because 'ML is not a function. If you want to create a list there, use the LIST function to create one.

Also you have a couple of style issues which are not bugs. Lispers usually do not use underscores to separate words in symbols. MOVE-ROBOT, PR-MOVE, and NO-MOVE would be more normal names (I only capitalize these symbols here to make it clear that they are Lisp code. I'm not suggesting that you do so in your program).

While your use of COND is correct, using CASE would result in shorter code.

In your second COND, you're not actually doing anything different depending on the value of PR_MOVE. You can simply interpolate this variable into the list you print/return. What you've done is as silly as (IF 'A 'A).

Check me on this, but I believe the following should do what your function is supposed to do. I don't mind putting it here, since the problems with your code are just syntactic, and you seem to know what you're trying to do.
Code: Select all
(defun move-robot (move pr-move x y)
  (case move
        ((ML MU MD) 'NO-MOVE)
        ((MR) (princ (list pr-move x (1+ y))))))
Paul Donnelly
 
Posts: 148
Joined: Wed Jul 30, 2008 11:26 pm

Re: one program please can someone help me

Postby MaraPatisia » Fri Mar 20, 2009 3:37 am

Thanks for your help, but there's another problem i would like the function to get 2 parameters, The first is the move that we want to move the second is a list .The list has 3 atoms .The first atom is the previous move pr_move the second is x row and the third is y coloumn. How could i get a list in my function and how i could call the function? I suppose Non with the below way

(move_robot (read) '((read) (read) (read)))
MaraPatisia
 
Posts: 2
Joined: Thu Mar 19, 2009 4:22 am

Re: one program please can someone help me

Postby Paul Donnelly » Fri Mar 20, 2009 3:50 pm

MaraPatisia wrote:Thanks for your help, but there's another problem i would like the function to get 2 parameters, The first is the move that we want to move the second is a list .The list has 3 atoms .The first atom is the previous move pr_move the second is x row and the third is y coloumn. How could i get a list in my function and how i could call the function? I suppose Non with the below way

(move_robot (read) '((read) (read) (read)))

You can pass a list as a single parameter and either take it apart by hand or use DESTRUCTURING-BIND in your function. Unless I'm confused, only in macros is it possible to put destructuring right in the lambda list. You could also use a struct to carry these parameters around, if it seems more appropriate.
Paul Donnelly
 
Posts: 148
Joined: Wed Jul 30, 2008 11:26 pm

Re: one program please can someone help me

Postby Harleqin » Fri Mar 20, 2009 5:36 pm

I see only one reason to put logically independent arguments into a list: that they are already stored that way somewhere.

If so, you will have to give it to your function as a single parameter, and destructure it manually:

Code: Select all
(defun move-robot (direction prev-move-and-position)
  (destructuring-bind (pr-move x y) prev-move-and-position
    ; ...
    ))


The alternative is to use a macro that wraps around your function. Assuming that your function is declared like this:

Code: Select all
(defun move-robot (direction prev-move x y)
  ; ...
  )


The macro would be something like

Code: Select all
(defmacro move-robot* (direction (prev-move x y))
  `(move-robot ,direction ,prev-move ,x ,y))


Note that the parameters don't have to be named the same.

But this is somewhat silly, anyway.
"Just throw more hardware at it" is the root of all evil.
Svante
Harleqin
 
Posts: 71
Joined: Wed Dec 17, 2008 5:18 am
Location: Bonn, Germany


Return to Common Lisp

Who is online

Users browsing this forum: Google [Bot], Yahoo [Bot] and 2 guests