/content/drafts/go_fish_autohotkey.md

https://github.com/ad-si/RosettaGit · Markdown · 209 lines · 202 code · 7 blank · 0 comment · 0 complexity · 16caad63a49d82e5a5a1e253ed6a3d30 MD5 · raw file

  1. +++
  2. title = "Go Fish/AutoHotkey"
  3. description = ""
  4. date = 2014-03-17T22:07:51Z
  5. aliases = []
  6. [extra]
  7. id = 17396
  8. [taxonomies]
  9. categories = []
  10. tags = []
  11. +++
  12. {{collection|Go Fish}}
  13. [[Category:AutoHotkey]]
  14. {{works with|AutoHotkey L}} Unicode
  15. Easily expanded to multiple players, any combination of human and AI.
  16. ```ahk
  17. #NoEnv
  18. SetBatchLines -1
  19. #SingleInstance Force
  20. Global Suits:={1:"♣",2:"♦",3:"♠",4:"♥"}
  21. Global Pips:={13:"A",1:"2",2:"3",3:"4",4:"5",5:"6",6:"7",7:"8",8:"9",9:"T",10:"J",11:"Q",12:"K"}
  22. Deck:=new Deck
  23. Deck.Shuffle()
  24. Player1:=new Human
  25. Player0:=new AI
  26. i:=!i ; current player
  27. o:=!i ; current opponent
  28. While (Player%i%.Archive() || Player1.Hand.HasCards() || Player0.Hand.HasCards())
  29. {
  30. If (!Player%i%.Hand.HasCards()) ; if hand is empty,
  31. Player%i%.Hand.Draw() ; draw 1
  32. pip := Player%i%.Choose(o) ; player's request
  33. If pip not in % Player%i%.Pips() ; if invalid,
  34. Continue ; try again
  35. If (Player%i%.Take(pip, o)) ; if received what requested from opponent,
  36. Continue ; go again
  37. If (Player%i%.Hand.Draw().Pip = pip) ; if obtained what requested from pond,
  38. Continue ; go again
  39. i:=!i ; current player
  40. o:=!i ; current opponent
  41. }
  42. Msgbox % "Human: " Player1.Book.Show()
  43. . "`nAI: " Player0.Book.Show()
  44. . "`nWinner: " (Player1.Book.HasCards() > Player0.Book.HasCards() ? "Human" : "AI")
  45. Return ;--------------------------------------------------------------------------------
  46. class Card
  47. {
  48. __New(Pip, Suit) {
  49. this.Pip:=Pip, this.Suit:=Suit
  50. }
  51. Show() {
  52. Return this.Pip . this.Suit
  53. }
  54. }
  55. class Cards
  56. {
  57. Cards:=[]
  58. HasCards() {
  59. Return this.Cards.MaxIndex()
  60. }
  61. Shuffle() { ; Knuth Shuffle from http://rosettacode.org/wiki/Knuth_Shuffle#AutoHotkey
  62. Loop % this.HasCards()-1 {
  63. Random, i, A_Index, this.HasCards() ; swap item 1,2... with a random item to the right of it
  64. temp := this.Cards[i], this.Cards[i] := this.Cards[A_Index], this.Cards[A_Index] := temp
  65. }
  66. }
  67. Show(Sort=0) {
  68. For i, Card in this.Cards
  69. s .= Card.Show() ","
  70. s:=SubStr(s,1,-1)
  71. If Sort
  72. Sort, s, D,
  73. Return s
  74. }
  75. }
  76. class Deck extends Cards
  77. {
  78. __New() {
  79. For i, Pip in Pips
  80. For j, Suit in Suits
  81. this.Cards.Insert(new Card(Pip,Suit))
  82. }
  83. }
  84. class Hand extends Cards
  85. {
  86. lastDraw := ""
  87. __New() {
  88. this.Draw(9)
  89. }
  90. Draw(n=1) {
  91. Loop, %n%
  92. If (Deck.HasCards())
  93. this.Cards.Insert(temp:=Deck.Cards.Remove(1)) ; to deal from bottom, use Remove()
  94. lastDraw := temp.Pip ","
  95. Return temp.Pip
  96. }
  97. }
  98. class Player
  99. {
  100. Hand := new Hand
  101. Book := new Cards
  102. oRequests := "" ; log pips requested by opponent here
  103. Pip() {
  104. For i, Card in this.Hand.Cards
  105. s .= Card.Pip ","
  106. s:=SubStr(s,1,-1)
  107. Sort, s, D,
  108. Return s
  109. }
  110. Pips() {
  111. s := this.Pip()
  112. Sort, s, UD,
  113. Return s
  114. }
  115. Take(Pip, o) {
  116. Player%o%.oRequests := Pip "," Player%o%.oRequests
  117. For i, Card in Player%o%.Hand.Cards
  118. If (Card.Pip = Pip)
  119. this.Hand.Cards.Insert(Card)
  120. , toremove .= i ","
  121. toremove:=SubStr(toremove,1,-1)
  122. Sort, toremove, RND, ; must remove in reverse order
  123. Loop, Parse, toremove, `, ; so as not to mess up loop
  124. Player%o%.Hand.Cards.Remove(A_LoopField)
  125. Return toremove ? 1 : 0
  126. }
  127. Archive() {
  128. s := this.Pip()
  129. Loop, Parse, s, `,
  130. {
  131. If (A_LoopField = previous)
  132. count++
  133. Else
  134. count := 1
  135. If (count = Suits.MaxIndex()) ; normally 4
  136. {
  137. toarchive := A_LoopField
  138. Break
  139. }
  140. previous := A_LoopField
  141. }
  142. If (toarchive)
  143. {
  144. For i, Card in this.Hand.Cards
  145. If (Card.Pip = toarchive)
  146. this.Book.Cards.Insert(Card)
  147. , toremove .= i ","
  148. toremove:=SubStr(toremove,1,-1)
  149. Sort, toremove, RND, ; must remove in reverse order
  150. Loop, Parse, toremove, `, ; so as not to mess up loop
  151. this.Hand.Cards.Remove(A_LoopField)
  152. }
  153. Return 0
  154. }
  155. }
  156. class Human extends Player
  157. {
  158. Choose(o) {
  159. InputBox, Pip, Enter a rank to request from opponent.
  160. , % "Your cards: " this.Hand.Show(1)
  161. . "`nYour books: " this.Book.Show(1)
  162. . "`nAI's books: " Player%o%.Book.Show(1)
  163. . "`nEnter rank: " this.Pips()
  164. , , 900
  165. Return Pip
  166. }
  167. }
  168. class AI extends Player
  169. {
  170. Choose(o) {
  171. Static Pip ; last asked
  172. s := this.Pip()
  173. Loop, Parse, s, `,
  174. {
  175. If (A_LoopField = previous)
  176. count++
  177. Else
  178. count := 1
  179. Random, rand, 0, 2
  180. If (count > oldcount - rand//2 && count < Suits.MaxIndex())
  181. oldcount := count
  182. , IHaveMostOf := A_LoopField
  183. previous := A_LoopField
  184. }
  185. ChoicePrefs := this.oRequests . this.Hand.lastDraw . IHaveMostOf . "," . s
  186. this.Hand.lastDraw := ""
  187. Loop, Parse, ChoicePrefs, `,
  188. If A_LoopField in % this.Pips()
  189. If (A_LoopField != Pip) ; don't repeat last asked
  190. {
  191. Pip := A_LoopField
  192. Break
  193. }
  194. Msgbox, , Opponent requests a rank from you.
  195. , % "Your cards: " Player%o%.Hand.Show(1)
  196. . "`nYour books: " Player%o%.Book.Show(1)
  197. . "`nAI's books: " this.Book.Show(1)
  198. . "`n`n`nRequested rank: " Pip
  199. Return Pip
  200. }
  201. }
  202. ```