Przeglądaj źródła

Go through all cards instead of randomly selecting

We now have a CardPool class which abstracts away a deck of cards that
you can draw from. Right now we just store all the cards in memory and
shuffle there since performance isn't an issue yet.
Thomas Dy 11 lat temu
rodzic
commit
9774d896ae
3 zmienionych plików z 39 dodań i 15 usunięć
  1. 6 1
      app/controllers/Cards.scala
  2. 22 13
      app/models/Card.scala
  3. 11 1
      app/models/Taboo.scala

+ 6 - 1
app/controllers/Cards.scala

@@ -30,8 +30,13 @@ object Cards extends Controller {
     Ok(Json.toJson(Card.list()))
   }
 
+  var cardPool = CardPool.get()
+
   def random = Action {
-    Ok(Json.toJson(Card.getRandom()))
+    if(!cardPool.hasNext) {
+      cardPool = CardPool.get()
+    }
+    Ok(Json.toJson(cardPool.next()))
   }
 
 }

+ 22 - 13
app/models/Card.scala

@@ -27,18 +27,6 @@ object Card {
     }
   }
 
-  def getRandom() = DB.withConnection { implicit c =>
-    val list = SQL("""
-      with rand as (
-        select * from words offset floor(random() * (select count(*) from words)) limit 1
-      )
-      select rand.word as word, taboo.word as taboo from taboo, rand where word_id = rand.id
-    """)
-    .list(str("word") ~ str("taboo") map flatten)
-
-    mapToCard(list).head
-  }
-
   def list() = DB.withConnection { implicit c =>
     val list = SQL("""
       select words.word as word, taboo.word as taboo
@@ -52,7 +40,7 @@ object Card {
   def mapToCard(seq: Seq[(String, String)]) = {
     seq.groupBy(_._1).map {
       case (word, taboos) => Card(word, taboos.map(_._2).toSet)
-    }
+    }.toList
   }
 }
 
@@ -75,3 +63,24 @@ case class Card(word: String, taboo: Set[String]) {
   }
 
 }
+
+object CardPool {
+  import scala.util.Random
+
+  def get() = DB.withConnection { implicit c =>
+    val list = Card.list()
+    CardPool(Random.shuffle(list))
+  }
+}
+
+case class CardPool(list: List[Card]) {
+  var index = 0
+
+  def hasNext = list.size > index
+
+  def next() = {
+    val card = list(index)
+    index += 1
+    card
+  }
+}

+ 11 - 1
app/models/Taboo.scala

@@ -95,6 +95,7 @@ class TabooGame(val chatActor: ActorRef) extends Actor {
 
   var currentTeam: Team = teamB
   var opposingTeam: Team = teamA
+  var cardPool: CardPool = CardPool.get()
 
   def receive = {
     case Join(username) =>
@@ -164,7 +165,16 @@ class TabooGame(val chatActor: ActorRef) extends Actor {
       ))
 
     case NextCard =>
-      val card = Card.getRandom()
+      if(!cardPool.hasNext) {
+        cardPool = CardPool.get()
+        chatActor ! Announce(Json.obj(
+          "kind" -> "talk",
+          "user" -> "*GM",
+          "message" -> "And we're out of cards... Reshuffling the current set. You can help by contributing more cards though! *hint* *hint*"
+        ))
+      }
+
+      val card = cardPool.next()
       roundActor ! card
 
       val message = Json.obj(