2010-03-31 4 views
0

У меня есть список под названием hand и другой, называемый колодой, главная цель здесь - взять первую карту (или элемент) в колоде списка и поместить ее в ручку списка, когда я назову фрикционную ничью ...Схема переопределения списка

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

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

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

(define hand '()) 

ответ

0

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

(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) 

Теперь каждый из списков «(„пост“)» („первый“ „пост“) и «(совершенно новый список) неизменные („неизменные“) списки, но название некоторых -list сначала указывает на один, затем на другой, затем на третий.

Предостережение: для многих проблем вы хотите избежать установки! и попытаться по-другому подумать о проблеме. Например, если вы работаете с мирами и вселенными для своей игры, то вам нужно, чтобы ваши обновления возвращали новое состояние мира, а не использовали set! для изменения старого.

0

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

(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) 
1

функциональное решение, с 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

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

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

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

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

Теперь напишите 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 не пуста, прежде чем делать что-либо.

Смежные вопросы