0

このPythonコードに相当するものは何ですか?

class Player:
    def __init__(self): 
        self.hp = 10
        self.pos = [0,0,0]
        self.items = []
    def damage(self,dmg):
        self.hp -= dmg

player = Player()
player.damage(3)
player.pos[0] += 5
player.items.append("banana")

print player.hp, player.pos, player.items
>> 3 [5,0,0] ["banana"]

Clojure(または他のLisp)では?

4

4 に答える 4

3

ラケットで:

#lang racket

(define player%
  (class object%
    (init-field [hp 10] [pos '(0 0 0)] [items '()])

    (define/public (damage dmg)
      (set! hp (- hp dmg)))

    (define/public (move dx dy dz)
      (set! pos (list (+ (first pos) dx)
                      (+ (second pos) dy)
                      (+ (third pos) dz))))

    (define/public (add-item item)
      (set! items (cons item items)))

    (super-new)))

(send* (new player%)
       (damage 3)
       (move 5 0 0)
       (add-item "banana"))

Racketを使用している場合は、より機能的なスタイルでプログラミングすることをお勧めします。その場合、ミューテーションを回避するために次のようなメソッドを作成できます。

(define/public (damage dmg)
  (new this% [hp (- hp dmg)] [pos pos] [items items]))
于 2012-06-26T22:52:06.253 に答える
3

Common Lisp では:

(defclass player ()
  ((hp :accessor hp :initform 10)
   (pos :accessor pos :initform (list 0 0 0))
   (items :accessor items :initform nil)))

(defmethod damage ((a-player player) damage)
  (decf (hp a-player) damage))

REPLでは

; compiling (DEFCLASS PLAYER ...)
; compiling (DEFMETHOD DAMAGE ...)
CL-USER> (defparameter *player* (make-instance 'player))

*PLAYER*
CL-USER> (damage *player* 3)
7
CL-USER> (incf (car (pos *player*)) 5)
5
CL-USER> (push :banana (items *player*))
(:BANANA)
CL-USER> (list (hp *player*) (pos *player*) (items *player*))
(7 (5 0 0) (:BANANA))
CL-USER> 

個人的には、後で表現を変更することにした場合に備えて、posxの 、y、に分割zし、在庫に物を出し入れするいくつかのメソッドをおそらく定義します。

于 2012-06-26T23:10:59.560 に答える
3

Clojure では、通常は変更可能なデータ構造を使用せず、代わりにプレーヤーの現在の状態を表す不変のデータを作成します。プレーヤーを更新すると、更新された状態を説明する新しいデータが作成されます。マットの答えは、これを行う良い例です。

複数の状態変化を伴う単一の「プレイヤー」アイデンティティを長期にわたって維持したい場合は、次のようなアトムを使用してこれを行うことができます。

(def initial-player-state 
 {:hp 10
  :pos [0 0 0]
  :items []})

(def player (atom initial-player-state))

;; Define some update functions

(defn damage [player dmg]
  (update-in player [:hp] + dmg))

(defn move [player dir]
  (update-in player [:pos] #(vec (map + % dir))))

(defn add-item [player item]
  (update-in player [:items] conj item))

;;  Make some changes

(swap! player move [5 0 0])
(swap! player damage -3)
(swap! player add-item "Apple")

;; view the current player state by dereferencing the atom

@player
=> {:hp 10, :pos [0 0 0], :items ["Apple"]}

実際のゲームでは、プレーヤーだけでなく、不変のゲーム ステート全体が 1 つのアトムに含まれる場合があることに注意してください。

于 2012-06-26T22:37:23.740 に答える
3

Clojure の場合:

(def player {
    :hp 10
    :pos [0 0 0]
    :items [] })

(defn damage [player amount]
    (update-in player [:hp] - amount))

(defn move [player direction]
    (update-in player [:pos] #(map + % direction)))

(defn give [player item]
    (update-in player [:items] conj item))

(-> player
    (damage 3)
    (move [5 0 0])
    (give "banana"))

; Output: {:hp 7, :pos (5 0 0), :items ["banana"]}
于 2012-06-26T22:25:00.203 に答える