2011-09-07 6 views
7

मेरे गेम मेंस्कैला में मानचित्र में कुंजी के रूप में कक्षा का प्रकार

class Enemy 

है जो एआई/कार्यक्षमता है मैं

trait Moving 
trait VerticalMover extends Moving 
trait RandomMover extends Moving 

और अन्य के साथ बदल सकता हूं। अब मुझे विशेषता के आधार पर प्रीलोडेड सामान लाने की जरूरत है। मैं जो करना चाहता हूं वह एक ऐसा नक्शा है जो सभी लक्षणों को स्वीकार करता है जो कि कुंजी के रूप में आगे बढ़ते हैं और फिर कुछ एनीमकंटनर मूल्य के रूप में होते हैं जिसमें विशेषता संबंधित सामग्री प्रीलोड हो जाती है।

लेकिन मैं इस तरह के मानचित्र को कैसे परिभाषित कर सकता हूं और कुछ दुश्मनों के उदाहरण से कंटेनर प्राप्त करने के लिए मेरे .get() को कैसे प्रारूपित करता हूं। कुछ ऐसा:

val myEnemy = new Enemy with RandomMover 
val myDetails:EnemyContainer = enemyDetailsStore.get(myEnemy.getClass) 
+0

क्या आपका मतलब है कि आप 'दुश्मन डिस्प्लेस्टोर' को एक चीज़ वापस करने के लिए चाहते हैं यदि 'myEnemy'' वर्टिकलमोवर 'बढ़ाता है, और दूसरी बात यह है कि यह' रैंडममोवर 'बढ़ाती है? क्या होगा यदि यह दोनों को बढ़ाता है? –

+0

हां, यही मेरा मतलब था। लेकिन मैं अपने पूरे विचार की स्वच्छता के लिए आश्चर्यचकित होना शुरू कर रहा हूं। हो सकता है कि मेरे पास लक्षणों में एम्बेडेड कुछ महत्वपूर्ण स्ट्रिंग हो और उस कुंजी के रूप में उपयोग करें। तो विशेषता रैखिकरण के साथ आखिरी ओवरराइडिंग विशेषता एनीमीकंटनर को दूसरे शब्दों में स्थापित करेगी जो बनावट दुश्मन को प्रदर्शित करने के लिए उपयोग की जाती है। – vertti

+3

अधिकांश समय, एक विशेषता/इंटरफ़ेस का बिंदु "मैं जानता हूं कि * एक्स * कैसे करना है", एक्स के विभिन्न कार्यान्वयन की अनुमति देते हुए, अन्य विवरणों की अनुपस्थिति में, मैंने सोचा होगा कि सबसे प्राकृतिक डिजाइन होगा 'मूविंग' विशेषता के पास कुछ प्रकार की 'getMovingStrategy' या' move' विधि सीधे है, जिसे आप लंबवत और यादृच्छिक प्रेरक उपखंडों में तदनुसार कार्यान्वित कर सकते हैं। –

उत्तर

5

ठीक है, मुझे लगता है कि आपके दुश्मन विवरण स्टोर Map[Class[_ <: Moving], EnemyDetails] प्रकार का है। मुझे लगता है कि कुछ की तरह:

//gives a Map[Class[_ <: Moving], EnemyDetails] for all matching keys 
enemyDetailsStore.filterKeys(_ isInstance myEnemy) 

या:

//Iterable[EnemyDetails] 
enemyDetailsStore collect { case (c, d) if c isInstance myEnemy => d } 

या यहां तक ​​कि बस:

//Option[EnemyDetails] 
enemyDetailsStore collectFirst { case (c, d) if c isInstance myEnemy => d } 

आपके लिए क्या करेंगे। इस कोड के साथ एकमात्र "मुद्दा" यह है कि यह ओ (एन) है, जिसमें इसे सरल लुकअप के बजाय मानचित्र के ट्रैवर्सल की आवश्यकता होती है, जो ओ (1), या ओ (लॉग एन)

10

होगा हो सकता है कि आप एक मैप [मैनिफेस्ट, कोई भी] लपेट सकें ताकि यह सुनिश्चित किया जा सके कि मान मैनिफेस्ट कुंजी से मेल खाते हैं।

कि के संभावित स्केच। सबसे पहले एक छोटे से सहायक

class Typed[A](value: A)(implicit val key: Manifest[A]) { 
    def toPair: (Manifest[_], Any) = (key, value) 
} 
object Typed { 
    implicit def toTyped[A: Manifest](a: A) = new Typed(a) 
    implicit def toTypable[A](a: A) = new { 
    def typedAs[T >: A : Manifest] = new Typed[T](a)(manifest[T]) 
    } 
} 

तो आवरण ही (जो एक नक्शा नहीं है)

class TypedMap private(val inner: Map[Manifest[_], Any]) { 
    def +[A](t: Typed[A]) = new TypedMap(inner + t.toPair) 
    def +[A : Manifest](a: A) = new TypedMap(inner + (manifest[A] -> a)) 
    def -[A : Manifest]() = new TypedMap(inner - manifest[A]) 
    def apply[A : Manifest]: A = inner(manifest[A]).asInstanceOf[A] 
    def get[A : Manifest]: Option[A] = inner.get(manifest[A]).map(_.asInstanceOf[A]) 
    override def toString = inner.toString 
    override def equals(other: Any) = other match { 
    case that: TypedMap => this.inner == that.inner 
    case _ => false 
    } 
    override def hashCode = inner.hashCode 
} 

object TypedMap { 
    val empty = new TypedMap(Map()) 
    def apply(items: Typed[_]*) = new TypedMap(Map(items.map(_.toPair) : _*)) 
} 
इसी के साथ

आप

import Typed._ 
val repository = TypedMap("foo", 12, "bar".typedAs[Any]) 

भंडार कर सकते हैं: TypedMap = मानचित्र (जावा .lang.String -> foo इंट -> 12, किसी भी -> बार)

आप

repository[String] // returns "foo" 
repository.get[Any] // returns Some("bar") 

साथ तत्वों को पुनः प्राप्त मुझे लगता है कि निजी निर्माता सुनिश्चित करना चाहिए कि _ asInstanceOf सुरक्षित है। inner, सार्वजनिक छोड़ा जा सकता है के रूप में यह अपरिवर्तनीय है। इस तरह, Map की समृद्ध इंटरफेस उपलब्ध हो जाएगा, लेकिन दुर्भाग्य से, एक और TypedMap बनाने के लिए नहीं।

संबंधित मुद्दे