Advertisement
Guest User

Untitled

a guest
Dec 4th, 2016
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.00 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4. "errors"
  5. "fmt"
  6. "math/rand"
  7. "strings"
  8. "time"
  9. )
  10.  
  11. const Spy = false
  12.  
  13. var rnd = rand.New(rand.NewSource(time.Now().UnixNano()))
  14.  
  15. type Card int
  16.  
  17. func (c Card) String() string {
  18. return [...]string{"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"}[int(c)]
  19. }
  20.  
  21. func parseCard(s string) (Card, error) {
  22. for i := 0; i < 13; i++ {
  23. card := Card(i)
  24. if card.String() == s {
  25. return card, nil
  26. }
  27. }
  28. return Card(0), errors.New("Unknown card value: " + s)
  29. }
  30.  
  31. type Player struct {
  32. hand []int
  33. score int
  34. computer bool
  35. }
  36.  
  37. func newPlayer(computer bool) *Player {
  38. return &Player{make([]int, 13, 13), 0, computer}
  39. }
  40.  
  41. func (p *Player) TakeCard(card Card) {
  42. p.hand[card]++
  43. if p.hand[card] == 4 {
  44. p.hand[card] = 0
  45. p.score++
  46. fmt.Printf("There's a complete book of %s.n", card)
  47. }
  48. }
  49.  
  50. func (p *Player) NumberOfCards() int {
  51. total := 0
  52. for _, count := range p.hand {
  53. total += count
  54. }
  55. return total
  56. }
  57.  
  58. type GoFishGame struct {
  59. deck []Card
  60. players []*Player
  61. turn *Player
  62. turnIndex int
  63. }
  64.  
  65. func NewGoFishGame(computer ...bool) *GoFishGame {
  66. deck := make([]Card, 52, 52)
  67. for i, card := range rnd.Perm(52) {
  68. deck[i] = Card(card % 13)
  69. }
  70. players := make([]*Player, len(computer), len(computer))
  71. for i, computer := range computer {
  72. players[i] = newPlayer(computer)
  73. }
  74. return &GoFishGame{deck, players, players[0], 0}
  75. }
  76.  
  77. func (gm *GoFishGame) playerName(index int) string {
  78. if gm.players[index].computer {
  79. return fmt.Sprintf("Computer %d", index+1)
  80. } else {
  81. return fmt.Sprintf("Human %d", index+1)
  82. }
  83. }
  84.  
  85. func (gm *GoFishGame) decideStealingComputer() (int, Card) {
  86. opponentIndex := rnd.Intn(len(gm.players) - 1)
  87. if opponentIndex >= gm.turnIndex {
  88. opponentIndex++
  89. }
  90.  
  91. var choices []Card
  92. for card, count := range gm.turn.hand {
  93. for i := 0; i < count; i++ {
  94. choices = append(choices, Card(card))
  95. }
  96. }
  97. rank := choices[rnd.Intn(len(choices))]
  98.  
  99. return opponentIndex, rank
  100. }
  101.  
  102. func (gm *GoFishGame) decideStealingHuman() (int, Card) {
  103. again:
  104. var index int
  105. if len(gm.players) == 2 {
  106. index = (gm.turnIndex + 1) % 2
  107. } else {
  108. var oneIndex int
  109. fmt.Printf("Steal from whom (1-%d)? ", len(gm.players))
  110. fmt.Scan(&oneIndex)
  111. index = oneIndex - 1
  112. if !(0 <= index && index <= len(gm.players) && index != gm.turnIndex) {
  113. fmt.Println("Wrong opponent.")
  114. goto again
  115. }
  116. }
  117.  
  118. fmt.Print("Steal which rank? ")
  119. var card string
  120. fmt.Scan(&card)
  121. rank, err := parseCard(strings.ToUpper(card))
  122. if err != nil {
  123. fmt.Println("Wrong rank.")
  124. goto again
  125. }
  126.  
  127. if gm.turn.hand[rank] == 0 {
  128. fmt.Println("You can only steal a rank from your hand.")
  129. goto again
  130. }
  131. return index, rank
  132. }
  133.  
  134. func (gm *GoFishGame) decideStealing() (int, Card) {
  135. if gm.turn.computer {
  136. return gm.decideStealingComputer()
  137. } else {
  138. return gm.decideStealingHuman()
  139. }
  140. }
  141.  
  142. func (gm *GoFishGame) drawCard(quiet bool) {
  143. card := gm.deck[0]
  144. gm.deck = gm.deck[1:]
  145. gm.turn.TakeCard(card)
  146. if !quiet {
  147. if Spy || !gm.turn.computer {
  148. fmt.Printf("%s drew card %s.n", gm.playerName(gm.turnIndex), card)
  149. } else {
  150. fmt.Printf("%s drew a card.n", gm.playerName(gm.turnIndex))
  151. }
  152. }
  153. }
  154.  
  155. func (gm *GoFishGame) nextPlayer(quiet bool) {
  156. gm.turnIndex = (gm.turnIndex + 1) % len(gm.players)
  157. gm.turn = gm.players[gm.turnIndex]
  158. if !quiet {
  159. fmt.Printf("%s to play.n", gm.playerName(gm.turnIndex))
  160. }
  161. }
  162.  
  163. func (gm *GoFishGame) setup() {
  164. for range gm.players {
  165. for i := 0; i < 9; i++ {
  166. gm.drawCard(true)
  167. }
  168. gm.nextPlayer(true)
  169. }
  170. }
  171.  
  172. func (gm *GoFishGame) gameOver() bool {
  173. if len(gm.deck) != 0 {
  174. return false
  175. }
  176. for _, player := range gm.players {
  177. if player.NumberOfCards() > 0 {
  178. return false
  179. }
  180. }
  181. return true
  182. }
  183.  
  184. func (gm *GoFishGame) printStatus() {
  185. for p, player := range gm.players {
  186. if p != 0 {
  187. fmt.Print(" ")
  188. }
  189. n := player.NumberOfCards()
  190. fmt.Print(gm.playerName(p), ": ", n, " cards")
  191. if (Spy || !player.computer) && n > 0 {
  192. fmt.Print(" (")
  193. sep := ""
  194. for rank, count := range player.hand {
  195. for i := 0; i < count; i++ {
  196. fmt.Print(sep, Card(rank))
  197. sep = " "
  198. }
  199. }
  200. fmt.Print(")")
  201. }
  202. fmt.Print(", ", player.score, " points.")
  203. }
  204. fmt.Print(" ", len(gm.deck), " cards left.")
  205. fmt.Println()
  206. }
  207.  
  208. func (gm *GoFishGame) move() {
  209. player := gm.turn
  210.  
  211. again:
  212. if player.NumberOfCards() == 0 {
  213. if len(gm.deck) == 0 {
  214. return
  215. }
  216. gm.drawCard(false)
  217. }
  218.  
  219. opponentIndex, rank := gm.decideStealing()
  220. if player.hand[rank] == 0 {
  221. panic("strategy generated illegal move")
  222. }
  223.  
  224. opponent := gm.players[opponentIndex]
  225. stolen := opponent.hand[rank]
  226. opponent.hand[rank] = 0
  227.  
  228. if stolen != 0 {
  229. fmt.Printf("%s stole %d cards of rank %s from %s.n",
  230. gm.playerName(gm.turnIndex), stolen, rank, gm.playerName(opponentIndex))
  231. for i := 0; i < stolen; i++ {
  232. player.TakeCard(rank)
  233. }
  234. if player.hand[rank] == 0 && gm.gameOver() {
  235. return
  236. }
  237. gm.printStatus()
  238. goto again
  239. }
  240.  
  241. fmt.Printf("%s does not have cards of rank %s.n", gm.playerName(opponentIndex), rank)
  242. if len(gm.deck) > 0 {
  243. gm.drawCard(false)
  244. }
  245. }
  246.  
  247. func (gm *GoFishGame) Play() {
  248. gm.setup()
  249.  
  250. for !gm.gameOver() {
  251. gm.printStatus()
  252. gm.move()
  253. gm.nextPlayer(false)
  254. }
  255.  
  256. fmt.Println("Game over.")
  257. gm.printStatus()
  258. }
  259.  
  260. func main() {
  261. gm := NewGoFishGame(true, true, true, true, true)
  262. gm.Play()
  263. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement