Card.scala 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package models
  2. import anorm._
  3. import anorm.SqlParser._
  4. import play.api.db._
  5. import play.api.libs.json._
  6. import play.api.Play.current
  7. object Card {
  8. implicit val writes = new Writes[Card] {
  9. def writes(o: Card) = Json.obj(
  10. "word" -> o.word,
  11. "taboo" -> o.taboo
  12. )
  13. }
  14. def size = DB.withConnection { implicit c =>
  15. SQL("select count(*) from words").single(long("count"))
  16. }
  17. def exists(word: String) = DB.withConnection { implicit c =>
  18. SQL("select * from words where lower(word) = lower({word})")
  19. .on('word -> word)
  20. .list(str("word"))
  21. .nonEmpty
  22. }
  23. def add(card: Card) = DB.withTransaction { implicit c =>
  24. SQL("insert into words (word) values ({word})")
  25. .on('word -> card.word)
  26. .execute()
  27. val id = SQL("select last_insert_rowid()").singleOpt(int("last_insert_rowid()"))
  28. id.map { id =>
  29. card.taboo.map { word =>
  30. SQL("insert into taboo (word_id, word) values ({id}, {word})")
  31. .on('id -> id, 'word -> word)
  32. .execute()
  33. }
  34. }
  35. }
  36. def list() = DB.withConnection { implicit c =>
  37. val list = SQL("""
  38. select words.id as id, words.word as word, taboo.word as taboo
  39. from words left join taboo on word_id = words.id
  40. """)
  41. .list(int("id") ~ str("word") ~ str("taboo") map flatten)
  42. mapToCard(list)
  43. }
  44. def mapToCard(seq: Seq[(Int, String, String)]) = {
  45. seq.groupBy(_._1).map {
  46. case (id, taboos) => Card(taboos.map(_._2).head, taboos.map(_._3).toSet)
  47. }.toList
  48. }
  49. }
  50. case class Card(word: String, taboo: Set[String]) {
  51. lazy val tabooRegex = (taboo + word).flatMap(compoundWords).map { word =>
  52. ("\\b"+word.toLowerCase+"\\b").r
  53. }
  54. def compoundWords(text: String): Seq[String] = {
  55. text.split(" ") :+ text.replace(" ", "")
  56. }
  57. def isTaboo(text: String) = {
  58. val lower = text.toLowerCase
  59. // check if text contains word or anything in taboo
  60. tabooRegex.map(!_.findFirstIn(lower).isEmpty).foldLeft(false)(_ || _)
  61. }
  62. def isCorrect(text: String) = {
  63. text.toLowerCase.indexOf(word.toLowerCase) >= 0
  64. }
  65. }
  66. object CardPool {
  67. import scala.util.Random
  68. def get() = DB.withConnection { implicit c =>
  69. val list = Card.list()
  70. CardPool(Random.shuffle(list))
  71. }
  72. }
  73. case class CardPool(list: List[Card]) {
  74. var index = 0
  75. def hasNext = list.size > index
  76. def next() = {
  77. val card = list(index)
  78. index += 1
  79. card
  80. }
  81. }