Схема переопределения списка - PullRequest
0 голосов
/ 01 апреля 2010

У меня есть список, называемый рукой, и еще один, называемый колода, основная цель здесь состоит в том, чтобы взять первую карту (или элемент) в колоду списка и поместить ее в руку списка, когда я вызываю ничью fnction ... 1001 *

> (draw hand deck)
(2 C)
> (draw hand deck)
(2 C) (3 H) 
> (draw hand deck)
(2 C) (3 H) (K D)

но каждый раз, когда я называю это, рука никогда не меняет значение ... Я понятия не имею, есть ли способ, как в O-Object постоянно изменять содержимое руки?

и я изначально определяю пустую руку, потому что у игрока нет карты для старта.

(define hand '())

Ответы [ 4 ]

1 голос
/ 01 апреля 2010

Функциональное решение, при котором draw не имеет побочных эффектов:

;; Returns a cons whose car will be the new hand and cdr being the
;; rest of the original deck
(define (draw deck hand)
    (if (not (null? deck))
        (cons (cons (car deck) hand) (cdr deck))
        (cons hand ())))

;; Gets the new hand from the cons returned by draw.
(define (hand cards) (car cards))

;; Gets the new deck from the cons returned by draw.
(define (deck cards) (cdr cards))

;; test
(define cards (draw '(1 2 3 4 5) ()))
cards
=> ((1) 2 3 4 5)
(hand cards)
=> (1)
(deck cards)
=> (2 3 4 5)
;; draw again
(set! cards (draw (deck cards) (hand cards)))
cards
=> ((2 1) 3 4 5)
(hand cards)
=> (2 1)
(deck cards)
=> (3 4 5)
0 голосов
/ 01 апреля 2010

Виджей имеет лучшее решение для Схемы. Однако, если вы действительно хотите сделать эту работу путем постоянного изменения списков, вам придется использовать set-car! и set-cdr!. Это не естественно в Scheme, и для его работы требуется несколько хаков:

Сначала определите hand и deck:

(define hand '(dummy))
(define deck '((2 C) (3 H) (K D)))

hand должен начинаться с существующего элемента, чтобы иметь некоторую существующую структуру списка для изменения. Вы не можете использовать set-car! и set-cdr! с нулем ('()).

Теперь напишите draw:

(define (draw from to)
  ; push the top element of `from` onto `to`
  (set-cdr! to (copy to))
  (set-car! to (car from))
  ; pop the top element of `from` off
  (set-car! deck (cadr deck))
  (set-cdr! deck (cddr deck)))
; also we need to define copy
(define (copy l)
  (map (lambda (x) x) l))

Это означает, что последний элемент вашей руки всегда будет пустышкой. Было бы лучше добавить проверку для начального регистра и перезаписать его вместо нажатия:

(define (draw from to)
  ; push the top element of `from` onto `to` (just overwrite the first time)
  (when (pair? (cdr to))
    (set-cdr! to (copy to)))
  (set-car! to (car from))
  ; pop the top element of `from` off
  (set-car! deck (cadr deck))
  (set-cdr! deck (cddr deck)))

Также вы должны проверить, что from не пусто, прежде чем что-либо делать.

0 голосов
/ 01 апреля 2010

О, и затем вы обнаружите, что изменение списка, на который ссылается имя внутри функции, не изменит того, на что ссылается имя, с точки зрения того, кто вызвал эту функцию. Итак:

(define (foo lst)
  (set! lst '(hi))
  (display "within foo: ")
  (display lst)
  (newline)
  lst)
(define my-list '(hello))
(foo my-list)
(display "after foo: ") 
(display my-list)
(newline)
(set! my-list (foo my-list))
(display "using the result of foo: ")
(display my-list)
(newline)
0 голосов
/ 01 апреля 2010

Вы не можете изменить содержимое списка, но вы можете изменить список, к которому относится имя. Итак:

(let ((some-list '("post")))
 (display "initially: ")
 (display some-list)
 (newline)
 (set! some-list (cons "first" some-list))
 (display "added first: ")
 (display some-list)
 (newline)
 (set! some-list '(a completely new list))
 (display "finally: ")
 (display some-list)
 (newline)
 some-list)

Теперь каждый из списков '("post")' ("first" "post") и '(полностью новый список) являются неизменяемыми ("неизменяемыми") списками, но имя some-list сначала указывает на один потом другой, потом третий.

Предостережение: для многих проблем вам захочется избежать установки! и попытаться думать о проблеме по-другому. Например, если вы работаете с мирами и вселенными для вашей игры, http://pre.plt -scheme.org / рх / док / teachpack / 2htdpuniverse.html тогда вы захотите, чтобы ваши средства обновления возвращали новое состояние мира, а не использовали set! изменить старый.

...