doFile("names.io") Suits := Object clone do ( hearts := 3 asCharacter dimonds := 4 asCharacter clubs := 5 asCharacter spades := 6 asCharacter all := list(hearts, dimonds, clubs, spades) ) Face := Object clone do ( type := "Face" setValue := method(value, self value := value; self) setName := method(name, self name := name; self) compare := method(rhs, if(self value < rhs value, -1, if(self value > rhs value, 1, 0)) ) shortName := method( if(self name type == "String", self name splitAt(1) at(0), self name asString ) ) ) Faces := list(2,3,4,5,6,7,8,9,"x (10)","jack","queen","king","ace") map(i, v, Face clone setValue(i) setName(v)) Card := Object clone do ( type := "Card" setSuit := method(suit, self suit := suit; self) setFace := method(face, self face := face; self) name := method( self face shortName .. self suit ) asString := method(self name) print := method( self name print ) #compare := method( rhs, self face compare(rhs face) ) less := method( rhs, self face value < rhs face value ) ) Card clone setSuit(Suits hearts) setFace(Faces at(7)) CardHolder := Object clone do ( type := "CardHolder" init := method(self cards := list()) count := method(self cards count) isEmpty := method(self count == 0) hasCards := method(if(self isEmpty, Nil, self count)) add := method(card, self cards add(card)) pop := method(self cards pop) take := method(holder, self add(holder pop)) give := method(holder, holder add(self pop)) takeAll := method(holder, while(holder hasCards, self take(holder))) giveAll := method(holder, while(self hasCards, self give(holder))) sort := method( self cards sortBy(block(a,b, a less(b))); self ) reverse := method( self cards := self cards reverse) append := method( holder, self cards addList(holder cards) holder cards empty ) ) Deck := CardHolder clone do ( type := "Deck" init := method ( self cards := list() Suits all foreach(i, suit, Faces foreach(j, face, card := Card clone setSuit(suit) setFace(face) self cards add(card) ) ) ) print := method( showList(self cards) ) shuffle := method( self cards randomize; self ) ) cardsAsString := block(cards, result := "" cards foreach(i, card, if(i != 0, result := result append(" ")) result := result append(card asString) ) if(result length == 0, "- ", result) ) Stack := CardHolder clone do ( type := "Stack" proto := CardHolder init := method(self cards := list()) top := method(self cards at(self cards count - 1)) second := method(self cards at(self cards count - 2)) asString := method( cardsAsString(self cards) ) print := method( self asString print ) hasSecond := method( self cards count >= 2 ) ) TableAnalysis := Object clone do ( init := method( self suits := Map clone self secondSuits := Map clone self empties := list() ) hasEmpties := method(self empties count > 0) anEmpty := method(self empties at(0)) add := method(stack, if(stack hasCards, ( groupBySuit(stack) if (stack hasSecond, groupSecondsBySuit(stack)) ), ( self empties add(stack) ) ) ) groupBySuit := method(stack, suit := stack top suit current := self suits at(suit) or list() self suits atPut(suit, current add(stack)) ) groupSecondsBySuit := method(stack, suit := stack second suit current := self secondSuits at(suit) or list() self secondSuits atPut(suit, current add(stack)) ) which := method( smallest := Nil self suits foreach(suit, x, if(x count >= 2, #smallest := x at(0) smallest := smallest or x at(0) x foreach(i, s, if (smallest top face value > s top face value, smallest := s ) ) #return smallest ) ) return smallest ) whichMove := method ( if( hasEmpties, largest := Nil self secondSuits foreach(suit, seconds, x := self suits at(suit) if(x, seconds foreach(i, stack, largest = largest or stack if (largest top face value < stack top face value, largest := stack ) ) ) ) return largest ) ) ) Table := Object clone do ( type := "Table" init := method( self stacks := list(Stack clone, Stack clone, Stack clone, Stack clone) ) deal := method(deck, self stacks foreach(i, stack, stack take(deck)) self verbosePrint self ) verbosePrint := method( if(Lobby hasSlot("verbose") and Lobby verbose, system("cls") self print wait(Lobby verbose) ) ) print := method( self stacks foreach(i, stack, writeln(stack asString)) writeln self ) suitCounts := method( result := TableAnalysis clone self stacks foreach(i, stack, result add(stack)) result ) remove := method(discards, while( 1, stack := self suitCounts which if(stack == Nil, return self) stack give(discards) self verbosePrint ) ) move := method( analysis := self suitCounts stack := analysis whichMove #writeln("whichMove = ", stack) if(stack, analysis anEmpty take(stack) self verbosePrint return 1 ) return Nil ) giveAll := method(holder, self stacks foreach(i, stack, stack giveAll(holder)) ) addTo := method(holder, self stacks foreach(i, stack, holder append(stack)) ) ) rate := Object clone do ( games := 0 wins := 0 percentage := method( 100 * wins / games ) win := method( games = games + 1; wins = wins + 1 ) loss := method( games = games + 1; return games - wins ) ) simplePlay := block(deck, table, discards, #deck shuffle while(deck hasCards, table deal(deck) remove(discards) while(table move, table remove(discards)) ) score := 52 - 4 - discards count # 0 means you won #writeln(score) if (score == 0, rate win, rate loss) score ) simple := block( deck := Deck clone table := Table clone discards := CardHolder clone deck shuffle simplePlay(deck, table, discards) ) clean := block( Lobby removeSlot("deck") Lobby removeSlot("table") Lobby removeSlot("discards") ) mkDeck := block( Lobby deck := if(Lobby hasSlot("deck"), deck, Deck clone) Lobby table := if(Lobby hasSlot("table"), table, Table clone) Lobby discards := if(Lobby hasSlot("discards"), discards, CardHolder clone) ) newDeck := block( clean mkDeck ) batch := block(n, mkDeck deck shuffle for(i, 0, n-1, s := simplePlay(deck, table, discards) writeln(s) if(i mod(10) == 0, writeln(rate percentage)) deck append(discards) table addTo(deck) deck reverse ) rate print ) a := block(Lobby doFile("aces.io"))