Go Fish/AutoHotkey

Revision as of 16:26, 18 January 2020 by Thundergnat (talk | contribs) (Avoid miscounting task entries twice)

AutoHotkey

Go Fish/AutoHotkey is part of Go Fish. You may find other members of Go Fish at Category:Go Fish.

Works with: AutoHotkey L

Unicode

Easily expanded to multiple players, any combination of human and AI. <lang ahk>#NoEnv SetBatchLines -1

  1. SingleInstance Force

Global Suits:={1:"♣",2:"♦",3:"♠",4:"♥"} 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"} Deck:=new Deck Deck.Shuffle() Player1:=new Human Player0:=new AI i:=!i ; current player o:=!i ; current opponent While (Player%i%.Archive() || Player1.Hand.HasCards() || Player0.Hand.HasCards()) { If (!Player%i%.Hand.HasCards()) ; if hand is empty, Player%i%.Hand.Draw() ; draw 1 pip := Player%i%.Choose(o) ; player's request If pip not in % Player%i%.Pips() ; if invalid, Continue ; try again If (Player%i%.Take(pip, o)) ; if received what requested from opponent, Continue ; go again If (Player%i%.Hand.Draw().Pip = pip) ; if obtained what requested from pond, Continue ; go again i:=!i  ; current player o:=!i ; current opponent } Msgbox % "Human: " Player1.Book.Show() . "`nAI: " Player0.Book.Show() . "`nWinner: " (Player1.Book.HasCards() > Player0.Book.HasCards() ? "Human" : "AI") Return ;--------------------------------------------------------------------------------

class Card { __New(Pip, Suit) { this.Pip:=Pip, this.Suit:=Suit } Show() { Return this.Pip . this.Suit } } class Cards { Cards:=[]

HasCards() { Return this.Cards.MaxIndex() } Shuffle() { ; Knuth Shuffle from http://rosettacode.org/wiki/Knuth_Shuffle#AutoHotkey Loop % this.HasCards()-1 { Random, i, A_Index, this.HasCards() ; swap item 1,2... with a random item to the right of it temp := this.Cards[i], this.Cards[i] := this.Cards[A_Index], this.Cards[A_Index] := temp } } Show(Sort=0) { For i, Card in this.Cards s .= Card.Show() "," s:=SubStr(s,1,-1) If Sort Sort, s, D, Return s } } class Deck extends Cards { __New() { For i, Pip in Pips For j, Suit in Suits this.Cards.Insert(new Card(Pip,Suit)) } } class Hand extends Cards { lastDraw := "" __New() { this.Draw(9) } Draw(n=1) { Loop, %n% If (Deck.HasCards()) this.Cards.Insert(temp:=Deck.Cards.Remove(1)) ; to deal from bottom, use Remove() lastDraw := temp.Pip "," Return temp.Pip } } class Player { Hand := new Hand Book := new Cards oRequests := "" ; log pips requested by opponent here

Pip() { For i, Card in this.Hand.Cards s .= Card.Pip "," s:=SubStr(s,1,-1) Sort, s, D, Return s } Pips() { s := this.Pip() Sort, s, UD, Return s } Take(Pip, o) { Player%o%.oRequests := Pip "," Player%o%.oRequests For i, Card in Player%o%.Hand.Cards If (Card.Pip = Pip) this.Hand.Cards.Insert(Card) , toremove .= i "," toremove:=SubStr(toremove,1,-1) Sort, toremove, RND, ; must remove in reverse order Loop, Parse, toremove, `, ; so as not to mess up loop Player%o%.Hand.Cards.Remove(A_LoopField) Return toremove ? 1 : 0 } Archive() { s := this.Pip() Loop, Parse, s, `, { If (A_LoopField = previous) count++ Else count := 1 If (count = Suits.MaxIndex()) ; normally 4 { toarchive := A_LoopField Break } previous := A_LoopField } If (toarchive) { For i, Card in this.Hand.Cards If (Card.Pip = toarchive) this.Book.Cards.Insert(Card) , toremove .= i "," toremove:=SubStr(toremove,1,-1) Sort, toremove, RND, ; must remove in reverse order Loop, Parse, toremove, `, ; so as not to mess up loop this.Hand.Cards.Remove(A_LoopField) } Return 0 } } class Human extends Player { Choose(o) { InputBox, Pip, Enter a rank to request from opponent. , % "Your cards: " this.Hand.Show(1) . "`nYour books: " this.Book.Show(1) . "`nAI's books: " Player%o%.Book.Show(1) . "`nEnter rank: " this.Pips() , , 900 Return Pip } } class AI extends Player { Choose(o) { Static Pip ; last asked s := this.Pip() Loop, Parse, s, `, { If (A_LoopField = previous) count++ Else count := 1 Random, rand, 0, 2 If (count > oldcount - rand//2 && count < Suits.MaxIndex()) oldcount := count , IHaveMostOf := A_LoopField previous := A_LoopField } ChoicePrefs := this.oRequests . this.Hand.lastDraw . IHaveMostOf . "," . s this.Hand.lastDraw := "" Loop, Parse, ChoicePrefs, `, If A_LoopField in % this.Pips() If (A_LoopField != Pip) ; don't repeat last asked { Pip := A_LoopField Break } Msgbox, , Opponent requests a rank from you. , % "Your cards: " Player%o%.Hand.Show(1) . "`nYour books: " Player%o%.Book.Show(1) . "`nAI's books: " this.Book.Show(1) . "`n`n`nRequested rank: " Pip Return Pip } }</lang>