deck.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. package main
  2. import (
  3. "red-green/door"
  4. "strings"
  5. )
  6. type Deck struct {
  7. Cards []door.Panel
  8. Backs []door.Panel
  9. Mark []door.Panel
  10. }
  11. func (d *Deck) SetBackColor(color string) {
  12. for x := 0; x < 5; x++ {
  13. for idx, _ := range d.Backs[x].Lines {
  14. d.Backs[x].Lines[idx].DefaultColor = color
  15. }
  16. }
  17. }
  18. func (d *Deck) Init() {
  19. d.Cards = make([]door.Panel, 52)
  20. for x := 0; x < 52; x++ {
  21. d.Cards[x] = CardOf(x)
  22. }
  23. d.Backs = make([]door.Panel, 5)
  24. for x := 0; x < 5; x++ {
  25. d.Backs[0] = BackOf(x)
  26. }
  27. d.Mark = make([]door.Panel, 2)
  28. d.Mark[0] = MarkOf(0)
  29. d.Mark[1] = MarkOf(1)
  30. }
  31. func CardOf(c int) door.Panel {
  32. suit := GetSuit(c)
  33. rank := GetRank(c)
  34. var is_red bool = suit < 2
  35. var color string
  36. if is_red {
  37. color = door.ColorText("RED ON WHITE")
  38. } else {
  39. color = door.ColorText("BLACK ON WHITE")
  40. }
  41. p := door.Panel{
  42. X: 0,
  43. Y: 0,
  44. Width: 5}
  45. r := RankSymbol(rank)
  46. s := SuitSymbol(suit)
  47. p.Lines = append(p.Lines,
  48. door.Line{Text: string(r) + string(s) + " ",
  49. DefaultColor: color})
  50. p.Lines = append(p.Lines,
  51. door.Line{Text: " " + string(s) + " ",
  52. DefaultColor: color})
  53. p.Lines = append(p.Lines,
  54. door.Line{Text: " " + string(s) + string(r),
  55. DefaultColor: color})
  56. return p
  57. }
  58. func BackOf(level int) door.Panel {
  59. p := door.Panel{
  60. X: 0,
  61. Y: 0,
  62. Width: 5,
  63. }
  64. for x := 0; x < 3; x++ {
  65. p.Lines = append(p.Lines,
  66. door.Line{Text: strings.Repeat(string(BackSymbol(level)), 5)})
  67. }
  68. return p
  69. }
  70. func MarkOf(c int) door.Panel {
  71. p := door.Panel{Width: 1}
  72. color := door.ColorText("BLUE ON WHITE")
  73. var m rune
  74. if c == 0 {
  75. m = ' '
  76. } else {
  77. if door.Unicode {
  78. m = '\u25a0'
  79. } else {
  80. m = '\xfe'
  81. }
  82. }
  83. p.Lines = append(p.Lines,
  84. door.Line{Text: string(m),
  85. DefaultColor: color})
  86. return p
  87. }
  88. func RankSymbol(c int) rune {
  89. const symbols = "A23456789TJQK"
  90. return rune(symbols[c])
  91. }
  92. func SuitSymbol(c int) rune {
  93. if door.Unicode {
  94. switch c {
  95. case 0:
  96. return '\u2665'
  97. case 1:
  98. return '\u2666'
  99. case 2:
  100. return '\u2663'
  101. case 3:
  102. return '\u2660'
  103. }
  104. } else {
  105. if door.Full_CP437 {
  106. switch c {
  107. case 0:
  108. return '\x03'
  109. case 1:
  110. return '\x04'
  111. case 2:
  112. return '\x05'
  113. case 3:
  114. return '\x06'
  115. }
  116. } else {
  117. switch c {
  118. case 0:
  119. return '*'
  120. case 1:
  121. return '^'
  122. case 2:
  123. return '%'
  124. case 3:
  125. return '$'
  126. }
  127. }
  128. }
  129. return '?'
  130. }
  131. func BackSymbol(level int) rune {
  132. if level == 0 {
  133. return ' '
  134. }
  135. if door.Unicode {
  136. switch level {
  137. case 1:
  138. return '\u2591'
  139. case 2:
  140. return '\u2592'
  141. case 3:
  142. return '\u2593'
  143. case 4:
  144. return '\u2588'
  145. }
  146. } else {
  147. switch level {
  148. case 1:
  149. return '\xb0'
  150. case 2:
  151. return '\xb1'
  152. case 3:
  153. return '\xb2'
  154. case 4:
  155. return '\xdb'
  156. }
  157. }
  158. return '?'
  159. }
  160. func GetRank(c int) int {
  161. return (c % 52) % 13
  162. }
  163. func GetSuit(c int) int {
  164. return (c % 52) / 13
  165. }
  166. func GetDeck(c int) int {
  167. return c / 52
  168. }
  169. type CardPair struct {
  170. card1 int
  171. card2 int
  172. }
  173. var blocks []CardPair
  174. func init() {
  175. blocks = []CardPair{
  176. CardPair{3, 4},
  177. CardPair{5, 6},
  178. CardPair{7, 8},
  179. CardPair{9, 10},
  180. CardPair{10, 11},
  181. CardPair{12, 13},
  182. CardPair{13, 14},
  183. CardPair{15, 16},
  184. CardPair{16, 17},
  185. CardPair{18, 19},
  186. CardPair{19, 20},
  187. CardPair{20, 21},
  188. CardPair{21, 22},
  189. CardPair{22, 23},
  190. CardPair{23, 24},
  191. CardPair{24, 25},
  192. CardPair{25, 26},
  193. CardPair{26, 27},
  194. }
  195. }
  196. // Which card(s) are unblocked by this card?
  197. func Unblocks(card int) []int {
  198. var result []int
  199. for idx := range blocks {
  200. if blocks[idx].card1 == card || blocks[idx].card2 == card {
  201. result = append(result, idx)
  202. }
  203. }
  204. return result
  205. }
  206. func CanPlay(card1 int, card2 int) bool {
  207. rank1 := GetRank(card1)
  208. rank2 := GetRank(card2)
  209. if (rank1+1)%13 == rank2 {
  210. return true
  211. }
  212. if rank1 == 0 {
  213. rank1 += 13
  214. }
  215. if rank1-1 == rank2 {
  216. return true
  217. }
  218. return false
  219. }