From fce7449de279dc3587497b2048d88013bcfbae27 Mon Sep 17 00:00:00 2001 From: lieuraymond Date: Sun, 12 Jan 2020 01:28:24 -0800 Subject: [PATCH 01/18] Created lieur folder --- projects/lieur/README.md | 1 + projects/lieur/dominion/Dominion.py | 762 +++++++++++++++++++++ projects/lieur/dominion/README.md | 10 + projects/lieur/dominion/REPLdominion.py | 853 ++++++++++++++++++++++++ projects/lieur/dominion/playDominion.py | 119 ++++ 5 files changed, 1745 insertions(+) create mode 100644 projects/lieur/README.md create mode 100644 projects/lieur/dominion/Dominion.py create mode 100644 projects/lieur/dominion/README.md create mode 100644 projects/lieur/dominion/REPLdominion.py create mode 100644 projects/lieur/dominion/playDominion.py diff --git a/projects/lieur/README.md b/projects/lieur/README.md new file mode 100644 index 0000000..fe8676d --- /dev/null +++ b/projects/lieur/README.md @@ -0,0 +1 @@ +#Raymond Lieu, lieur \ No newline at end of file diff --git a/projects/lieur/dominion/Dominion.py b/projects/lieur/dominion/Dominion.py new file mode 100644 index 0000000..6a0a534 --- /dev/null +++ b/projects/lieur/dominion/Dominion.py @@ -0,0 +1,762 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue Oct 13 15:26:55 2015 + +@author: tfleck +""" +import random +from collections import Counter, OrderedDict +from operator import itemgetter +import re +import pandas + +class Card(): + def __init__(self,name,category,cost,buypower,vpoints): + self.name = name + self.category = category + self.cost = cost + self.buypower = buypower + self.vpoints = vpoints + def react(self,player): + return False + +class Coin_card(Card): + def __init__(self,name,cost,buypower): + Card.__init__(self,name,"coin",cost,buypower,0) + +class Copper(Coin_card): + def __init__(self): + Coin_card.__init__(self,"Copper",0,1) + +class Silver(Coin_card): + def __init__(self): + Coin_card.__init__(self,"Silver",3,2) + +class Gold(Coin_card): + def __init__(self): + Coin_card.__init__(self,"Gold",6,3) + +class Victory_card(Card): + def __init__(self,name,cost,vpoints): + Card.__init__(self,name,"victory",cost,0,vpoints) + +class Estate(Victory_card): + def __init__(self): + Victory_card.__init__(self,"Estate",2,1) + +class Duchy(Victory_card): + def __init__(self): + Victory_card.__init__(self,"Duchy",5,3) + +class Province(Victory_card): + def __init__(self): + Victory_card.__init__(self,"Province",8,6) + +class Gardens(Victory_card): + def __init__(self): + Victory_card.__init__(self,"Gardens",4,0) + +class Curse(Card): + def __init__(self): + Card.__init__(self,"Curse","curse",0,0,-1) + +class Action_card(Card): + def __init__(self,name,cost,actions,cards,buys,coins): + Card.__init__(self,name,"action",cost,0,0) + self.actions = actions + self.cards = cards + self.buys = buys + self.coins = coins + def use(self,player,trash): + player.played.append(self) + player.hand.remove(self) + def augment(self,player): + player.actions+=self.actions + player.buys+=self.buys + player.purse+=self.coins + for i in range(self.cards): + player.draw() + def play(self,player,players,supply,trash): + pass + +class Woodcutter(Action_card): + def __init__(self): + Action_card.__init__(self,"Woodcutter",3,0,0,1,2) + +class Smithy(Action_card): + def __init__(self): + Action_card.__init__(self,"Smithy",4,0,3,0,0) + +class Laboratory(Action_card): + def __init__(self): + Action_card.__init__(self,"Laboratory",5,1,2,0,0) + +class Village(Action_card): + def __init__(self): + Action_card.__init__(self,"Village",3,2,1,0,0) + +class Festival(Action_card): + def __init__(self): + Action_card.__init__(self,"Festival",5,2,0,1,2) + +class Market(Action_card): + def __init__(self): + Action_card.__init__(self,"Market",5,1,1,1,1) + +class Chancellor(Action_card): + def __init__(self): + Action_card.__init__(self,"Chancellor",3,0,0,0,2) + def play(self,player,players,supply,trash): + if player.yesnoinput('Would you like to discard your entire deck?'): + player.discard = player.discard + player.deck + player.deck = [] + +class Workshop(Action_card): + def __init__(self): + Action_card.__init__(self,"Workshop",3,0,0,0,0) + def play(self,player,players,supply,trash): + player.gaincard(supply,4) + +class Moneylender(Action_card): + def __init__(self): + Action_card.__init__(self,"Moneylender",4,0,0,0,0) + def play(self,player,players,supply,trash): + c = getcard("Copper",supply,player.hand,"your hand") + if c: + trash.append(c) + player.hand.remove(c) + player.purse += 3 + +class Chapel(Action_card): + def __init__(self): + Action_card.__init__(self,"Chapel",2,0,0,0,0) + def play(self,player,players,supply,trash): + trashed=0 + while trashed<4 and len(player.hand)>0: + trashcard = input("Choose a card from your hand to trash: ") + if not trashcard: + break + c = getcard(trashcard,supply,player.hand,"your hand") + if c: + trash.append(c) + player.hand.remove(c) + trashed+=1 + +class Cellar(Action_card): + def __init__(self): + Action_card.__init__(self,"Cellar",2,1,0,0,0) + def play(self,player,players,supply,trash): + discarded=0 + while len(player.hand)>0: + dis_card=input("Choose a card from your hand to discard: ") + if not dis_card: + break + c = getcard(dis_card,supply,player.hand,"your hand") + if c: + player.discard.append(c) + player.hand.remove(c) + discarded+=1 + for j in range(discarded): + player.draw() + +class Remodel(Action_card): + def __init__(self): + Action_card.__init__(self,"Remodel",4,0,0,0,0) + def play(self,player,players,supply,trash): + while len(player.hand)>0: + this_card = input("Choose a card from your hand to remodel: ") + c = getcard(this_card,supply,player.hand,"your hand") + if c: + trash.append(c) + player.hand.remove(c) + player.gaincard(supply,c.cost+2) + break + +class Adventurer(Action_card): + def __init__(self): + Action_card.__init__(self,"Adventurer",6,0,0,0,0) + def play(self,player,players,supply,trash): + coins_added = 0 + while (player.deck or player.discard) and coins_added <2: + player.draw() + if player.hand[-1].category == "coin": + coins_added +=1 + else: + player.aside.append(player.hand.pop()) + +class Feast(Action_card): + def __init__(self): + Action_card.__init__(self,"Feast",4,0,0,0,0) + def use(self,player,trash): + trash.append(self) + player.hand.remove(self) + def play(self,player,players,supply,trash): + player.gaincard(supply,5) + +class Mine(Action_card): + def __init__(self): + Action_card.__init__(self,"Mine",5,0,0,0,0) + def play(self,player,players,supply,trash): + while "coin" in catinlist(player.hand): + this_card = input("Choose a coin from your hand to upgrade: ") + c = getcard(this_card,supply,player.hand,"your hand",["coin"]) + if c: + trash.append(c) + player.hand.remove(c) + while c.cost>2 or len(supply["Copper"])>0 or len(supply["Silver"])>0: + pick = input("Choose a coin to gain. Any coin up to " + str(c.cost+3)+": ") + g = getcard(pick,supply,categories=["coin"],upto=c.cost+3) + if g: + player.hand.append(g) + supply[pick].remove(g) + break + break + +class Library(Action_card): + def __init__(self): + Action_card.__init__(self,"Library",5,0,0,0,0) + def play(self,player,players,supply,trash): + while (player.deck or player.discard) and len(player.hand) <7: + player.draw(player.hold) + if (player.hold[-1].category == "action" and not player.yesnoinput("You drew " + player.hold[-1].name + ". Would you like to keep it?",", add to my hand", ", set it aside")): + player.aside.append(player.hold.pop()) + else: + player.hand.append(player.hold.pop()) + +class Moat(Action_card): + def __init__(self): + Action_card.__init__(self,"Moat",2,0,2,0,0) + def react(self,player): + player.show() + return player.yesnoinput(player.name + ", you have a " + self.name + + " in your hand. Do you want to block the attack?") + +class Council_Room(Action_card): + def __init__(self): + Action_card.__init__(self,"Council Room",5,0,3,1,0) + def play(self,this_player,players,supply,trash): + for player in players: + player.draw() + +class Witch(Action_card): + def __init__(self): + Action_card.__init__(self,"Witch",5,0,2,0,0) + def play(self,this_player,players,supply,trash): + if len(supply["Curse"])>0: + for player in players: + if player==this_player: + pass + else: + for c in player.hand: + if c.react(player): + break + else: + if len(supply["Curse"])>0: + player.discard.append(supply["Curse"].pop()) + +class Bureaucrat(Action_card): + def __init__(self): + Action_card.__init__(self,"Bureaucrat",4,0,0,0,0) + def play(self,this_player,players,supply,trash): + if len(supply["Silver"])>0: + this_player.deck.insert(0,supply["Silver"].pop()) + for player in players: + if (not player==this_player) and ("victory" in catinlist(player.hand)): + for c in player.hand: + if c.react(player): + break + else: + player.show() + while True: + putback = player.choose_discard(player.name + ", which victory card" + + " do you want to put on top of your deck?\n--> ") + c = getcard(putback,supply,player.hand,"your hand",["victory"]) + if c: + player.hand.remove(c) + player.deck.insert(0,c) + break + +class Militia(Action_card): + def __init__(self): + Action_card.__init__(self,"Militia",4,0,0,0,2) + def play(self,this_player,players,supply,trash): + for player in players: + if (not player==this_player) and len(player.hand)>3: + for c in player.hand: + if c.react(player): + break + else: + player.show() + while len(player.hand)>3: + dis_card=player.choose_discard(player.name + ", choose a card from your hand to discard: ") + if dis_card: + c = getcard(dis_card,supply,player.hand,"your hand") + if c: + player.hand.remove(c) + player.discard.append(c) + +class Spy(Action_card): + def __init__(self): + Action_card.__init__(self,"Spy",4,1,1,0,0) + def play(self,this_player,players,supply,trash): + for player in players: + for c in player.hand: + if c.react(player): + break + else: + b = player.draw([]) + if not b: + continue + else: + print("The first card in the deck of " + player.name + " is " + b.name) + if this_player.yesnoinput(this_player.name + ", do you want " + player.name + " to discard this?", + ", discard",", keep"): + player.discard.append(b) + else: + player.deck.insert(0,b) + #check logic of this structure + +class Thief(Action_card): + def __init__(self): + Action_card.__init__(self,"Thief",4,0,0,0,0) + def play(self,this_player,players,supply,trash): + for player in players: + if player == this_player: + continue + for c in player.hand: + if c.react(player): + break + else: + for i in range(2): + player.draw(player.hold) + print( player.name, namesinlist(player.hold)) + if "coin" in catinlist(player.hold): + while True: + burn = input("Which card would you like " + player.name + " to trash?\n-->") + c = getcard(burn,supply,player.hold," the top 2 cards",["coin"]) + if c: + player.hold.remove(c) + break + if this_player.yesnoinput("Do you want to steal it?",", it's mine!",", leave it in the trash."): + this_player.discard.append(c) + else: + trash.append(c) + player.discard=player.discard+player.hold + player.hold = [] + +class Throne_Room(Action_card): + def __init__(self): + Action_card.__init__(self,"Throne Room",4,0,0,0,0) + def play(self,player,players,supply,trash): + if "action" in catinlist(player.hand): + while True: + double = input("What card would you like to double?\n--> ") + c = getcard(double,supply,player.hand," your hand",["action"]) + if c: + c.use(player,trash) + c.augment(player) + c.play(player,players,supply,trash) + player.show() + c.augment(player) + c.play(player,players,supply,trash) + break + + +class Player(): + def __init__(self,name): + self.name = name + self.hand = [] + self.deck = [Copper()]*7 + [Estate()]*3 + random.shuffle(self.deck) + self.played = [] + self.discard = [] + self.aside = [] + self.hold = [] + for i in range(5): + self.draw() + + def other(self): + return self.played+self.discard+self.hold+self.aside + def stack(self): + return (self.deck + self.hand + self.played + self.discard + self.aside + self.hold) + def draw(self,dest=None): + #defualt destination is player's hand + if dest==None: + dest = self.hand + #Replenish deck if necessary. + if len(self.deck)==0: + self.deck = self.discard + self.discard = [] + random.shuffle(self.deck) + #If deck has cards, add card to destination list + if len(self.deck)>0: + c = self.deck.pop(0) + dest.append(c) + return c + def turn(self,players,supply,trash): + self.show() + self.actions = 1 + self.buys = 1 + self.purse = 0 + #action phase + while self.actions>0 and 'action' in catinlist(self.hand): + playthis = input("Which card would you like to play? You have " + + str(self.actions) + " action(s). \n-Hit enter for no play. --> ") + if playthis: + c = getcard(playthis,supply,self.hand,"your hand",['action']) + if c: + self.actions = self.actions - 1 + c.use(self,trash) + c.augment(self) + c.play(self,players,supply,trash) + self.show() + else: + self.actions=0 + #buy phase + for c in self.hand: + self.purse += c.buypower + while self.buys>0: + buy_string = "Buying power is " + str(self.purse) + ". You have " + str(self.buys) + " buy" + if self.buys>1: + buy_string += "s" + buy_string += "." + print( buy_string) + purchase = input("What would you like to purchase? -Hit enter for no purchase.-\n--> ") + if not purchase: + break + else: + c = getcard(purchase,supply,upto=self.purse) + if c: + self.discard.append(supply[purchase].pop()) + self.buys = self.buys -1 + self.purse = self.purse - c.cost + + #cleanup phase + self.discard = self.discard + self.played + self.hand + self.aside + self.played = [] + self.hand = [] + self.aside = [] + for i in range(5): + self.draw() + + def gaincard(self,supply,upto): + while True: + gain = input("What would you like to get? Any card up to " + str(upto) + "\n--> ") + c = getcard(gain,supply,upto=upto) + if c: + self.discard.append(c) + supply[gain].remove(c) + break + def yesnoinput(self,prompt,yesstring='',nostring=''): + print(prompt + "\n1 - Yes" + yesstring + "\n0 - No" + nostring) + while True: + r = input("--> ") + if r == "0": + return False + if r == "1": + return True + + def choose_discard(self,prompt): + return input(prompt) + + def show(self): + print (self.name) + print ("hand:", ", ".join(sorted(namesinlist(self.hand)))) + if len(self.deck)>0: + print ("deck (alphabetical order):", ", ".join(sorted(namesinlist(self.deck)))) + if len(self.discard)>0: + print ("discard:", ", ".join(sorted(namesinlist(self.discard)))) + if len(self.played)>0: + print ("played:", ", ".join(sorted(namesinlist(self.played)))) + if len(self.aside)>0: + print ("aside:", ", ".join(sorted(namesinlist(self.aside)))) + print ("\r") + + def action_balance(self): + balance = 0 + for c in self.stack(): + if c.category == "action": + balance = balance - 1 + c.actions + return 70*balance / len(self.stack()) + + def cardsummary(self): + summary = {} + for c in self.stack(): + if c.name in summary: + summary[c.name] += 1 + else: + summary[c.name] = 1 + summary['VICTORY POINTS']=self.calcpoints() + return summary + + def calcpoints(self): + tally = 0 + gardens = 0 + n = 0 + for c in self.stack(): + tally += c.vpoints + n += 1 + if c.name == "Gardens": + gardens+=1 + return tally + n//10 * gardens + +class ComputerPlayer(Player): + def __init__(self,name): + Player.__init__(self,name) + self.index = 0 + self.buygaintable = [] + #beginning and middle of game + self.buygaintable1 = ["Province","Gold","Laboratory","Festival","Witch", + "Council Room","Market","Militia","Adventurer","Smithy","Bureaucrat","Silver","Moat",""] + #end of game + self.buygaintable2 = ["Province","Gardens","Duchy","Estate","Gold","Silver",""] + #beginning and middle of the game, too many action cards + self.buygaintable3 = ["Province","Gold","Festival","Laboratory","Market","Village", + "Silver",""] + self.playtable1 = ["Village","Festival","Market","Laboratory","Witch", + "Council Room","Militia","Adventurer","Smithy","Bureaucrat","Moat",""] + self.discardtable1 = ["Gardens","Duchy","Province","Estate","Curse","Copper", + "Village","Bureaucrat","Silver","Militia","Smithy","Council Room","Witch", + "Festival","Market","Adventurer","Laboratory","Gold","Moat"] + + def turn(self,players,supply,trash): + self.show() + self.actions = 1 + self.buys = 1 + self.purse = 0 + #action phase + self.index = 0 + while self.actions>0 and 'action' in catinlist(self.hand): + playthis = self.playtable1[self.index] + if playthis: + c = self.getcard(playthis,supply,self.hand,"your hand",['action']) + if c: + print (self.name + " plays " + c.name) + self.actions = self.actions - 1 + c.use(self,trash) + self.index=0 + c.augment(self) + c.play(self,players,supply,trash) + self.show() + else: + self.index += 1 + else: + self.actions=0 + #buy phase + if len(supply["Province"])>len(players)+totalbuypower(self.deck)/8: + if self.action_balance()<-10: + self.buygaintable = self.buygaintable3 + else: + self.buygaintable = self.buygaintable1 + else: + self.buygaintable = self.buygaintable2 + self.index = 0 + for c in self.hand: + self.purse += c.buypower + while self.buys>0: + purchase = self.buygaintable[self.index] + if not purchase: + break + else: + c = self.getcard(purchase,supply,upto=self.purse) + if c: + self.discard.append(supply[purchase].pop()) + self.index = 0 + self.buys = self.buys -1 + self.purse = self.purse - c.cost + print (self.name + " bought " + c.name) + else: + self.index += 1 + + #cleanup phase + self.discard = self.discard + self.played + self.hand + self.aside + self.played = [] + self.hand = [] + self.aside = [] + for i in range(5): + self.draw() + + def getcard(self,name,supply,target_list=None,target_name= "the supply anymore",categories=['action','coin','curse','victory'],upto=100): + if not name in supply: + #print name + " is not in this game." + return None + if not target_list: + target_list = supply[name] + nameslist = namesinlist(target_list) + if not name in nameslist: + #print "There is no " + name + " in " + target_name + return None + i = nameslist.index(name) + c = target_list[i] + if c.category not in categories: + catstring = categories[0] + for i in categories[1:]: + catstring = catstring + " or " + categories[i] + #print name + " is not a " + catstring + " card." + return None + if c.cost > upto: + #print name + " costs " + str(c.cost) + return None + return c + + def choose_discard(self,prompt): + index = 0 + while True: + dis_card = self.discardtable1[index] + c = self.getcard(dis_card,[dis_card],self.hand) + if c: + return c.name + else: + index+=1 + + def yesnoinput(self,prompt,yesstring='',nostring=''): + return True + + def show(self): + pass + +class TablePlayer(ComputerPlayer): + def __init__(self,name): + ComputerPlayer.__init__(self,name) + self.index=0 + self.buygaintable=[] + q=re.match(r'([a-zA-Z]+)(\d+)',name) + if q: + self.number = q.group(2) + else: + print(name) + self.playtable1 = ["Village","Festival","Market","Laboratory","Witch", + "Council Room","Militia","Adventurer","Smithy","Bureaucrat","Moat",""] + self.discardtable1 = ["Gardens","Duchy","Province","Estate","Curse","Copper", + "Village","Bureaucrat","Silver","Militia","Smithy","Council Room","Witch", + "Festival","Market","Adventurer","Laboratory","Gold","Moat"] + + def turn(self,players,supply,trash): + self.show() + self.actions = 1 + self.buys = 1 + self.purse = 0 + #action phase + self.index = 0 + while self.actions>0 and 'action' in catinlist(self.hand): + playthis = self.playtable1[self.index] + if playthis: + c = self.getcard(playthis,supply,self.hand,"your hand",['action']) + if c: + #print (self.name + " plays " + c.name) + self.actions = self.actions - 1 + c.use(self,trash) + self.index=0 + c.augment(self) + c.play(self,players,supply,trash) + self.show() + else: + self.index += 1 + else: + self.actions=0 + #buy phase + v= self.number + csvstring = r"Dominionbuy" + str(v) + ".csv" + buydf=pandas.read_csv(csvstring,na_filter=False) + sortedbuydf=buydf.sort_values("Buyvalues",ascending=False) + ranktable = sortedbuydf.Cardname + self.index = 0 + for c in self.hand: + self.purse += c.buypower + while self.buys>0: + purchase = ranktable.iloc[self.index] + if not purchase: + break + else: + c = self.getcard(purchase,supply,upto=self.purse) + if c: + self.discard.append(supply[purchase].pop()) + self.index = 0 + self.buys = self.buys -1 + self.purse = self.purse - c.cost + else: + self.index += 1 + + #cleanup phase + self.discard = self.discard + self.played + self.hand + self.aside + self.played = [] + self.hand = [] + self.aside = [] + for i in range(5): + self.draw() + + +def gameover(supply): + if len(supply["Province"])==0: + return True + out = 0 + for stack in supply: + if len(supply[stack])==0: + out+=1 + if out>=3: + return True + return False + +def namesinlist(cardlist): + namelist = [] + for c in cardlist: + namelist.append(c.name) + return namelist + +def catinlist(cardlist): + catlist = [] + for c in cardlist: + catlist.append(c.category) + return catlist + +def getcard(name,supply,target_list=None,target_name= "the supply anymore",categories=['action','coin','curse','victory'],upto=100): + if not name in supply: + print( name + " is not in this game.") + return None + if not target_list: + target_list = supply[name] + nameslist = namesinlist(target_list) + if not name in nameslist: + print ("There is no " + name + " in " + target_name) + return None + i = nameslist.index(name) + c = target_list[i] + if c.category not in categories: + catstring = categories[0] + for i in categories[1:]: + catstring = catstring + " or " + categories[i] + print (name + " is not a " + catstring + " card.") + return None + if c.cost > upto: + print (name + " costs " + str(c.cost)) + return None + return c + +def totalbuypower(cardlist): + TBP = 0 + for c in cardlist: + TBP += c.buypower + if c.category == "action": + TBP += c.coins + return TBP + +def cardsummaries(players): + cardsums={} + for player in players: + cardsums[player.name]=player.cardsummary() + cardsdf = pandas.DataFrame(cardsums).fillna(0).sort_index() + vp=cardsdf.loc[['VICTORY POINTS']] + cardsdf.drop(['VICTORY POINTS'],inplace=True) + return pandas.concat([cardsdf,vp],axis=0).fillna(0).astype(int) + +def countsupply(supply,form): + return [len(supply[a]) for a in form] + +def countcards(cards,form): + dcount = Counter(namesinlist(cards)) + return [dcount[a] for a in form] + +def rankcards(form,vector): + od = OrderedDict(zip(form,vector)) + sd = OrderedDict(sorted(od.items(),key = itemgetter(1),reverse=True)) + return list(sd.keys()) \ No newline at end of file diff --git a/projects/lieur/dominion/README.md b/projects/lieur/dominion/README.md new file mode 100644 index 0000000..9e00834 --- /dev/null +++ b/projects/lieur/dominion/README.md @@ -0,0 +1,10 @@ +# Dominion +complete Dominion game in python, text-only + +Dominion is a popular deck-building game, for 2-4 players. Each card in the deck gives a player points or money, or lets a player perform a certain action when played. Each player tries to get the most points before the end of the game. As of July 2016, I have only programmed the base version. + +There are two versions of the game--one that uses a module and a main page, and one that includes all the code in one main page, useful for sharing with a friend who doesn't have python. (It can be executed in an online REPL, hence the name.) + +The list of players is hard-coded, so edit to play. Add a * at the beginning of the name for a computer player. + +The computer (currently) plays a very simple direct strategy. Its main advantage is that is has a perfect memory of every transaction, and an accurate, dispassionate calculation of when the game is likely to end. diff --git a/projects/lieur/dominion/REPLdominion.py b/projects/lieur/dominion/REPLdominion.py new file mode 100644 index 0000000..5499972 --- /dev/null +++ b/projects/lieur/dominion/REPLdominion.py @@ -0,0 +1,853 @@ +import random +from collections import Counter, OrderedDict +from operator import itemgetter +import re +import pandas + +class Card(): + def __init__(self,name,category,cost,buypower,vpoints): + self.name = name + self.category = category + self.cost = cost + self.buypower = buypower + self.vpoints = vpoints + def react(self,player): + return False + +class Coin_card(Card): + def __init__(self,name,cost,buypower): + Card.__init__(self,name,"coin",cost,buypower,0) + +class Copper(Coin_card): + def __init__(self): + Coin_card.__init__(self,"Copper",0,1) + +class Silver(Coin_card): + def __init__(self): + Coin_card.__init__(self,"Silver",3,2) + +class Gold(Coin_card): + def __init__(self): + Coin_card.__init__(self,"Gold",6,3) + +class Victory_card(Card): + def __init__(self,name,cost,vpoints): + Card.__init__(self,name,"victory",cost,0,vpoints) + +class Estate(Victory_card): + def __init__(self): + Victory_card.__init__(self,"Estate",2,1) + +class Duchy(Victory_card): + def __init__(self): + Victory_card.__init__(self,"Duchy",5,3) + +class Province(Victory_card): + def __init__(self): + Victory_card.__init__(self,"Province",8,6) + +class Garden(Victory_card): + def __init__(self): + Victory_card.__init__(self,"Garden",4,0) + +class Curse(Card): + def __init__(self): + Card.__init__(self,"Curse","curse",0,0,-1) + +class Action_card(Card): + def __init__(self,name,cost,actions,cards,buys,coins): + Card.__init__(self,name,"action",cost,0,0) + self.actions = actions + self.cards = cards + self.buys = buys + self.coins = coins + def use(self,player,trash): + player.played.append(self) + player.hand.remove(self) + def augment(self,player): + player.actions+=self.actions + player.buys+=self.buys + player.purse+=self.coins + for i in range(self.cards): + player.draw() + def play(self,player,players,supply,trash): + pass + +class Woodcutter(Action_card): + def __init__(self): + Action_card.__init__(self,"Woodcutter",3,0,0,1,2) + +class Smithy(Action_card): + def __init__(self): + Action_card.__init__(self,"Smithy",4,0,3,0,0) + +class Laboratory(Action_card): + def __init__(self): + Action_card.__init__(self,"Laboratory",5,1,2,0,0) + +class Village(Action_card): + def __init__(self): + Action_card.__init__(self,"Village",3,2,1,0,0) + +class Festival(Action_card): + def __init__(self): + Action_card.__init__(self,"Festival",5,2,0,1,2) + +class Market(Action_card): + def __init__(self): + Action_card.__init__(self,"Market",5,1,1,1,1) + +class Chancellor(Action_card): + def __init__(self): + Action_card.__init__(self,"Chancellor",3,0,0,0,2) + def play(self,player,players,supply,trash): + if player.yesnoinput('Would you like to discard your entire deck?'): + player.discard = player.discard + player.deck + player.deck = [] + +class Workshop(Action_card): + def __init__(self): + Action_card.__init__(self,"Workshop",3,0,0,0,0) + def play(self,player,players,supply,trash): + player.gaincard(supply,4) + +class Moneylender(Action_card): + def __init__(self): + Action_card.__init__(self,"Moneylender",4,0,0,0,0) + def play(self,player,players,supply,trash): + c = getcard("Copper",supply,player.hand,"your hand") + if c: + trash.append(c) + player.hand.remove(c) + player.purse += 3 + +class Chapel(Action_card): + def __init__(self): + Action_card.__init__(self,"Chapel",2,0,0,0,0) + def play(self,player,players,supply,trash): + trashed=0 + while trashed<4 and len(player.hand)>0: + trashcard = input("Choose a card from your hand to trash: ") + if not trashcard: + break + c = getcard(trashcard,supply,player.hand,"your hand") + if c: + trash.append(c) + player.hand.remove(c) + trashed+=1 + +class Cellar(Action_card): + def __init__(self): + Action_card.__init__(self,"Cellar",2,1,0,0,0) + def play(self,player,players,supply,trash): + discarded=0 + while len(player.hand)>0: + dis_card=input("Choose a card from your hand to discard: ") + if not dis_card: + break + c = getcard(dis_card,supply,player.hand,"your hand") + if c: + player.discard.append(c) + player.hand.remove(c) + discarded+=1 + for j in range(discarded): + player.draw() + +class Remodel(Action_card): + def __init__(self): + Action_card.__init__(self,"Remodel",4,0,0,0,0) + def play(self,player,players,supply,trash): + while len(player.hand)>0: + this_card = input("Choose a card from your hand to remodel: ") + c = getcard(this_card,supply,player.hand,"your hand") + if c: + trash.append(c) + player.hand.remove(c) + player.gaincard(supply,c.cost+2) + break + +class Adventurer(Action_card): + def __init__(self): + Action_card.__init__(self,"Adventurer",6,0,0,0,0) + def play(self,player,players,supply,trash): + coins_added = 0 + while (player.deck or player.discard) and coins_added <2: + player.draw() + if player.hand[-1].category == "coin": + coins_added +=1 + else: + player.aside.append(player.hand.pop()) + +class Feast(Action_card): + def __init__(self): + Action_card.__init__(self,"Feast",4,0,0,0,0) + def use(self,player,trash): + trash.append(self) + player.hand.remove(self) + def play(self,player,players,supply,trash): + player.gaincard(supply,5) + +class Mine(Action_card): + def __init__(self): + Action_card.__init__(self,"Mine",5,0,0,0,0) + def play(self,player,players,supply,trash): + while "coin" in catinlist(player.hand): + this_card = input("Choose a coin from your hand to upgrade: ") + c = getcard(this_card,supply,player.hand,"your hand",["coin"]) + if c: + trash.append(c) + player.hand.remove(c) + while c.cost>2 or len(supply["Copper"])>0 or len(supply["Silver"])>0: + pick = input("Choose a coin to gain. Any coin up to " + str(c.cost+3)+": ") + g = getcard(pick,supply,categories=["coin"],upto=c.cost+3) + if g: + player.hand.append(g) + supply[pick].remove(g) + break + break + +class Library(Action_card): + def __init__(self): + Action_card.__init__(self,"Library",5,0,0,0,0) + def play(self,player,players,supply,trash): + while (player.deck or player.discard) and len(player.hand) <7: + player.draw(player.hold) + if (player.hold[-1].category == "action" and not player.yesnoinput("You drew " + player.hold[-1].name + ". Would you like to keep it?",", add to my hand", ", set it aside")): + player.aside.append(player.hold.pop()) + else: + player.hand.append(player.hold.pop()) + +class Moat(Action_card): + def __init__(self): + Action_card.__init__(self,"Moat",2,0,2,0,0) + def react(self,player): + player.show() + return player.yesnoinput(player.name + ", you have a " + self.name + + " in your hand. Do you want to block the attack?") + +class Council_Room(Action_card): + def __init__(self): + Action_card.__init__(self,"Council Room",5,0,3,1,0) + def play(self,this_player,players,supply,trash): + for player in players: + player.draw() + +class Witch(Action_card): + def __init__(self): + Action_card.__init__(self,"Witch",5,0,2,0,0) + def play(self,this_player,players,supply,trash): + if len(supply["Curse"])>0: + for player in players: + if player==this_player: + pass + else: + for c in player.hand: + if c.react(player): + break + else: + if len(supply["Curse"])>0: + player.discard.append(supply["Curse"].pop()) + +class Bureaucrat(Action_card): + def __init__(self): + Action_card.__init__(self,"Bureaucrat",4,0,0,0,0) + def play(self,this_player,players,supply,trash): + if len(supply["Silver"])>0: + this_player.deck.insert(0,supply["Silver"].pop()) + for player in players: + if (not player==this_player) and ("victory" in catinlist(player.hand)): + for c in player.hand: + if c.react(player): + break + else: + player.show() + while True: + putback = player.choose_discard(player.name + ", which victory card" + + " do you want to put on top of your deck?\n--> ") + c = getcard(putback,supply,player.hand,"your hand",["victory"]) + if c: + player.hand.remove(c) + player.deck.insert(0,c) + break + +class Militia(Action_card): + def __init__(self): + Action_card.__init__(self,"Militia",4,0,0,0,2) + def play(self,this_player,players,supply,trash): + for player in players: + if (not player==this_player) and len(player.hand)>3: + for c in player.hand: + if c.react(player): + break + else: + player.show() + while len(player.hand)>3: + dis_card=player.choose_discard(player.name + ", choose a card from your hand to discard: ") + if dis_card: + c = getcard(dis_card,supply,player.hand,"your hand") + if c: + player.hand.remove(c) + player.discard.append(c) + +class Spy(Action_card): + def __init__(self): + Action_card.__init__(self,"Spy",4,1,1,0,0) + def play(self,this_player,players,supply,trash): + for player in players: + for c in player.hand: + if c.react(player): + break + else: + b = player.draw([]) + if not b: + continue + else: + print("The first card in the deck of " + player.name + " is " + b.name) + if this_player.yesnoinput(this_player.name + ", do you want " + player.name + " to discard this?", + ", discard",", keep"): + player.discard.append(b) + else: + player.deck.insert(0,b) + #check logic of this structure + +class Thief(Action_card): + def __init__(self): + Action_card.__init__(self,"Thief",4,0,0,0,0) + def play(self,this_player,players,supply,trash): + for player in players: + if player == this_player: + continue + for c in player.hand: + if c.react(player): + break + else: + for i in range(2): + player.draw(player.hold) + print( player.name, namesinlist(player.hold)) + if "coin" in catinlist(player.hold): + while True: + burn = input("Which card would you like " + player.name + " to trash?\n-->") + c = getcard(burn,supply,player.hold," the top 2 cards",["coin"]) + if c: + player.hold.remove(c) + break + if this_player.yesnoinput("Do you want to steal it?",", it's mine!",", leave it in the trash."): + this_player.discard.append(c) + else: + trash.append(c) + player.discard=player.discard+player.hold + player.hold = [] + +class Throne_Room(Action_card): + def __init__(self): + Action_card.__init__(self,"Throne Room",4,0,0,0,0) + def play(self,player,players,supply,trash): + if "action" in catinlist(player.hand): + while True: + double = input("What card would you like to double?\n--> ") + c = getcard(double,supply,player.hand," your hand",["action"]) + if c: + c.use(player,trash) + c.augment(player) + c.play(player,players,supply,trash) + player.show() + c.augment(player) + c.play(player,players,supply,trash) + break + + +class Player(): + def __init__(self,name): + self.name = name + deal = [Copper()]*7 + [Estate()]*3 + random.shuffle(deal) + self.hand = deal[:5] + self.deck = deal[5:] + self.played = [] + self.discard = [] + self.aside = [] + self.hold = [] + random.shuffle(self.deck) + for i in range(5): + self.draw + def other(self): + return self.played+self.discard+self.hold+self.aside + def stack(self): + return (self.deck + self.hand + self.played + self.discard + self.aside + self.hold) + def draw(self,dest=None): + #defualt destination is player's hand + if dest==None: + dest = self.hand + #Replenish deck if necessary. + if len(self.deck)==0: + self.deck = self.discard + self.discard = [] + random.shuffle(self.deck) + #If deck has cards, add card to destination list + if len(self.deck)>0: + c = self.deck.pop(0) + dest.append(c) + return c + def turn(self,players,supply,trash): + self.show() + self.actions = 1 + self.buys = 1 + self.purse = 0 + #action phase + while self.actions>0 and 'action' in catinlist(self.hand): + playthis = input("Which card would you like to play? You have " + + str(self.actions) + " action(s). \n-Hit enter for no play. --> ") + if playthis: + c = getcard(playthis,supply,self.hand,"your hand",['action']) + if c: + self.actions = self.actions - 1 + c.use(self,trash) + c.augment(self) + c.play(self,players,supply,trash) + self.show() + else: + self.actions=0 + #buy phase + for c in self.hand: + self.purse += c.buypower + while self.buys>0: + buy_string = "Buying power is " + str(self.purse) + ". You have " + str(self.buys) + " buy" + if self.buys>1: + buy_string += "s" + buy_string += "." + print( buy_string) + purchase = input("What would you like to purchase? -Hit enter for no purchase.-\n--> ") + if not purchase: + break + else: + c = getcard(purchase,supply,upto=self.purse) + if c: + self.discard.append(supply[purchase].pop()) + self.buys = self.buys -1 + self.purse = self.purse - c.cost + + #cleanup phase + self.discard = self.discard + self.played + self.hand + self.aside + self.played = [] + self.hand = [] + self.aside = [] + for i in range(5): + self.draw() + + def gaincard(self,supply,upto): + while True: + gain = input("What would you like to get? Any card up to " + str(upto) + "\n--> ") + c = getcard(gain,supply,upto=upto) + if c: + self.discard.append(c) + supply[gain].remove(c) + break + def yesnoinput(self,prompt,yesstring='',nostring=''): + print(prompt + "\n1 - Yes" + yesstring + "\n0 - No" + nostring) + while True: + r = input("--> ") + if r == "0": + return False + if r == "1": + return True + + def choose_discard(self,prompt): + return input(prompt) + + def show(self): + print (self.name) + print ("hand: ", namesinlist(self.hand)) + shuffled_deck = namesinlist(self.deck) + random.shuffle(shuffled_deck) + print ("deck (not in order): ", shuffled_deck) + print ("discard: ", namesinlist(self.discard)) + if len(self.played)>0: + print ("played: ", namesinlist(self.played)) + if len(self.aside)>0: + print ("aside: ",namesinlist(self.aside)) + print ("\r") + + def action_balance(self): + balance = 0 + for c in self.stack(): + if c.category == "action": + balance = balance - 1 + c.actions + return 70*balance / len(self.stack()) + + def cardsummary(self): + summary = {} + for c in self.stack(): + if c.name in summary: + summary[c.name] += 1 + else: + summary[c.name] = 1 + return summary + + def calcpoints(self): + tally = 0 + gardens = 0 + n = 0 + for c in self.stack(): + tally += c.vpoints + n += 1 + if c.name == "Garden": + gardens+=1 + return tally + n//10 * gardens + +class ComputerPlayer(Player): + def __init__(self,name): + Player.__init__(self,name) + self.index = 0 + self.buygaintable = [] + #beginning and middle of game + self.buygaintable1 = ["Province","Gold","Laboratory","Festival","Witch", + "Council Room","Market","Militia","Adventurer","Smithy","Bureaucrat","Silver","Moat",""] + #end of game + self.buygaintable2 = ["Province","Garden","Duchy","Estate","Gold","Silver",""] + #beginning and middle of the game, too many action cards + self.buygaintable3 = ["Province","Gold","Festival","Laboratory","Market","Village", + "Silver",""] + self.playtable1 = ["Village","Festival","Market","Laboratory","Witch", + "Council Room","Militia","Adventurer","Smithy","Bureaucrat","Moat",""] + self.discardtable1 = ["Garden","Duchy","Province","Estate","Curse","Copper", + "Village","Bureaucrat","Silver","Militia","Smithy","Council Room","Witch", + "Festival","Market","Adventurer","Laboratory","Gold","Moat"] + + def turn(self,players,supply,trash): + self.show() + self.actions = 1 + self.buys = 1 + self.purse = 0 + #action phase + self.index = 0 + while self.actions>0 and 'action' in catinlist(self.hand): + playthis = self.playtable1[self.index] + if playthis: + c = self.getcard(playthis,supply,self.hand,"your hand",['action']) + if c: + #print (self.name + " plays " + c.name) + self.actions = self.actions - 1 + c.use(self,trash) + self.index=0 + c.augment(self) + c.play(self,players,supply,trash) + self.show() + else: + self.index += 1 + else: + self.actions=0 + #buy phase + if len(supply["Province"])>len(players)+totalbuypower(self.deck)/8: + if self.action_balance()<-10: + self.buygaintable = self.buygaintable3 + else: + self.buygaintable = self.buygaintable1 + else: + self.buygaintable = self.buygaintable2 + self.index = 0 + for c in self.hand: + self.purse += c.buypower + while self.buys>0: + purchase = self.buygaintable[self.index] + if not purchase: + break + else: + c = self.getcard(purchase,supply,upto=self.purse) + if c: + self.discard.append(supply[purchase].pop()) + self.index = 0 + self.buys = self.buys -1 + self.purse = self.purse - c.cost + #print (self.name + " bought " + c.name) + else: + self.index += 1 + + #cleanup phase + self.discard = self.discard + self.played + self.hand + self.aside + self.played = [] + self.hand = [] + self.aside = [] + for i in range(5): + self.draw() + + def getcard(self,name,supply,target_list=None,target_name= "the supply anymore",categories=['action','coin','curse','victory'],upto=100): + if not name in supply: + #print name + " is not in this game." + return None + if not target_list: + target_list = supply[name] + nameslist = namesinlist(target_list) + if not name in nameslist: + #print "There is no " + name + " in " + target_name + return None + i = nameslist.index(name) + c = target_list[i] + if c.category not in categories: + catstring = categories[0] + for i in categories[1:]: + catstring = catstring + " or " + categories[i] + #print name + " is not a " + catstring + " card." + return None + if c.cost > upto: + #print name + " costs " + str(c.cost) + return None + return c + + def choose_discard(self,prompt): + index = 0 + while True: + dis_card = self.discardtable1[index] + c = self.getcard(dis_card,[dis_card],self.hand) + if c: + return c.name + else: + index+=1 + + def yesnoinput(self,prompt,yesstring='',nostring=''): + return True + + def show(self): + pass + +class TablePlayer(ComputerPlayer): + def __init__(self,name): + ComputerPlayer.__init__(self,name) + self.index=0 + self.buygaintable=[] + q=re.match(r'([a-zA-Z]+)(\d+)',name) + if q: + self.number = q.group(2) + else: + print(name) + self.playtable1 = ["Village","Festival","Market","Laboratory","Witch", + "Council Room","Militia","Adventurer","Smithy","Bureaucrat","Moat",""] + self.discardtable1 = ["Garden","Duchy","Province","Estate","Curse","Copper", + "Village","Bureaucrat","Silver","Militia","Smithy","Council Room","Witch", + "Festival","Market","Adventurer","Laboratory","Gold","Moat"] + + def turn(self,players,supply,trash): + self.show() + self.actions = 1 + self.buys = 1 + self.purse = 0 + #action phase + self.index = 0 + while self.actions>0 and 'action' in catinlist(self.hand): + playthis = self.playtable1[self.index] + if playthis: + c = self.getcard(playthis,supply,self.hand,"your hand",['action']) + if c: + #print (self.name + " plays " + c.name) + self.actions = self.actions - 1 + c.use(self,trash) + self.index=0 + c.augment(self) + c.play(self,players,supply,trash) + self.show() + else: + self.index += 1 + else: + self.actions=0 + #buy phase + v= self.number + csvstring = r"Dominionbuy" + str(v) + ".csv" + buydf=pandas.read_csv(csvstring,na_filter=False) + sortedbuydf=buydf.sort_values("Buyvalues",ascending=False) + ranktable = sortedbuydf.Cardname + self.index = 0 + for c in self.hand: + self.purse += c.buypower + while self.buys>0: + purchase = ranktable.iloc[self.index] + if not purchase: + break + else: + c = self.getcard(purchase,supply,upto=self.purse) + if c: + self.discard.append(supply[purchase].pop()) + self.index = 0 + self.buys = self.buys -1 + self.purse = self.purse - c.cost + else: + self.index += 1 + + #cleanup phase + self.discard = self.discard + self.played + self.hand + self.aside + self.played = [] + self.hand = [] + self.aside = [] + for i in range(5): + self.draw() + + +def gameover(supply): + if len(supply["Province"])==0: + return True + out = 0 + for stack in supply: + if len(supply[stack])==0: + out+=1 + if out>=3: + return True + return False + +def namesinlist(cardlist): + namelist = [] + for c in cardlist: + namelist.append(c.name) + return namelist + +def catinlist(cardlist): + catlist = [] + for c in cardlist: + catlist.append(c.category) + return catlist + +def getcard(name,supply,target_list=None,target_name= "the supply anymore",categories=['action','coin','curse','victory'],upto=100): + if not name in supply: + print( name + " is not in this game.") + return None + if not target_list: + target_list = supply[name] + nameslist = namesinlist(target_list) + if not name in nameslist: + print ("There is no " + name + " in " + target_name) + return None + i = nameslist.index(name) + c = target_list[i] + if c.category not in categories: + catstring = categories[0] + for i in categories[1:]: + catstring = catstring + " or " + categories[i] + print (name + " is not a " + catstring + " card.") + return None + if c.cost > upto: + print (name + " costs " + str(c.cost)) + return None + return c + +def totalbuypower(cardlist): + TBP = 0 + for c in cardlist: + TBP += c.buypower + if c.category == "action": + TBP += c.coins + return TBP + +def countsupply(supply,form): + return [len(supply[a]) for a in form] + +def countcards(cards,form): + dcount = Counter(namesinlist(cards)) + return [dcount[a] for a in form] + +def rankcards(form,vector): + od = OrderedDict(zip(form,vector)) + sd = OrderedDict(sorted(od.items(),key = itemgetter(1),reverse=True)) + return list(sd.keys()) + +#import Dominion +#import random +from collections import defaultdict + +#Get player names +player_names = ["Timothy","*Grover","*Elmo"] + +#number of curses and victory cards +if len(player_names)>2: + nV=12 +else: + nV=8 +nC = -10 + 10 * len(player_names) + +#Define box +box = {} +box["Woodcutter"]=[Woodcutter()]*10 +box["Smithy"]=[Smithy()]*10 +box["Laboratory"]=[Laboratory()]*10 +box["Village"]=[Village()]*10 +box["Festival"]=[Festival()]*10 +box["Market"]=[Market()]*10 +box["Chancellor"]=[Chancellor()]*10 +box["Workshop"]=[Workshop()]*10 +box["Moneylender"]=[Moneylender()]*10 +box["Chapel"]=[Chapel()]*10 +box["Cellar"]=[Cellar()]*10 +box["Remodel"]=[Remodel()]*10 +box["Adventurer"]=[Adventurer()]*10 +box["Feast"]=[Feast()]*10 +box["Mine"]=[Mine()]*10 +box["Library"]=[Library()]*10 +box["Garden"]=[Garden()]*nV +box["Moat"]=[Moat()]*10 +box["Council Room"]=[Council_Room()]*10 +box["Witch"]=[Witch()]*10 +box["Bureaucrat"]=[Bureaucrat()]*10 +box["Militia"]=[Militia()]*10 +box["Spy"]=[Spy()]*10 +box["Thief"]=[Thief()]*10 +box["Throne Room"]=[Throne_Room()]*10 + +supply_order = {0:['Curse','Copper'],2:['Estate','Cellar','Chapel','Moat'], + 3:['Silver','Chancellor','Village','Woodcutter','Workshop'], + 4:['Garden','Bureaucrat','Feast','Militia','Moneylender','Remodel','Smithy','Spy','Thief','Throne Room'], + 5:['Duchy','Market','Council Room','Festival','Laboratory','Library','Mine','Witch'], + 6:['Gold','Adventurer'],8:['Province']} + +#Pick 10 cards from box to be in the supply. +boxlist = [k for k in box] +random.shuffle(boxlist) +random10 = boxlist[:10] +supply = defaultdict(list,[(k,box[k]) for k in random10]) + + +#The supply always has these cards +supply["Copper"]=[Copper()]*(60-len(player_names)*7) +supply["Silver"]=[Silver()]*40 +supply["Gold"]=[Gold()]*30 +supply["Estate"]=[Estate()]*nV +supply["Duchy"]=[Duchy()]*nV +supply["Province"]=[Province()]*nV +supply["Curse"]=[Curse()]*nC + +#initialize the trash +trash = [] + +#Costruct the Player objects +players = [] +for name in player_names: + if name[0]=="*": + players.append(ComputerPlayer(name[1:])) + elif name[0]=="^": + players.append(TablePlayer(name[1:])) + else: + players.append(Player(name)) + +#Play the game +turn = 0 +while not gameover(supply): + turn += 1 + print("\r") + for value in supply_order: + print (value) + for stack in supply_order[value]: + if stack in supply: + print (stack, len(supply[stack])) + print("\r") + for player in players: + print (player.name,player.calcpoints()) + print ("\rStart of turn " + str(turn)) + for player in players: + if not gameover(supply): + print("\r") + player.turn(players,supply,trash) + + +#Final score +print ("\r") +for player in players: + print (player.name,player.calcpoints()) + +print ("\n") +for player in players: + print (player.name,player.cardsummary()) \ No newline at end of file diff --git a/projects/lieur/dominion/playDominion.py b/projects/lieur/dominion/playDominion.py new file mode 100644 index 0000000..b4d6021 --- /dev/null +++ b/projects/lieur/dominion/playDominion.py @@ -0,0 +1,119 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue Oct 13 15:42:42 2015 + +@author: tfleck +""" + +import Dominion +import random +from collections import defaultdict + +#Get player names +player_names = ["Annie","*Ben","*Carla"] + +#number of curses and victory cards +if len(player_names)>2: + nV=12 +else: + nV=8 +nC = -10 + 10 * len(player_names) + +#Define box +box = {} +box["Woodcutter"]=[Dominion.Woodcutter()]*10 +box["Smithy"]=[Dominion.Smithy()]*10 +box["Laboratory"]=[Dominion.Laboratory()]*10 +box["Village"]=[Dominion.Village()]*10 +box["Festival"]=[Dominion.Festival()]*10 +box["Market"]=[Dominion.Market()]*10 +box["Chancellor"]=[Dominion.Chancellor()]*10 +box["Workshop"]=[Dominion.Workshop()]*10 +box["Moneylender"]=[Dominion.Moneylender()]*10 +box["Chapel"]=[Dominion.Chapel()]*10 +box["Cellar"]=[Dominion.Cellar()]*10 +box["Remodel"]=[Dominion.Remodel()]*10 +box["Adventurer"]=[Dominion.Adventurer()]*10 +box["Feast"]=[Dominion.Feast()]*10 +box["Mine"]=[Dominion.Mine()]*10 +box["Library"]=[Dominion.Library()]*10 +box["Gardens"]=[Dominion.Gardens()]*nV +box["Moat"]=[Dominion.Moat()]*10 +box["Council Room"]=[Dominion.Council_Room()]*10 +box["Witch"]=[Dominion.Witch()]*10 +box["Bureaucrat"]=[Dominion.Bureaucrat()]*10 +box["Militia"]=[Dominion.Militia()]*10 +box["Spy"]=[Dominion.Spy()]*10 +box["Thief"]=[Dominion.Thief()]*10 +box["Throne Room"]=[Dominion.Throne_Room()]*10 + +supply_order = {0:['Curse','Copper'],2:['Estate','Cellar','Chapel','Moat'], + 3:['Silver','Chancellor','Village','Woodcutter','Workshop'], + 4:['Gardens','Bureaucrat','Feast','Militia','Moneylender','Remodel','Smithy','Spy','Thief','Throne Room'], + 5:['Duchy','Market','Council Room','Festival','Laboratory','Library','Mine','Witch'], + 6:['Gold','Adventurer'],8:['Province']} + +#Pick 10 cards from box to be in the supply. +boxlist = [k for k in box] +random.shuffle(boxlist) +random10 = boxlist[:10] +supply = defaultdict(list,[(k,box[k]) for k in random10]) + + +#The supply always has these cards +supply["Copper"]=[Dominion.Copper()]*(60-len(player_names)*7) +supply["Silver"]=[Dominion.Silver()]*40 +supply["Gold"]=[Dominion.Gold()]*30 +supply["Estate"]=[Dominion.Estate()]*nV +supply["Duchy"]=[Dominion.Duchy()]*nV +supply["Province"]=[Dominion.Province()]*nV +supply["Curse"]=[Dominion.Curse()]*nC + +#initialize the trash +trash = [] + +#Costruct the Player objects +players = [] +for name in player_names: + if name[0]=="*": + players.append(Dominion.ComputerPlayer(name[1:])) + elif name[0]=="^": + players.append(Dominion.TablePlayer(name[1:])) + else: + players.append(Dominion.Player(name)) + +#Play the game +turn = 0 +while not Dominion.gameover(supply): + turn += 1 + print("\r") + for value in supply_order: + print (value) + for stack in supply_order[value]: + if stack in supply: + print (stack, len(supply[stack])) + print("\r") + for player in players: + print (player.name,player.calcpoints()) + print ("\rStart of turn " + str(turn)) + for player in players: + if not Dominion.gameover(supply): + print("\r") + player.turn(players,supply,trash) + + +#Final score +dcs=Dominion.cardsummaries(players) +vp=dcs.loc['VICTORY POINTS'] +vpmax=vp.max() +winners=[] +for i in vp.index: + if vp.loc[i]==vpmax: + winners.append(i) +if len(winners)>1: + winstring= ' and '.join(winners) + ' win!' +else: + winstring = ' '.join([winners[0],'wins!']) + +print("\nGAME OVER!!!\n"+winstring+"\n") +print(dcs) \ No newline at end of file From 395dbfeefca637ffb400af3dadec9c07514831c9 Mon Sep 17 00:00:00 2001 From: lieuraymond Date: Sat, 18 Jan 2020 16:15:19 -0800 Subject: [PATCH 02/18] Add copy of tests --- projects/lieur/dominion/testDominion1.py | 762 +++++++++++++++++++++++ projects/lieur/dominion/testDominion2.py | 762 +++++++++++++++++++++++ 2 files changed, 1524 insertions(+) create mode 100644 projects/lieur/dominion/testDominion1.py create mode 100644 projects/lieur/dominion/testDominion2.py diff --git a/projects/lieur/dominion/testDominion1.py b/projects/lieur/dominion/testDominion1.py new file mode 100644 index 0000000..6a0a534 --- /dev/null +++ b/projects/lieur/dominion/testDominion1.py @@ -0,0 +1,762 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue Oct 13 15:26:55 2015 + +@author: tfleck +""" +import random +from collections import Counter, OrderedDict +from operator import itemgetter +import re +import pandas + +class Card(): + def __init__(self,name,category,cost,buypower,vpoints): + self.name = name + self.category = category + self.cost = cost + self.buypower = buypower + self.vpoints = vpoints + def react(self,player): + return False + +class Coin_card(Card): + def __init__(self,name,cost,buypower): + Card.__init__(self,name,"coin",cost,buypower,0) + +class Copper(Coin_card): + def __init__(self): + Coin_card.__init__(self,"Copper",0,1) + +class Silver(Coin_card): + def __init__(self): + Coin_card.__init__(self,"Silver",3,2) + +class Gold(Coin_card): + def __init__(self): + Coin_card.__init__(self,"Gold",6,3) + +class Victory_card(Card): + def __init__(self,name,cost,vpoints): + Card.__init__(self,name,"victory",cost,0,vpoints) + +class Estate(Victory_card): + def __init__(self): + Victory_card.__init__(self,"Estate",2,1) + +class Duchy(Victory_card): + def __init__(self): + Victory_card.__init__(self,"Duchy",5,3) + +class Province(Victory_card): + def __init__(self): + Victory_card.__init__(self,"Province",8,6) + +class Gardens(Victory_card): + def __init__(self): + Victory_card.__init__(self,"Gardens",4,0) + +class Curse(Card): + def __init__(self): + Card.__init__(self,"Curse","curse",0,0,-1) + +class Action_card(Card): + def __init__(self,name,cost,actions,cards,buys,coins): + Card.__init__(self,name,"action",cost,0,0) + self.actions = actions + self.cards = cards + self.buys = buys + self.coins = coins + def use(self,player,trash): + player.played.append(self) + player.hand.remove(self) + def augment(self,player): + player.actions+=self.actions + player.buys+=self.buys + player.purse+=self.coins + for i in range(self.cards): + player.draw() + def play(self,player,players,supply,trash): + pass + +class Woodcutter(Action_card): + def __init__(self): + Action_card.__init__(self,"Woodcutter",3,0,0,1,2) + +class Smithy(Action_card): + def __init__(self): + Action_card.__init__(self,"Smithy",4,0,3,0,0) + +class Laboratory(Action_card): + def __init__(self): + Action_card.__init__(self,"Laboratory",5,1,2,0,0) + +class Village(Action_card): + def __init__(self): + Action_card.__init__(self,"Village",3,2,1,0,0) + +class Festival(Action_card): + def __init__(self): + Action_card.__init__(self,"Festival",5,2,0,1,2) + +class Market(Action_card): + def __init__(self): + Action_card.__init__(self,"Market",5,1,1,1,1) + +class Chancellor(Action_card): + def __init__(self): + Action_card.__init__(self,"Chancellor",3,0,0,0,2) + def play(self,player,players,supply,trash): + if player.yesnoinput('Would you like to discard your entire deck?'): + player.discard = player.discard + player.deck + player.deck = [] + +class Workshop(Action_card): + def __init__(self): + Action_card.__init__(self,"Workshop",3,0,0,0,0) + def play(self,player,players,supply,trash): + player.gaincard(supply,4) + +class Moneylender(Action_card): + def __init__(self): + Action_card.__init__(self,"Moneylender",4,0,0,0,0) + def play(self,player,players,supply,trash): + c = getcard("Copper",supply,player.hand,"your hand") + if c: + trash.append(c) + player.hand.remove(c) + player.purse += 3 + +class Chapel(Action_card): + def __init__(self): + Action_card.__init__(self,"Chapel",2,0,0,0,0) + def play(self,player,players,supply,trash): + trashed=0 + while trashed<4 and len(player.hand)>0: + trashcard = input("Choose a card from your hand to trash: ") + if not trashcard: + break + c = getcard(trashcard,supply,player.hand,"your hand") + if c: + trash.append(c) + player.hand.remove(c) + trashed+=1 + +class Cellar(Action_card): + def __init__(self): + Action_card.__init__(self,"Cellar",2,1,0,0,0) + def play(self,player,players,supply,trash): + discarded=0 + while len(player.hand)>0: + dis_card=input("Choose a card from your hand to discard: ") + if not dis_card: + break + c = getcard(dis_card,supply,player.hand,"your hand") + if c: + player.discard.append(c) + player.hand.remove(c) + discarded+=1 + for j in range(discarded): + player.draw() + +class Remodel(Action_card): + def __init__(self): + Action_card.__init__(self,"Remodel",4,0,0,0,0) + def play(self,player,players,supply,trash): + while len(player.hand)>0: + this_card = input("Choose a card from your hand to remodel: ") + c = getcard(this_card,supply,player.hand,"your hand") + if c: + trash.append(c) + player.hand.remove(c) + player.gaincard(supply,c.cost+2) + break + +class Adventurer(Action_card): + def __init__(self): + Action_card.__init__(self,"Adventurer",6,0,0,0,0) + def play(self,player,players,supply,trash): + coins_added = 0 + while (player.deck or player.discard) and coins_added <2: + player.draw() + if player.hand[-1].category == "coin": + coins_added +=1 + else: + player.aside.append(player.hand.pop()) + +class Feast(Action_card): + def __init__(self): + Action_card.__init__(self,"Feast",4,0,0,0,0) + def use(self,player,trash): + trash.append(self) + player.hand.remove(self) + def play(self,player,players,supply,trash): + player.gaincard(supply,5) + +class Mine(Action_card): + def __init__(self): + Action_card.__init__(self,"Mine",5,0,0,0,0) + def play(self,player,players,supply,trash): + while "coin" in catinlist(player.hand): + this_card = input("Choose a coin from your hand to upgrade: ") + c = getcard(this_card,supply,player.hand,"your hand",["coin"]) + if c: + trash.append(c) + player.hand.remove(c) + while c.cost>2 or len(supply["Copper"])>0 or len(supply["Silver"])>0: + pick = input("Choose a coin to gain. Any coin up to " + str(c.cost+3)+": ") + g = getcard(pick,supply,categories=["coin"],upto=c.cost+3) + if g: + player.hand.append(g) + supply[pick].remove(g) + break + break + +class Library(Action_card): + def __init__(self): + Action_card.__init__(self,"Library",5,0,0,0,0) + def play(self,player,players,supply,trash): + while (player.deck or player.discard) and len(player.hand) <7: + player.draw(player.hold) + if (player.hold[-1].category == "action" and not player.yesnoinput("You drew " + player.hold[-1].name + ". Would you like to keep it?",", add to my hand", ", set it aside")): + player.aside.append(player.hold.pop()) + else: + player.hand.append(player.hold.pop()) + +class Moat(Action_card): + def __init__(self): + Action_card.__init__(self,"Moat",2,0,2,0,0) + def react(self,player): + player.show() + return player.yesnoinput(player.name + ", you have a " + self.name + + " in your hand. Do you want to block the attack?") + +class Council_Room(Action_card): + def __init__(self): + Action_card.__init__(self,"Council Room",5,0,3,1,0) + def play(self,this_player,players,supply,trash): + for player in players: + player.draw() + +class Witch(Action_card): + def __init__(self): + Action_card.__init__(self,"Witch",5,0,2,0,0) + def play(self,this_player,players,supply,trash): + if len(supply["Curse"])>0: + for player in players: + if player==this_player: + pass + else: + for c in player.hand: + if c.react(player): + break + else: + if len(supply["Curse"])>0: + player.discard.append(supply["Curse"].pop()) + +class Bureaucrat(Action_card): + def __init__(self): + Action_card.__init__(self,"Bureaucrat",4,0,0,0,0) + def play(self,this_player,players,supply,trash): + if len(supply["Silver"])>0: + this_player.deck.insert(0,supply["Silver"].pop()) + for player in players: + if (not player==this_player) and ("victory" in catinlist(player.hand)): + for c in player.hand: + if c.react(player): + break + else: + player.show() + while True: + putback = player.choose_discard(player.name + ", which victory card" + + " do you want to put on top of your deck?\n--> ") + c = getcard(putback,supply,player.hand,"your hand",["victory"]) + if c: + player.hand.remove(c) + player.deck.insert(0,c) + break + +class Militia(Action_card): + def __init__(self): + Action_card.__init__(self,"Militia",4,0,0,0,2) + def play(self,this_player,players,supply,trash): + for player in players: + if (not player==this_player) and len(player.hand)>3: + for c in player.hand: + if c.react(player): + break + else: + player.show() + while len(player.hand)>3: + dis_card=player.choose_discard(player.name + ", choose a card from your hand to discard: ") + if dis_card: + c = getcard(dis_card,supply,player.hand,"your hand") + if c: + player.hand.remove(c) + player.discard.append(c) + +class Spy(Action_card): + def __init__(self): + Action_card.__init__(self,"Spy",4,1,1,0,0) + def play(self,this_player,players,supply,trash): + for player in players: + for c in player.hand: + if c.react(player): + break + else: + b = player.draw([]) + if not b: + continue + else: + print("The first card in the deck of " + player.name + " is " + b.name) + if this_player.yesnoinput(this_player.name + ", do you want " + player.name + " to discard this?", + ", discard",", keep"): + player.discard.append(b) + else: + player.deck.insert(0,b) + #check logic of this structure + +class Thief(Action_card): + def __init__(self): + Action_card.__init__(self,"Thief",4,0,0,0,0) + def play(self,this_player,players,supply,trash): + for player in players: + if player == this_player: + continue + for c in player.hand: + if c.react(player): + break + else: + for i in range(2): + player.draw(player.hold) + print( player.name, namesinlist(player.hold)) + if "coin" in catinlist(player.hold): + while True: + burn = input("Which card would you like " + player.name + " to trash?\n-->") + c = getcard(burn,supply,player.hold," the top 2 cards",["coin"]) + if c: + player.hold.remove(c) + break + if this_player.yesnoinput("Do you want to steal it?",", it's mine!",", leave it in the trash."): + this_player.discard.append(c) + else: + trash.append(c) + player.discard=player.discard+player.hold + player.hold = [] + +class Throne_Room(Action_card): + def __init__(self): + Action_card.__init__(self,"Throne Room",4,0,0,0,0) + def play(self,player,players,supply,trash): + if "action" in catinlist(player.hand): + while True: + double = input("What card would you like to double?\n--> ") + c = getcard(double,supply,player.hand," your hand",["action"]) + if c: + c.use(player,trash) + c.augment(player) + c.play(player,players,supply,trash) + player.show() + c.augment(player) + c.play(player,players,supply,trash) + break + + +class Player(): + def __init__(self,name): + self.name = name + self.hand = [] + self.deck = [Copper()]*7 + [Estate()]*3 + random.shuffle(self.deck) + self.played = [] + self.discard = [] + self.aside = [] + self.hold = [] + for i in range(5): + self.draw() + + def other(self): + return self.played+self.discard+self.hold+self.aside + def stack(self): + return (self.deck + self.hand + self.played + self.discard + self.aside + self.hold) + def draw(self,dest=None): + #defualt destination is player's hand + if dest==None: + dest = self.hand + #Replenish deck if necessary. + if len(self.deck)==0: + self.deck = self.discard + self.discard = [] + random.shuffle(self.deck) + #If deck has cards, add card to destination list + if len(self.deck)>0: + c = self.deck.pop(0) + dest.append(c) + return c + def turn(self,players,supply,trash): + self.show() + self.actions = 1 + self.buys = 1 + self.purse = 0 + #action phase + while self.actions>0 and 'action' in catinlist(self.hand): + playthis = input("Which card would you like to play? You have " + + str(self.actions) + " action(s). \n-Hit enter for no play. --> ") + if playthis: + c = getcard(playthis,supply,self.hand,"your hand",['action']) + if c: + self.actions = self.actions - 1 + c.use(self,trash) + c.augment(self) + c.play(self,players,supply,trash) + self.show() + else: + self.actions=0 + #buy phase + for c in self.hand: + self.purse += c.buypower + while self.buys>0: + buy_string = "Buying power is " + str(self.purse) + ". You have " + str(self.buys) + " buy" + if self.buys>1: + buy_string += "s" + buy_string += "." + print( buy_string) + purchase = input("What would you like to purchase? -Hit enter for no purchase.-\n--> ") + if not purchase: + break + else: + c = getcard(purchase,supply,upto=self.purse) + if c: + self.discard.append(supply[purchase].pop()) + self.buys = self.buys -1 + self.purse = self.purse - c.cost + + #cleanup phase + self.discard = self.discard + self.played + self.hand + self.aside + self.played = [] + self.hand = [] + self.aside = [] + for i in range(5): + self.draw() + + def gaincard(self,supply,upto): + while True: + gain = input("What would you like to get? Any card up to " + str(upto) + "\n--> ") + c = getcard(gain,supply,upto=upto) + if c: + self.discard.append(c) + supply[gain].remove(c) + break + def yesnoinput(self,prompt,yesstring='',nostring=''): + print(prompt + "\n1 - Yes" + yesstring + "\n0 - No" + nostring) + while True: + r = input("--> ") + if r == "0": + return False + if r == "1": + return True + + def choose_discard(self,prompt): + return input(prompt) + + def show(self): + print (self.name) + print ("hand:", ", ".join(sorted(namesinlist(self.hand)))) + if len(self.deck)>0: + print ("deck (alphabetical order):", ", ".join(sorted(namesinlist(self.deck)))) + if len(self.discard)>0: + print ("discard:", ", ".join(sorted(namesinlist(self.discard)))) + if len(self.played)>0: + print ("played:", ", ".join(sorted(namesinlist(self.played)))) + if len(self.aside)>0: + print ("aside:", ", ".join(sorted(namesinlist(self.aside)))) + print ("\r") + + def action_balance(self): + balance = 0 + for c in self.stack(): + if c.category == "action": + balance = balance - 1 + c.actions + return 70*balance / len(self.stack()) + + def cardsummary(self): + summary = {} + for c in self.stack(): + if c.name in summary: + summary[c.name] += 1 + else: + summary[c.name] = 1 + summary['VICTORY POINTS']=self.calcpoints() + return summary + + def calcpoints(self): + tally = 0 + gardens = 0 + n = 0 + for c in self.stack(): + tally += c.vpoints + n += 1 + if c.name == "Gardens": + gardens+=1 + return tally + n//10 * gardens + +class ComputerPlayer(Player): + def __init__(self,name): + Player.__init__(self,name) + self.index = 0 + self.buygaintable = [] + #beginning and middle of game + self.buygaintable1 = ["Province","Gold","Laboratory","Festival","Witch", + "Council Room","Market","Militia","Adventurer","Smithy","Bureaucrat","Silver","Moat",""] + #end of game + self.buygaintable2 = ["Province","Gardens","Duchy","Estate","Gold","Silver",""] + #beginning and middle of the game, too many action cards + self.buygaintable3 = ["Province","Gold","Festival","Laboratory","Market","Village", + "Silver",""] + self.playtable1 = ["Village","Festival","Market","Laboratory","Witch", + "Council Room","Militia","Adventurer","Smithy","Bureaucrat","Moat",""] + self.discardtable1 = ["Gardens","Duchy","Province","Estate","Curse","Copper", + "Village","Bureaucrat","Silver","Militia","Smithy","Council Room","Witch", + "Festival","Market","Adventurer","Laboratory","Gold","Moat"] + + def turn(self,players,supply,trash): + self.show() + self.actions = 1 + self.buys = 1 + self.purse = 0 + #action phase + self.index = 0 + while self.actions>0 and 'action' in catinlist(self.hand): + playthis = self.playtable1[self.index] + if playthis: + c = self.getcard(playthis,supply,self.hand,"your hand",['action']) + if c: + print (self.name + " plays " + c.name) + self.actions = self.actions - 1 + c.use(self,trash) + self.index=0 + c.augment(self) + c.play(self,players,supply,trash) + self.show() + else: + self.index += 1 + else: + self.actions=0 + #buy phase + if len(supply["Province"])>len(players)+totalbuypower(self.deck)/8: + if self.action_balance()<-10: + self.buygaintable = self.buygaintable3 + else: + self.buygaintable = self.buygaintable1 + else: + self.buygaintable = self.buygaintable2 + self.index = 0 + for c in self.hand: + self.purse += c.buypower + while self.buys>0: + purchase = self.buygaintable[self.index] + if not purchase: + break + else: + c = self.getcard(purchase,supply,upto=self.purse) + if c: + self.discard.append(supply[purchase].pop()) + self.index = 0 + self.buys = self.buys -1 + self.purse = self.purse - c.cost + print (self.name + " bought " + c.name) + else: + self.index += 1 + + #cleanup phase + self.discard = self.discard + self.played + self.hand + self.aside + self.played = [] + self.hand = [] + self.aside = [] + for i in range(5): + self.draw() + + def getcard(self,name,supply,target_list=None,target_name= "the supply anymore",categories=['action','coin','curse','victory'],upto=100): + if not name in supply: + #print name + " is not in this game." + return None + if not target_list: + target_list = supply[name] + nameslist = namesinlist(target_list) + if not name in nameslist: + #print "There is no " + name + " in " + target_name + return None + i = nameslist.index(name) + c = target_list[i] + if c.category not in categories: + catstring = categories[0] + for i in categories[1:]: + catstring = catstring + " or " + categories[i] + #print name + " is not a " + catstring + " card." + return None + if c.cost > upto: + #print name + " costs " + str(c.cost) + return None + return c + + def choose_discard(self,prompt): + index = 0 + while True: + dis_card = self.discardtable1[index] + c = self.getcard(dis_card,[dis_card],self.hand) + if c: + return c.name + else: + index+=1 + + def yesnoinput(self,prompt,yesstring='',nostring=''): + return True + + def show(self): + pass + +class TablePlayer(ComputerPlayer): + def __init__(self,name): + ComputerPlayer.__init__(self,name) + self.index=0 + self.buygaintable=[] + q=re.match(r'([a-zA-Z]+)(\d+)',name) + if q: + self.number = q.group(2) + else: + print(name) + self.playtable1 = ["Village","Festival","Market","Laboratory","Witch", + "Council Room","Militia","Adventurer","Smithy","Bureaucrat","Moat",""] + self.discardtable1 = ["Gardens","Duchy","Province","Estate","Curse","Copper", + "Village","Bureaucrat","Silver","Militia","Smithy","Council Room","Witch", + "Festival","Market","Adventurer","Laboratory","Gold","Moat"] + + def turn(self,players,supply,trash): + self.show() + self.actions = 1 + self.buys = 1 + self.purse = 0 + #action phase + self.index = 0 + while self.actions>0 and 'action' in catinlist(self.hand): + playthis = self.playtable1[self.index] + if playthis: + c = self.getcard(playthis,supply,self.hand,"your hand",['action']) + if c: + #print (self.name + " plays " + c.name) + self.actions = self.actions - 1 + c.use(self,trash) + self.index=0 + c.augment(self) + c.play(self,players,supply,trash) + self.show() + else: + self.index += 1 + else: + self.actions=0 + #buy phase + v= self.number + csvstring = r"Dominionbuy" + str(v) + ".csv" + buydf=pandas.read_csv(csvstring,na_filter=False) + sortedbuydf=buydf.sort_values("Buyvalues",ascending=False) + ranktable = sortedbuydf.Cardname + self.index = 0 + for c in self.hand: + self.purse += c.buypower + while self.buys>0: + purchase = ranktable.iloc[self.index] + if not purchase: + break + else: + c = self.getcard(purchase,supply,upto=self.purse) + if c: + self.discard.append(supply[purchase].pop()) + self.index = 0 + self.buys = self.buys -1 + self.purse = self.purse - c.cost + else: + self.index += 1 + + #cleanup phase + self.discard = self.discard + self.played + self.hand + self.aside + self.played = [] + self.hand = [] + self.aside = [] + for i in range(5): + self.draw() + + +def gameover(supply): + if len(supply["Province"])==0: + return True + out = 0 + for stack in supply: + if len(supply[stack])==0: + out+=1 + if out>=3: + return True + return False + +def namesinlist(cardlist): + namelist = [] + for c in cardlist: + namelist.append(c.name) + return namelist + +def catinlist(cardlist): + catlist = [] + for c in cardlist: + catlist.append(c.category) + return catlist + +def getcard(name,supply,target_list=None,target_name= "the supply anymore",categories=['action','coin','curse','victory'],upto=100): + if not name in supply: + print( name + " is not in this game.") + return None + if not target_list: + target_list = supply[name] + nameslist = namesinlist(target_list) + if not name in nameslist: + print ("There is no " + name + " in " + target_name) + return None + i = nameslist.index(name) + c = target_list[i] + if c.category not in categories: + catstring = categories[0] + for i in categories[1:]: + catstring = catstring + " or " + categories[i] + print (name + " is not a " + catstring + " card.") + return None + if c.cost > upto: + print (name + " costs " + str(c.cost)) + return None + return c + +def totalbuypower(cardlist): + TBP = 0 + for c in cardlist: + TBP += c.buypower + if c.category == "action": + TBP += c.coins + return TBP + +def cardsummaries(players): + cardsums={} + for player in players: + cardsums[player.name]=player.cardsummary() + cardsdf = pandas.DataFrame(cardsums).fillna(0).sort_index() + vp=cardsdf.loc[['VICTORY POINTS']] + cardsdf.drop(['VICTORY POINTS'],inplace=True) + return pandas.concat([cardsdf,vp],axis=0).fillna(0).astype(int) + +def countsupply(supply,form): + return [len(supply[a]) for a in form] + +def countcards(cards,form): + dcount = Counter(namesinlist(cards)) + return [dcount[a] for a in form] + +def rankcards(form,vector): + od = OrderedDict(zip(form,vector)) + sd = OrderedDict(sorted(od.items(),key = itemgetter(1),reverse=True)) + return list(sd.keys()) \ No newline at end of file diff --git a/projects/lieur/dominion/testDominion2.py b/projects/lieur/dominion/testDominion2.py new file mode 100644 index 0000000..6a0a534 --- /dev/null +++ b/projects/lieur/dominion/testDominion2.py @@ -0,0 +1,762 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue Oct 13 15:26:55 2015 + +@author: tfleck +""" +import random +from collections import Counter, OrderedDict +from operator import itemgetter +import re +import pandas + +class Card(): + def __init__(self,name,category,cost,buypower,vpoints): + self.name = name + self.category = category + self.cost = cost + self.buypower = buypower + self.vpoints = vpoints + def react(self,player): + return False + +class Coin_card(Card): + def __init__(self,name,cost,buypower): + Card.__init__(self,name,"coin",cost,buypower,0) + +class Copper(Coin_card): + def __init__(self): + Coin_card.__init__(self,"Copper",0,1) + +class Silver(Coin_card): + def __init__(self): + Coin_card.__init__(self,"Silver",3,2) + +class Gold(Coin_card): + def __init__(self): + Coin_card.__init__(self,"Gold",6,3) + +class Victory_card(Card): + def __init__(self,name,cost,vpoints): + Card.__init__(self,name,"victory",cost,0,vpoints) + +class Estate(Victory_card): + def __init__(self): + Victory_card.__init__(self,"Estate",2,1) + +class Duchy(Victory_card): + def __init__(self): + Victory_card.__init__(self,"Duchy",5,3) + +class Province(Victory_card): + def __init__(self): + Victory_card.__init__(self,"Province",8,6) + +class Gardens(Victory_card): + def __init__(self): + Victory_card.__init__(self,"Gardens",4,0) + +class Curse(Card): + def __init__(self): + Card.__init__(self,"Curse","curse",0,0,-1) + +class Action_card(Card): + def __init__(self,name,cost,actions,cards,buys,coins): + Card.__init__(self,name,"action",cost,0,0) + self.actions = actions + self.cards = cards + self.buys = buys + self.coins = coins + def use(self,player,trash): + player.played.append(self) + player.hand.remove(self) + def augment(self,player): + player.actions+=self.actions + player.buys+=self.buys + player.purse+=self.coins + for i in range(self.cards): + player.draw() + def play(self,player,players,supply,trash): + pass + +class Woodcutter(Action_card): + def __init__(self): + Action_card.__init__(self,"Woodcutter",3,0,0,1,2) + +class Smithy(Action_card): + def __init__(self): + Action_card.__init__(self,"Smithy",4,0,3,0,0) + +class Laboratory(Action_card): + def __init__(self): + Action_card.__init__(self,"Laboratory",5,1,2,0,0) + +class Village(Action_card): + def __init__(self): + Action_card.__init__(self,"Village",3,2,1,0,0) + +class Festival(Action_card): + def __init__(self): + Action_card.__init__(self,"Festival",5,2,0,1,2) + +class Market(Action_card): + def __init__(self): + Action_card.__init__(self,"Market",5,1,1,1,1) + +class Chancellor(Action_card): + def __init__(self): + Action_card.__init__(self,"Chancellor",3,0,0,0,2) + def play(self,player,players,supply,trash): + if player.yesnoinput('Would you like to discard your entire deck?'): + player.discard = player.discard + player.deck + player.deck = [] + +class Workshop(Action_card): + def __init__(self): + Action_card.__init__(self,"Workshop",3,0,0,0,0) + def play(self,player,players,supply,trash): + player.gaincard(supply,4) + +class Moneylender(Action_card): + def __init__(self): + Action_card.__init__(self,"Moneylender",4,0,0,0,0) + def play(self,player,players,supply,trash): + c = getcard("Copper",supply,player.hand,"your hand") + if c: + trash.append(c) + player.hand.remove(c) + player.purse += 3 + +class Chapel(Action_card): + def __init__(self): + Action_card.__init__(self,"Chapel",2,0,0,0,0) + def play(self,player,players,supply,trash): + trashed=0 + while trashed<4 and len(player.hand)>0: + trashcard = input("Choose a card from your hand to trash: ") + if not trashcard: + break + c = getcard(trashcard,supply,player.hand,"your hand") + if c: + trash.append(c) + player.hand.remove(c) + trashed+=1 + +class Cellar(Action_card): + def __init__(self): + Action_card.__init__(self,"Cellar",2,1,0,0,0) + def play(self,player,players,supply,trash): + discarded=0 + while len(player.hand)>0: + dis_card=input("Choose a card from your hand to discard: ") + if not dis_card: + break + c = getcard(dis_card,supply,player.hand,"your hand") + if c: + player.discard.append(c) + player.hand.remove(c) + discarded+=1 + for j in range(discarded): + player.draw() + +class Remodel(Action_card): + def __init__(self): + Action_card.__init__(self,"Remodel",4,0,0,0,0) + def play(self,player,players,supply,trash): + while len(player.hand)>0: + this_card = input("Choose a card from your hand to remodel: ") + c = getcard(this_card,supply,player.hand,"your hand") + if c: + trash.append(c) + player.hand.remove(c) + player.gaincard(supply,c.cost+2) + break + +class Adventurer(Action_card): + def __init__(self): + Action_card.__init__(self,"Adventurer",6,0,0,0,0) + def play(self,player,players,supply,trash): + coins_added = 0 + while (player.deck or player.discard) and coins_added <2: + player.draw() + if player.hand[-1].category == "coin": + coins_added +=1 + else: + player.aside.append(player.hand.pop()) + +class Feast(Action_card): + def __init__(self): + Action_card.__init__(self,"Feast",4,0,0,0,0) + def use(self,player,trash): + trash.append(self) + player.hand.remove(self) + def play(self,player,players,supply,trash): + player.gaincard(supply,5) + +class Mine(Action_card): + def __init__(self): + Action_card.__init__(self,"Mine",5,0,0,0,0) + def play(self,player,players,supply,trash): + while "coin" in catinlist(player.hand): + this_card = input("Choose a coin from your hand to upgrade: ") + c = getcard(this_card,supply,player.hand,"your hand",["coin"]) + if c: + trash.append(c) + player.hand.remove(c) + while c.cost>2 or len(supply["Copper"])>0 or len(supply["Silver"])>0: + pick = input("Choose a coin to gain. Any coin up to " + str(c.cost+3)+": ") + g = getcard(pick,supply,categories=["coin"],upto=c.cost+3) + if g: + player.hand.append(g) + supply[pick].remove(g) + break + break + +class Library(Action_card): + def __init__(self): + Action_card.__init__(self,"Library",5,0,0,0,0) + def play(self,player,players,supply,trash): + while (player.deck or player.discard) and len(player.hand) <7: + player.draw(player.hold) + if (player.hold[-1].category == "action" and not player.yesnoinput("You drew " + player.hold[-1].name + ". Would you like to keep it?",", add to my hand", ", set it aside")): + player.aside.append(player.hold.pop()) + else: + player.hand.append(player.hold.pop()) + +class Moat(Action_card): + def __init__(self): + Action_card.__init__(self,"Moat",2,0,2,0,0) + def react(self,player): + player.show() + return player.yesnoinput(player.name + ", you have a " + self.name + + " in your hand. Do you want to block the attack?") + +class Council_Room(Action_card): + def __init__(self): + Action_card.__init__(self,"Council Room",5,0,3,1,0) + def play(self,this_player,players,supply,trash): + for player in players: + player.draw() + +class Witch(Action_card): + def __init__(self): + Action_card.__init__(self,"Witch",5,0,2,0,0) + def play(self,this_player,players,supply,trash): + if len(supply["Curse"])>0: + for player in players: + if player==this_player: + pass + else: + for c in player.hand: + if c.react(player): + break + else: + if len(supply["Curse"])>0: + player.discard.append(supply["Curse"].pop()) + +class Bureaucrat(Action_card): + def __init__(self): + Action_card.__init__(self,"Bureaucrat",4,0,0,0,0) + def play(self,this_player,players,supply,trash): + if len(supply["Silver"])>0: + this_player.deck.insert(0,supply["Silver"].pop()) + for player in players: + if (not player==this_player) and ("victory" in catinlist(player.hand)): + for c in player.hand: + if c.react(player): + break + else: + player.show() + while True: + putback = player.choose_discard(player.name + ", which victory card" + + " do you want to put on top of your deck?\n--> ") + c = getcard(putback,supply,player.hand,"your hand",["victory"]) + if c: + player.hand.remove(c) + player.deck.insert(0,c) + break + +class Militia(Action_card): + def __init__(self): + Action_card.__init__(self,"Militia",4,0,0,0,2) + def play(self,this_player,players,supply,trash): + for player in players: + if (not player==this_player) and len(player.hand)>3: + for c in player.hand: + if c.react(player): + break + else: + player.show() + while len(player.hand)>3: + dis_card=player.choose_discard(player.name + ", choose a card from your hand to discard: ") + if dis_card: + c = getcard(dis_card,supply,player.hand,"your hand") + if c: + player.hand.remove(c) + player.discard.append(c) + +class Spy(Action_card): + def __init__(self): + Action_card.__init__(self,"Spy",4,1,1,0,0) + def play(self,this_player,players,supply,trash): + for player in players: + for c in player.hand: + if c.react(player): + break + else: + b = player.draw([]) + if not b: + continue + else: + print("The first card in the deck of " + player.name + " is " + b.name) + if this_player.yesnoinput(this_player.name + ", do you want " + player.name + " to discard this?", + ", discard",", keep"): + player.discard.append(b) + else: + player.deck.insert(0,b) + #check logic of this structure + +class Thief(Action_card): + def __init__(self): + Action_card.__init__(self,"Thief",4,0,0,0,0) + def play(self,this_player,players,supply,trash): + for player in players: + if player == this_player: + continue + for c in player.hand: + if c.react(player): + break + else: + for i in range(2): + player.draw(player.hold) + print( player.name, namesinlist(player.hold)) + if "coin" in catinlist(player.hold): + while True: + burn = input("Which card would you like " + player.name + " to trash?\n-->") + c = getcard(burn,supply,player.hold," the top 2 cards",["coin"]) + if c: + player.hold.remove(c) + break + if this_player.yesnoinput("Do you want to steal it?",", it's mine!",", leave it in the trash."): + this_player.discard.append(c) + else: + trash.append(c) + player.discard=player.discard+player.hold + player.hold = [] + +class Throne_Room(Action_card): + def __init__(self): + Action_card.__init__(self,"Throne Room",4,0,0,0,0) + def play(self,player,players,supply,trash): + if "action" in catinlist(player.hand): + while True: + double = input("What card would you like to double?\n--> ") + c = getcard(double,supply,player.hand," your hand",["action"]) + if c: + c.use(player,trash) + c.augment(player) + c.play(player,players,supply,trash) + player.show() + c.augment(player) + c.play(player,players,supply,trash) + break + + +class Player(): + def __init__(self,name): + self.name = name + self.hand = [] + self.deck = [Copper()]*7 + [Estate()]*3 + random.shuffle(self.deck) + self.played = [] + self.discard = [] + self.aside = [] + self.hold = [] + for i in range(5): + self.draw() + + def other(self): + return self.played+self.discard+self.hold+self.aside + def stack(self): + return (self.deck + self.hand + self.played + self.discard + self.aside + self.hold) + def draw(self,dest=None): + #defualt destination is player's hand + if dest==None: + dest = self.hand + #Replenish deck if necessary. + if len(self.deck)==0: + self.deck = self.discard + self.discard = [] + random.shuffle(self.deck) + #If deck has cards, add card to destination list + if len(self.deck)>0: + c = self.deck.pop(0) + dest.append(c) + return c + def turn(self,players,supply,trash): + self.show() + self.actions = 1 + self.buys = 1 + self.purse = 0 + #action phase + while self.actions>0 and 'action' in catinlist(self.hand): + playthis = input("Which card would you like to play? You have " + + str(self.actions) + " action(s). \n-Hit enter for no play. --> ") + if playthis: + c = getcard(playthis,supply,self.hand,"your hand",['action']) + if c: + self.actions = self.actions - 1 + c.use(self,trash) + c.augment(self) + c.play(self,players,supply,trash) + self.show() + else: + self.actions=0 + #buy phase + for c in self.hand: + self.purse += c.buypower + while self.buys>0: + buy_string = "Buying power is " + str(self.purse) + ". You have " + str(self.buys) + " buy" + if self.buys>1: + buy_string += "s" + buy_string += "." + print( buy_string) + purchase = input("What would you like to purchase? -Hit enter for no purchase.-\n--> ") + if not purchase: + break + else: + c = getcard(purchase,supply,upto=self.purse) + if c: + self.discard.append(supply[purchase].pop()) + self.buys = self.buys -1 + self.purse = self.purse - c.cost + + #cleanup phase + self.discard = self.discard + self.played + self.hand + self.aside + self.played = [] + self.hand = [] + self.aside = [] + for i in range(5): + self.draw() + + def gaincard(self,supply,upto): + while True: + gain = input("What would you like to get? Any card up to " + str(upto) + "\n--> ") + c = getcard(gain,supply,upto=upto) + if c: + self.discard.append(c) + supply[gain].remove(c) + break + def yesnoinput(self,prompt,yesstring='',nostring=''): + print(prompt + "\n1 - Yes" + yesstring + "\n0 - No" + nostring) + while True: + r = input("--> ") + if r == "0": + return False + if r == "1": + return True + + def choose_discard(self,prompt): + return input(prompt) + + def show(self): + print (self.name) + print ("hand:", ", ".join(sorted(namesinlist(self.hand)))) + if len(self.deck)>0: + print ("deck (alphabetical order):", ", ".join(sorted(namesinlist(self.deck)))) + if len(self.discard)>0: + print ("discard:", ", ".join(sorted(namesinlist(self.discard)))) + if len(self.played)>0: + print ("played:", ", ".join(sorted(namesinlist(self.played)))) + if len(self.aside)>0: + print ("aside:", ", ".join(sorted(namesinlist(self.aside)))) + print ("\r") + + def action_balance(self): + balance = 0 + for c in self.stack(): + if c.category == "action": + balance = balance - 1 + c.actions + return 70*balance / len(self.stack()) + + def cardsummary(self): + summary = {} + for c in self.stack(): + if c.name in summary: + summary[c.name] += 1 + else: + summary[c.name] = 1 + summary['VICTORY POINTS']=self.calcpoints() + return summary + + def calcpoints(self): + tally = 0 + gardens = 0 + n = 0 + for c in self.stack(): + tally += c.vpoints + n += 1 + if c.name == "Gardens": + gardens+=1 + return tally + n//10 * gardens + +class ComputerPlayer(Player): + def __init__(self,name): + Player.__init__(self,name) + self.index = 0 + self.buygaintable = [] + #beginning and middle of game + self.buygaintable1 = ["Province","Gold","Laboratory","Festival","Witch", + "Council Room","Market","Militia","Adventurer","Smithy","Bureaucrat","Silver","Moat",""] + #end of game + self.buygaintable2 = ["Province","Gardens","Duchy","Estate","Gold","Silver",""] + #beginning and middle of the game, too many action cards + self.buygaintable3 = ["Province","Gold","Festival","Laboratory","Market","Village", + "Silver",""] + self.playtable1 = ["Village","Festival","Market","Laboratory","Witch", + "Council Room","Militia","Adventurer","Smithy","Bureaucrat","Moat",""] + self.discardtable1 = ["Gardens","Duchy","Province","Estate","Curse","Copper", + "Village","Bureaucrat","Silver","Militia","Smithy","Council Room","Witch", + "Festival","Market","Adventurer","Laboratory","Gold","Moat"] + + def turn(self,players,supply,trash): + self.show() + self.actions = 1 + self.buys = 1 + self.purse = 0 + #action phase + self.index = 0 + while self.actions>0 and 'action' in catinlist(self.hand): + playthis = self.playtable1[self.index] + if playthis: + c = self.getcard(playthis,supply,self.hand,"your hand",['action']) + if c: + print (self.name + " plays " + c.name) + self.actions = self.actions - 1 + c.use(self,trash) + self.index=0 + c.augment(self) + c.play(self,players,supply,trash) + self.show() + else: + self.index += 1 + else: + self.actions=0 + #buy phase + if len(supply["Province"])>len(players)+totalbuypower(self.deck)/8: + if self.action_balance()<-10: + self.buygaintable = self.buygaintable3 + else: + self.buygaintable = self.buygaintable1 + else: + self.buygaintable = self.buygaintable2 + self.index = 0 + for c in self.hand: + self.purse += c.buypower + while self.buys>0: + purchase = self.buygaintable[self.index] + if not purchase: + break + else: + c = self.getcard(purchase,supply,upto=self.purse) + if c: + self.discard.append(supply[purchase].pop()) + self.index = 0 + self.buys = self.buys -1 + self.purse = self.purse - c.cost + print (self.name + " bought " + c.name) + else: + self.index += 1 + + #cleanup phase + self.discard = self.discard + self.played + self.hand + self.aside + self.played = [] + self.hand = [] + self.aside = [] + for i in range(5): + self.draw() + + def getcard(self,name,supply,target_list=None,target_name= "the supply anymore",categories=['action','coin','curse','victory'],upto=100): + if not name in supply: + #print name + " is not in this game." + return None + if not target_list: + target_list = supply[name] + nameslist = namesinlist(target_list) + if not name in nameslist: + #print "There is no " + name + " in " + target_name + return None + i = nameslist.index(name) + c = target_list[i] + if c.category not in categories: + catstring = categories[0] + for i in categories[1:]: + catstring = catstring + " or " + categories[i] + #print name + " is not a " + catstring + " card." + return None + if c.cost > upto: + #print name + " costs " + str(c.cost) + return None + return c + + def choose_discard(self,prompt): + index = 0 + while True: + dis_card = self.discardtable1[index] + c = self.getcard(dis_card,[dis_card],self.hand) + if c: + return c.name + else: + index+=1 + + def yesnoinput(self,prompt,yesstring='',nostring=''): + return True + + def show(self): + pass + +class TablePlayer(ComputerPlayer): + def __init__(self,name): + ComputerPlayer.__init__(self,name) + self.index=0 + self.buygaintable=[] + q=re.match(r'([a-zA-Z]+)(\d+)',name) + if q: + self.number = q.group(2) + else: + print(name) + self.playtable1 = ["Village","Festival","Market","Laboratory","Witch", + "Council Room","Militia","Adventurer","Smithy","Bureaucrat","Moat",""] + self.discardtable1 = ["Gardens","Duchy","Province","Estate","Curse","Copper", + "Village","Bureaucrat","Silver","Militia","Smithy","Council Room","Witch", + "Festival","Market","Adventurer","Laboratory","Gold","Moat"] + + def turn(self,players,supply,trash): + self.show() + self.actions = 1 + self.buys = 1 + self.purse = 0 + #action phase + self.index = 0 + while self.actions>0 and 'action' in catinlist(self.hand): + playthis = self.playtable1[self.index] + if playthis: + c = self.getcard(playthis,supply,self.hand,"your hand",['action']) + if c: + #print (self.name + " plays " + c.name) + self.actions = self.actions - 1 + c.use(self,trash) + self.index=0 + c.augment(self) + c.play(self,players,supply,trash) + self.show() + else: + self.index += 1 + else: + self.actions=0 + #buy phase + v= self.number + csvstring = r"Dominionbuy" + str(v) + ".csv" + buydf=pandas.read_csv(csvstring,na_filter=False) + sortedbuydf=buydf.sort_values("Buyvalues",ascending=False) + ranktable = sortedbuydf.Cardname + self.index = 0 + for c in self.hand: + self.purse += c.buypower + while self.buys>0: + purchase = ranktable.iloc[self.index] + if not purchase: + break + else: + c = self.getcard(purchase,supply,upto=self.purse) + if c: + self.discard.append(supply[purchase].pop()) + self.index = 0 + self.buys = self.buys -1 + self.purse = self.purse - c.cost + else: + self.index += 1 + + #cleanup phase + self.discard = self.discard + self.played + self.hand + self.aside + self.played = [] + self.hand = [] + self.aside = [] + for i in range(5): + self.draw() + + +def gameover(supply): + if len(supply["Province"])==0: + return True + out = 0 + for stack in supply: + if len(supply[stack])==0: + out+=1 + if out>=3: + return True + return False + +def namesinlist(cardlist): + namelist = [] + for c in cardlist: + namelist.append(c.name) + return namelist + +def catinlist(cardlist): + catlist = [] + for c in cardlist: + catlist.append(c.category) + return catlist + +def getcard(name,supply,target_list=None,target_name= "the supply anymore",categories=['action','coin','curse','victory'],upto=100): + if not name in supply: + print( name + " is not in this game.") + return None + if not target_list: + target_list = supply[name] + nameslist = namesinlist(target_list) + if not name in nameslist: + print ("There is no " + name + " in " + target_name) + return None + i = nameslist.index(name) + c = target_list[i] + if c.category not in categories: + catstring = categories[0] + for i in categories[1:]: + catstring = catstring + " or " + categories[i] + print (name + " is not a " + catstring + " card.") + return None + if c.cost > upto: + print (name + " costs " + str(c.cost)) + return None + return c + +def totalbuypower(cardlist): + TBP = 0 + for c in cardlist: + TBP += c.buypower + if c.category == "action": + TBP += c.coins + return TBP + +def cardsummaries(players): + cardsums={} + for player in players: + cardsums[player.name]=player.cardsummary() + cardsdf = pandas.DataFrame(cardsums).fillna(0).sort_index() + vp=cardsdf.loc[['VICTORY POINTS']] + cardsdf.drop(['VICTORY POINTS'],inplace=True) + return pandas.concat([cardsdf,vp],axis=0).fillna(0).astype(int) + +def countsupply(supply,form): + return [len(supply[a]) for a in form] + +def countcards(cards,form): + dcount = Counter(namesinlist(cards)) + return [dcount[a] for a in form] + +def rankcards(form,vector): + od = OrderedDict(zip(form,vector)) + sd = OrderedDict(sorted(od.items(),key = itemgetter(1),reverse=True)) + return list(sd.keys()) \ No newline at end of file From 5051b772cc47dc835ef9b20a4cafe7dc36f90652 Mon Sep 17 00:00:00 2001 From: lieuraymond Date: Sat, 18 Jan 2020 16:20:33 -0800 Subject: [PATCH 03/18] Removed wrong files --- projects/lieur/dominion/testDominion1.py | 762 ----------------------- projects/lieur/dominion/testDominion2.py | 762 ----------------------- 2 files changed, 1524 deletions(-) delete mode 100644 projects/lieur/dominion/testDominion1.py delete mode 100644 projects/lieur/dominion/testDominion2.py diff --git a/projects/lieur/dominion/testDominion1.py b/projects/lieur/dominion/testDominion1.py deleted file mode 100644 index 6a0a534..0000000 --- a/projects/lieur/dominion/testDominion1.py +++ /dev/null @@ -1,762 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Tue Oct 13 15:26:55 2015 - -@author: tfleck -""" -import random -from collections import Counter, OrderedDict -from operator import itemgetter -import re -import pandas - -class Card(): - def __init__(self,name,category,cost,buypower,vpoints): - self.name = name - self.category = category - self.cost = cost - self.buypower = buypower - self.vpoints = vpoints - def react(self,player): - return False - -class Coin_card(Card): - def __init__(self,name,cost,buypower): - Card.__init__(self,name,"coin",cost,buypower,0) - -class Copper(Coin_card): - def __init__(self): - Coin_card.__init__(self,"Copper",0,1) - -class Silver(Coin_card): - def __init__(self): - Coin_card.__init__(self,"Silver",3,2) - -class Gold(Coin_card): - def __init__(self): - Coin_card.__init__(self,"Gold",6,3) - -class Victory_card(Card): - def __init__(self,name,cost,vpoints): - Card.__init__(self,name,"victory",cost,0,vpoints) - -class Estate(Victory_card): - def __init__(self): - Victory_card.__init__(self,"Estate",2,1) - -class Duchy(Victory_card): - def __init__(self): - Victory_card.__init__(self,"Duchy",5,3) - -class Province(Victory_card): - def __init__(self): - Victory_card.__init__(self,"Province",8,6) - -class Gardens(Victory_card): - def __init__(self): - Victory_card.__init__(self,"Gardens",4,0) - -class Curse(Card): - def __init__(self): - Card.__init__(self,"Curse","curse",0,0,-1) - -class Action_card(Card): - def __init__(self,name,cost,actions,cards,buys,coins): - Card.__init__(self,name,"action",cost,0,0) - self.actions = actions - self.cards = cards - self.buys = buys - self.coins = coins - def use(self,player,trash): - player.played.append(self) - player.hand.remove(self) - def augment(self,player): - player.actions+=self.actions - player.buys+=self.buys - player.purse+=self.coins - for i in range(self.cards): - player.draw() - def play(self,player,players,supply,trash): - pass - -class Woodcutter(Action_card): - def __init__(self): - Action_card.__init__(self,"Woodcutter",3,0,0,1,2) - -class Smithy(Action_card): - def __init__(self): - Action_card.__init__(self,"Smithy",4,0,3,0,0) - -class Laboratory(Action_card): - def __init__(self): - Action_card.__init__(self,"Laboratory",5,1,2,0,0) - -class Village(Action_card): - def __init__(self): - Action_card.__init__(self,"Village",3,2,1,0,0) - -class Festival(Action_card): - def __init__(self): - Action_card.__init__(self,"Festival",5,2,0,1,2) - -class Market(Action_card): - def __init__(self): - Action_card.__init__(self,"Market",5,1,1,1,1) - -class Chancellor(Action_card): - def __init__(self): - Action_card.__init__(self,"Chancellor",3,0,0,0,2) - def play(self,player,players,supply,trash): - if player.yesnoinput('Would you like to discard your entire deck?'): - player.discard = player.discard + player.deck - player.deck = [] - -class Workshop(Action_card): - def __init__(self): - Action_card.__init__(self,"Workshop",3,0,0,0,0) - def play(self,player,players,supply,trash): - player.gaincard(supply,4) - -class Moneylender(Action_card): - def __init__(self): - Action_card.__init__(self,"Moneylender",4,0,0,0,0) - def play(self,player,players,supply,trash): - c = getcard("Copper",supply,player.hand,"your hand") - if c: - trash.append(c) - player.hand.remove(c) - player.purse += 3 - -class Chapel(Action_card): - def __init__(self): - Action_card.__init__(self,"Chapel",2,0,0,0,0) - def play(self,player,players,supply,trash): - trashed=0 - while trashed<4 and len(player.hand)>0: - trashcard = input("Choose a card from your hand to trash: ") - if not trashcard: - break - c = getcard(trashcard,supply,player.hand,"your hand") - if c: - trash.append(c) - player.hand.remove(c) - trashed+=1 - -class Cellar(Action_card): - def __init__(self): - Action_card.__init__(self,"Cellar",2,1,0,0,0) - def play(self,player,players,supply,trash): - discarded=0 - while len(player.hand)>0: - dis_card=input("Choose a card from your hand to discard: ") - if not dis_card: - break - c = getcard(dis_card,supply,player.hand,"your hand") - if c: - player.discard.append(c) - player.hand.remove(c) - discarded+=1 - for j in range(discarded): - player.draw() - -class Remodel(Action_card): - def __init__(self): - Action_card.__init__(self,"Remodel",4,0,0,0,0) - def play(self,player,players,supply,trash): - while len(player.hand)>0: - this_card = input("Choose a card from your hand to remodel: ") - c = getcard(this_card,supply,player.hand,"your hand") - if c: - trash.append(c) - player.hand.remove(c) - player.gaincard(supply,c.cost+2) - break - -class Adventurer(Action_card): - def __init__(self): - Action_card.__init__(self,"Adventurer",6,0,0,0,0) - def play(self,player,players,supply,trash): - coins_added = 0 - while (player.deck or player.discard) and coins_added <2: - player.draw() - if player.hand[-1].category == "coin": - coins_added +=1 - else: - player.aside.append(player.hand.pop()) - -class Feast(Action_card): - def __init__(self): - Action_card.__init__(self,"Feast",4,0,0,0,0) - def use(self,player,trash): - trash.append(self) - player.hand.remove(self) - def play(self,player,players,supply,trash): - player.gaincard(supply,5) - -class Mine(Action_card): - def __init__(self): - Action_card.__init__(self,"Mine",5,0,0,0,0) - def play(self,player,players,supply,trash): - while "coin" in catinlist(player.hand): - this_card = input("Choose a coin from your hand to upgrade: ") - c = getcard(this_card,supply,player.hand,"your hand",["coin"]) - if c: - trash.append(c) - player.hand.remove(c) - while c.cost>2 or len(supply["Copper"])>0 or len(supply["Silver"])>0: - pick = input("Choose a coin to gain. Any coin up to " + str(c.cost+3)+": ") - g = getcard(pick,supply,categories=["coin"],upto=c.cost+3) - if g: - player.hand.append(g) - supply[pick].remove(g) - break - break - -class Library(Action_card): - def __init__(self): - Action_card.__init__(self,"Library",5,0,0,0,0) - def play(self,player,players,supply,trash): - while (player.deck or player.discard) and len(player.hand) <7: - player.draw(player.hold) - if (player.hold[-1].category == "action" and not player.yesnoinput("You drew " + player.hold[-1].name + ". Would you like to keep it?",", add to my hand", ", set it aside")): - player.aside.append(player.hold.pop()) - else: - player.hand.append(player.hold.pop()) - -class Moat(Action_card): - def __init__(self): - Action_card.__init__(self,"Moat",2,0,2,0,0) - def react(self,player): - player.show() - return player.yesnoinput(player.name + ", you have a " + self.name + - " in your hand. Do you want to block the attack?") - -class Council_Room(Action_card): - def __init__(self): - Action_card.__init__(self,"Council Room",5,0,3,1,0) - def play(self,this_player,players,supply,trash): - for player in players: - player.draw() - -class Witch(Action_card): - def __init__(self): - Action_card.__init__(self,"Witch",5,0,2,0,0) - def play(self,this_player,players,supply,trash): - if len(supply["Curse"])>0: - for player in players: - if player==this_player: - pass - else: - for c in player.hand: - if c.react(player): - break - else: - if len(supply["Curse"])>0: - player.discard.append(supply["Curse"].pop()) - -class Bureaucrat(Action_card): - def __init__(self): - Action_card.__init__(self,"Bureaucrat",4,0,0,0,0) - def play(self,this_player,players,supply,trash): - if len(supply["Silver"])>0: - this_player.deck.insert(0,supply["Silver"].pop()) - for player in players: - if (not player==this_player) and ("victory" in catinlist(player.hand)): - for c in player.hand: - if c.react(player): - break - else: - player.show() - while True: - putback = player.choose_discard(player.name + ", which victory card" + - " do you want to put on top of your deck?\n--> ") - c = getcard(putback,supply,player.hand,"your hand",["victory"]) - if c: - player.hand.remove(c) - player.deck.insert(0,c) - break - -class Militia(Action_card): - def __init__(self): - Action_card.__init__(self,"Militia",4,0,0,0,2) - def play(self,this_player,players,supply,trash): - for player in players: - if (not player==this_player) and len(player.hand)>3: - for c in player.hand: - if c.react(player): - break - else: - player.show() - while len(player.hand)>3: - dis_card=player.choose_discard(player.name + ", choose a card from your hand to discard: ") - if dis_card: - c = getcard(dis_card,supply,player.hand,"your hand") - if c: - player.hand.remove(c) - player.discard.append(c) - -class Spy(Action_card): - def __init__(self): - Action_card.__init__(self,"Spy",4,1,1,0,0) - def play(self,this_player,players,supply,trash): - for player in players: - for c in player.hand: - if c.react(player): - break - else: - b = player.draw([]) - if not b: - continue - else: - print("The first card in the deck of " + player.name + " is " + b.name) - if this_player.yesnoinput(this_player.name + ", do you want " + player.name + " to discard this?", - ", discard",", keep"): - player.discard.append(b) - else: - player.deck.insert(0,b) - #check logic of this structure - -class Thief(Action_card): - def __init__(self): - Action_card.__init__(self,"Thief",4,0,0,0,0) - def play(self,this_player,players,supply,trash): - for player in players: - if player == this_player: - continue - for c in player.hand: - if c.react(player): - break - else: - for i in range(2): - player.draw(player.hold) - print( player.name, namesinlist(player.hold)) - if "coin" in catinlist(player.hold): - while True: - burn = input("Which card would you like " + player.name + " to trash?\n-->") - c = getcard(burn,supply,player.hold," the top 2 cards",["coin"]) - if c: - player.hold.remove(c) - break - if this_player.yesnoinput("Do you want to steal it?",", it's mine!",", leave it in the trash."): - this_player.discard.append(c) - else: - trash.append(c) - player.discard=player.discard+player.hold - player.hold = [] - -class Throne_Room(Action_card): - def __init__(self): - Action_card.__init__(self,"Throne Room",4,0,0,0,0) - def play(self,player,players,supply,trash): - if "action" in catinlist(player.hand): - while True: - double = input("What card would you like to double?\n--> ") - c = getcard(double,supply,player.hand," your hand",["action"]) - if c: - c.use(player,trash) - c.augment(player) - c.play(player,players,supply,trash) - player.show() - c.augment(player) - c.play(player,players,supply,trash) - break - - -class Player(): - def __init__(self,name): - self.name = name - self.hand = [] - self.deck = [Copper()]*7 + [Estate()]*3 - random.shuffle(self.deck) - self.played = [] - self.discard = [] - self.aside = [] - self.hold = [] - for i in range(5): - self.draw() - - def other(self): - return self.played+self.discard+self.hold+self.aside - def stack(self): - return (self.deck + self.hand + self.played + self.discard + self.aside + self.hold) - def draw(self,dest=None): - #defualt destination is player's hand - if dest==None: - dest = self.hand - #Replenish deck if necessary. - if len(self.deck)==0: - self.deck = self.discard - self.discard = [] - random.shuffle(self.deck) - #If deck has cards, add card to destination list - if len(self.deck)>0: - c = self.deck.pop(0) - dest.append(c) - return c - def turn(self,players,supply,trash): - self.show() - self.actions = 1 - self.buys = 1 - self.purse = 0 - #action phase - while self.actions>0 and 'action' in catinlist(self.hand): - playthis = input("Which card would you like to play? You have " + - str(self.actions) + " action(s). \n-Hit enter for no play. --> ") - if playthis: - c = getcard(playthis,supply,self.hand,"your hand",['action']) - if c: - self.actions = self.actions - 1 - c.use(self,trash) - c.augment(self) - c.play(self,players,supply,trash) - self.show() - else: - self.actions=0 - #buy phase - for c in self.hand: - self.purse += c.buypower - while self.buys>0: - buy_string = "Buying power is " + str(self.purse) + ". You have " + str(self.buys) + " buy" - if self.buys>1: - buy_string += "s" - buy_string += "." - print( buy_string) - purchase = input("What would you like to purchase? -Hit enter for no purchase.-\n--> ") - if not purchase: - break - else: - c = getcard(purchase,supply,upto=self.purse) - if c: - self.discard.append(supply[purchase].pop()) - self.buys = self.buys -1 - self.purse = self.purse - c.cost - - #cleanup phase - self.discard = self.discard + self.played + self.hand + self.aside - self.played = [] - self.hand = [] - self.aside = [] - for i in range(5): - self.draw() - - def gaincard(self,supply,upto): - while True: - gain = input("What would you like to get? Any card up to " + str(upto) + "\n--> ") - c = getcard(gain,supply,upto=upto) - if c: - self.discard.append(c) - supply[gain].remove(c) - break - def yesnoinput(self,prompt,yesstring='',nostring=''): - print(prompt + "\n1 - Yes" + yesstring + "\n0 - No" + nostring) - while True: - r = input("--> ") - if r == "0": - return False - if r == "1": - return True - - def choose_discard(self,prompt): - return input(prompt) - - def show(self): - print (self.name) - print ("hand:", ", ".join(sorted(namesinlist(self.hand)))) - if len(self.deck)>0: - print ("deck (alphabetical order):", ", ".join(sorted(namesinlist(self.deck)))) - if len(self.discard)>0: - print ("discard:", ", ".join(sorted(namesinlist(self.discard)))) - if len(self.played)>0: - print ("played:", ", ".join(sorted(namesinlist(self.played)))) - if len(self.aside)>0: - print ("aside:", ", ".join(sorted(namesinlist(self.aside)))) - print ("\r") - - def action_balance(self): - balance = 0 - for c in self.stack(): - if c.category == "action": - balance = balance - 1 + c.actions - return 70*balance / len(self.stack()) - - def cardsummary(self): - summary = {} - for c in self.stack(): - if c.name in summary: - summary[c.name] += 1 - else: - summary[c.name] = 1 - summary['VICTORY POINTS']=self.calcpoints() - return summary - - def calcpoints(self): - tally = 0 - gardens = 0 - n = 0 - for c in self.stack(): - tally += c.vpoints - n += 1 - if c.name == "Gardens": - gardens+=1 - return tally + n//10 * gardens - -class ComputerPlayer(Player): - def __init__(self,name): - Player.__init__(self,name) - self.index = 0 - self.buygaintable = [] - #beginning and middle of game - self.buygaintable1 = ["Province","Gold","Laboratory","Festival","Witch", - "Council Room","Market","Militia","Adventurer","Smithy","Bureaucrat","Silver","Moat",""] - #end of game - self.buygaintable2 = ["Province","Gardens","Duchy","Estate","Gold","Silver",""] - #beginning and middle of the game, too many action cards - self.buygaintable3 = ["Province","Gold","Festival","Laboratory","Market","Village", - "Silver",""] - self.playtable1 = ["Village","Festival","Market","Laboratory","Witch", - "Council Room","Militia","Adventurer","Smithy","Bureaucrat","Moat",""] - self.discardtable1 = ["Gardens","Duchy","Province","Estate","Curse","Copper", - "Village","Bureaucrat","Silver","Militia","Smithy","Council Room","Witch", - "Festival","Market","Adventurer","Laboratory","Gold","Moat"] - - def turn(self,players,supply,trash): - self.show() - self.actions = 1 - self.buys = 1 - self.purse = 0 - #action phase - self.index = 0 - while self.actions>0 and 'action' in catinlist(self.hand): - playthis = self.playtable1[self.index] - if playthis: - c = self.getcard(playthis,supply,self.hand,"your hand",['action']) - if c: - print (self.name + " plays " + c.name) - self.actions = self.actions - 1 - c.use(self,trash) - self.index=0 - c.augment(self) - c.play(self,players,supply,trash) - self.show() - else: - self.index += 1 - else: - self.actions=0 - #buy phase - if len(supply["Province"])>len(players)+totalbuypower(self.deck)/8: - if self.action_balance()<-10: - self.buygaintable = self.buygaintable3 - else: - self.buygaintable = self.buygaintable1 - else: - self.buygaintable = self.buygaintable2 - self.index = 0 - for c in self.hand: - self.purse += c.buypower - while self.buys>0: - purchase = self.buygaintable[self.index] - if not purchase: - break - else: - c = self.getcard(purchase,supply,upto=self.purse) - if c: - self.discard.append(supply[purchase].pop()) - self.index = 0 - self.buys = self.buys -1 - self.purse = self.purse - c.cost - print (self.name + " bought " + c.name) - else: - self.index += 1 - - #cleanup phase - self.discard = self.discard + self.played + self.hand + self.aside - self.played = [] - self.hand = [] - self.aside = [] - for i in range(5): - self.draw() - - def getcard(self,name,supply,target_list=None,target_name= "the supply anymore",categories=['action','coin','curse','victory'],upto=100): - if not name in supply: - #print name + " is not in this game." - return None - if not target_list: - target_list = supply[name] - nameslist = namesinlist(target_list) - if not name in nameslist: - #print "There is no " + name + " in " + target_name - return None - i = nameslist.index(name) - c = target_list[i] - if c.category not in categories: - catstring = categories[0] - for i in categories[1:]: - catstring = catstring + " or " + categories[i] - #print name + " is not a " + catstring + " card." - return None - if c.cost > upto: - #print name + " costs " + str(c.cost) - return None - return c - - def choose_discard(self,prompt): - index = 0 - while True: - dis_card = self.discardtable1[index] - c = self.getcard(dis_card,[dis_card],self.hand) - if c: - return c.name - else: - index+=1 - - def yesnoinput(self,prompt,yesstring='',nostring=''): - return True - - def show(self): - pass - -class TablePlayer(ComputerPlayer): - def __init__(self,name): - ComputerPlayer.__init__(self,name) - self.index=0 - self.buygaintable=[] - q=re.match(r'([a-zA-Z]+)(\d+)',name) - if q: - self.number = q.group(2) - else: - print(name) - self.playtable1 = ["Village","Festival","Market","Laboratory","Witch", - "Council Room","Militia","Adventurer","Smithy","Bureaucrat","Moat",""] - self.discardtable1 = ["Gardens","Duchy","Province","Estate","Curse","Copper", - "Village","Bureaucrat","Silver","Militia","Smithy","Council Room","Witch", - "Festival","Market","Adventurer","Laboratory","Gold","Moat"] - - def turn(self,players,supply,trash): - self.show() - self.actions = 1 - self.buys = 1 - self.purse = 0 - #action phase - self.index = 0 - while self.actions>0 and 'action' in catinlist(self.hand): - playthis = self.playtable1[self.index] - if playthis: - c = self.getcard(playthis,supply,self.hand,"your hand",['action']) - if c: - #print (self.name + " plays " + c.name) - self.actions = self.actions - 1 - c.use(self,trash) - self.index=0 - c.augment(self) - c.play(self,players,supply,trash) - self.show() - else: - self.index += 1 - else: - self.actions=0 - #buy phase - v= self.number - csvstring = r"Dominionbuy" + str(v) + ".csv" - buydf=pandas.read_csv(csvstring,na_filter=False) - sortedbuydf=buydf.sort_values("Buyvalues",ascending=False) - ranktable = sortedbuydf.Cardname - self.index = 0 - for c in self.hand: - self.purse += c.buypower - while self.buys>0: - purchase = ranktable.iloc[self.index] - if not purchase: - break - else: - c = self.getcard(purchase,supply,upto=self.purse) - if c: - self.discard.append(supply[purchase].pop()) - self.index = 0 - self.buys = self.buys -1 - self.purse = self.purse - c.cost - else: - self.index += 1 - - #cleanup phase - self.discard = self.discard + self.played + self.hand + self.aside - self.played = [] - self.hand = [] - self.aside = [] - for i in range(5): - self.draw() - - -def gameover(supply): - if len(supply["Province"])==0: - return True - out = 0 - for stack in supply: - if len(supply[stack])==0: - out+=1 - if out>=3: - return True - return False - -def namesinlist(cardlist): - namelist = [] - for c in cardlist: - namelist.append(c.name) - return namelist - -def catinlist(cardlist): - catlist = [] - for c in cardlist: - catlist.append(c.category) - return catlist - -def getcard(name,supply,target_list=None,target_name= "the supply anymore",categories=['action','coin','curse','victory'],upto=100): - if not name in supply: - print( name + " is not in this game.") - return None - if not target_list: - target_list = supply[name] - nameslist = namesinlist(target_list) - if not name in nameslist: - print ("There is no " + name + " in " + target_name) - return None - i = nameslist.index(name) - c = target_list[i] - if c.category not in categories: - catstring = categories[0] - for i in categories[1:]: - catstring = catstring + " or " + categories[i] - print (name + " is not a " + catstring + " card.") - return None - if c.cost > upto: - print (name + " costs " + str(c.cost)) - return None - return c - -def totalbuypower(cardlist): - TBP = 0 - for c in cardlist: - TBP += c.buypower - if c.category == "action": - TBP += c.coins - return TBP - -def cardsummaries(players): - cardsums={} - for player in players: - cardsums[player.name]=player.cardsummary() - cardsdf = pandas.DataFrame(cardsums).fillna(0).sort_index() - vp=cardsdf.loc[['VICTORY POINTS']] - cardsdf.drop(['VICTORY POINTS'],inplace=True) - return pandas.concat([cardsdf,vp],axis=0).fillna(0).astype(int) - -def countsupply(supply,form): - return [len(supply[a]) for a in form] - -def countcards(cards,form): - dcount = Counter(namesinlist(cards)) - return [dcount[a] for a in form] - -def rankcards(form,vector): - od = OrderedDict(zip(form,vector)) - sd = OrderedDict(sorted(od.items(),key = itemgetter(1),reverse=True)) - return list(sd.keys()) \ No newline at end of file diff --git a/projects/lieur/dominion/testDominion2.py b/projects/lieur/dominion/testDominion2.py deleted file mode 100644 index 6a0a534..0000000 --- a/projects/lieur/dominion/testDominion2.py +++ /dev/null @@ -1,762 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Tue Oct 13 15:26:55 2015 - -@author: tfleck -""" -import random -from collections import Counter, OrderedDict -from operator import itemgetter -import re -import pandas - -class Card(): - def __init__(self,name,category,cost,buypower,vpoints): - self.name = name - self.category = category - self.cost = cost - self.buypower = buypower - self.vpoints = vpoints - def react(self,player): - return False - -class Coin_card(Card): - def __init__(self,name,cost,buypower): - Card.__init__(self,name,"coin",cost,buypower,0) - -class Copper(Coin_card): - def __init__(self): - Coin_card.__init__(self,"Copper",0,1) - -class Silver(Coin_card): - def __init__(self): - Coin_card.__init__(self,"Silver",3,2) - -class Gold(Coin_card): - def __init__(self): - Coin_card.__init__(self,"Gold",6,3) - -class Victory_card(Card): - def __init__(self,name,cost,vpoints): - Card.__init__(self,name,"victory",cost,0,vpoints) - -class Estate(Victory_card): - def __init__(self): - Victory_card.__init__(self,"Estate",2,1) - -class Duchy(Victory_card): - def __init__(self): - Victory_card.__init__(self,"Duchy",5,3) - -class Province(Victory_card): - def __init__(self): - Victory_card.__init__(self,"Province",8,6) - -class Gardens(Victory_card): - def __init__(self): - Victory_card.__init__(self,"Gardens",4,0) - -class Curse(Card): - def __init__(self): - Card.__init__(self,"Curse","curse",0,0,-1) - -class Action_card(Card): - def __init__(self,name,cost,actions,cards,buys,coins): - Card.__init__(self,name,"action",cost,0,0) - self.actions = actions - self.cards = cards - self.buys = buys - self.coins = coins - def use(self,player,trash): - player.played.append(self) - player.hand.remove(self) - def augment(self,player): - player.actions+=self.actions - player.buys+=self.buys - player.purse+=self.coins - for i in range(self.cards): - player.draw() - def play(self,player,players,supply,trash): - pass - -class Woodcutter(Action_card): - def __init__(self): - Action_card.__init__(self,"Woodcutter",3,0,0,1,2) - -class Smithy(Action_card): - def __init__(self): - Action_card.__init__(self,"Smithy",4,0,3,0,0) - -class Laboratory(Action_card): - def __init__(self): - Action_card.__init__(self,"Laboratory",5,1,2,0,0) - -class Village(Action_card): - def __init__(self): - Action_card.__init__(self,"Village",3,2,1,0,0) - -class Festival(Action_card): - def __init__(self): - Action_card.__init__(self,"Festival",5,2,0,1,2) - -class Market(Action_card): - def __init__(self): - Action_card.__init__(self,"Market",5,1,1,1,1) - -class Chancellor(Action_card): - def __init__(self): - Action_card.__init__(self,"Chancellor",3,0,0,0,2) - def play(self,player,players,supply,trash): - if player.yesnoinput('Would you like to discard your entire deck?'): - player.discard = player.discard + player.deck - player.deck = [] - -class Workshop(Action_card): - def __init__(self): - Action_card.__init__(self,"Workshop",3,0,0,0,0) - def play(self,player,players,supply,trash): - player.gaincard(supply,4) - -class Moneylender(Action_card): - def __init__(self): - Action_card.__init__(self,"Moneylender",4,0,0,0,0) - def play(self,player,players,supply,trash): - c = getcard("Copper",supply,player.hand,"your hand") - if c: - trash.append(c) - player.hand.remove(c) - player.purse += 3 - -class Chapel(Action_card): - def __init__(self): - Action_card.__init__(self,"Chapel",2,0,0,0,0) - def play(self,player,players,supply,trash): - trashed=0 - while trashed<4 and len(player.hand)>0: - trashcard = input("Choose a card from your hand to trash: ") - if not trashcard: - break - c = getcard(trashcard,supply,player.hand,"your hand") - if c: - trash.append(c) - player.hand.remove(c) - trashed+=1 - -class Cellar(Action_card): - def __init__(self): - Action_card.__init__(self,"Cellar",2,1,0,0,0) - def play(self,player,players,supply,trash): - discarded=0 - while len(player.hand)>0: - dis_card=input("Choose a card from your hand to discard: ") - if not dis_card: - break - c = getcard(dis_card,supply,player.hand,"your hand") - if c: - player.discard.append(c) - player.hand.remove(c) - discarded+=1 - for j in range(discarded): - player.draw() - -class Remodel(Action_card): - def __init__(self): - Action_card.__init__(self,"Remodel",4,0,0,0,0) - def play(self,player,players,supply,trash): - while len(player.hand)>0: - this_card = input("Choose a card from your hand to remodel: ") - c = getcard(this_card,supply,player.hand,"your hand") - if c: - trash.append(c) - player.hand.remove(c) - player.gaincard(supply,c.cost+2) - break - -class Adventurer(Action_card): - def __init__(self): - Action_card.__init__(self,"Adventurer",6,0,0,0,0) - def play(self,player,players,supply,trash): - coins_added = 0 - while (player.deck or player.discard) and coins_added <2: - player.draw() - if player.hand[-1].category == "coin": - coins_added +=1 - else: - player.aside.append(player.hand.pop()) - -class Feast(Action_card): - def __init__(self): - Action_card.__init__(self,"Feast",4,0,0,0,0) - def use(self,player,trash): - trash.append(self) - player.hand.remove(self) - def play(self,player,players,supply,trash): - player.gaincard(supply,5) - -class Mine(Action_card): - def __init__(self): - Action_card.__init__(self,"Mine",5,0,0,0,0) - def play(self,player,players,supply,trash): - while "coin" in catinlist(player.hand): - this_card = input("Choose a coin from your hand to upgrade: ") - c = getcard(this_card,supply,player.hand,"your hand",["coin"]) - if c: - trash.append(c) - player.hand.remove(c) - while c.cost>2 or len(supply["Copper"])>0 or len(supply["Silver"])>0: - pick = input("Choose a coin to gain. Any coin up to " + str(c.cost+3)+": ") - g = getcard(pick,supply,categories=["coin"],upto=c.cost+3) - if g: - player.hand.append(g) - supply[pick].remove(g) - break - break - -class Library(Action_card): - def __init__(self): - Action_card.__init__(self,"Library",5,0,0,0,0) - def play(self,player,players,supply,trash): - while (player.deck or player.discard) and len(player.hand) <7: - player.draw(player.hold) - if (player.hold[-1].category == "action" and not player.yesnoinput("You drew " + player.hold[-1].name + ". Would you like to keep it?",", add to my hand", ", set it aside")): - player.aside.append(player.hold.pop()) - else: - player.hand.append(player.hold.pop()) - -class Moat(Action_card): - def __init__(self): - Action_card.__init__(self,"Moat",2,0,2,0,0) - def react(self,player): - player.show() - return player.yesnoinput(player.name + ", you have a " + self.name + - " in your hand. Do you want to block the attack?") - -class Council_Room(Action_card): - def __init__(self): - Action_card.__init__(self,"Council Room",5,0,3,1,0) - def play(self,this_player,players,supply,trash): - for player in players: - player.draw() - -class Witch(Action_card): - def __init__(self): - Action_card.__init__(self,"Witch",5,0,2,0,0) - def play(self,this_player,players,supply,trash): - if len(supply["Curse"])>0: - for player in players: - if player==this_player: - pass - else: - for c in player.hand: - if c.react(player): - break - else: - if len(supply["Curse"])>0: - player.discard.append(supply["Curse"].pop()) - -class Bureaucrat(Action_card): - def __init__(self): - Action_card.__init__(self,"Bureaucrat",4,0,0,0,0) - def play(self,this_player,players,supply,trash): - if len(supply["Silver"])>0: - this_player.deck.insert(0,supply["Silver"].pop()) - for player in players: - if (not player==this_player) and ("victory" in catinlist(player.hand)): - for c in player.hand: - if c.react(player): - break - else: - player.show() - while True: - putback = player.choose_discard(player.name + ", which victory card" + - " do you want to put on top of your deck?\n--> ") - c = getcard(putback,supply,player.hand,"your hand",["victory"]) - if c: - player.hand.remove(c) - player.deck.insert(0,c) - break - -class Militia(Action_card): - def __init__(self): - Action_card.__init__(self,"Militia",4,0,0,0,2) - def play(self,this_player,players,supply,trash): - for player in players: - if (not player==this_player) and len(player.hand)>3: - for c in player.hand: - if c.react(player): - break - else: - player.show() - while len(player.hand)>3: - dis_card=player.choose_discard(player.name + ", choose a card from your hand to discard: ") - if dis_card: - c = getcard(dis_card,supply,player.hand,"your hand") - if c: - player.hand.remove(c) - player.discard.append(c) - -class Spy(Action_card): - def __init__(self): - Action_card.__init__(self,"Spy",4,1,1,0,0) - def play(self,this_player,players,supply,trash): - for player in players: - for c in player.hand: - if c.react(player): - break - else: - b = player.draw([]) - if not b: - continue - else: - print("The first card in the deck of " + player.name + " is " + b.name) - if this_player.yesnoinput(this_player.name + ", do you want " + player.name + " to discard this?", - ", discard",", keep"): - player.discard.append(b) - else: - player.deck.insert(0,b) - #check logic of this structure - -class Thief(Action_card): - def __init__(self): - Action_card.__init__(self,"Thief",4,0,0,0,0) - def play(self,this_player,players,supply,trash): - for player in players: - if player == this_player: - continue - for c in player.hand: - if c.react(player): - break - else: - for i in range(2): - player.draw(player.hold) - print( player.name, namesinlist(player.hold)) - if "coin" in catinlist(player.hold): - while True: - burn = input("Which card would you like " + player.name + " to trash?\n-->") - c = getcard(burn,supply,player.hold," the top 2 cards",["coin"]) - if c: - player.hold.remove(c) - break - if this_player.yesnoinput("Do you want to steal it?",", it's mine!",", leave it in the trash."): - this_player.discard.append(c) - else: - trash.append(c) - player.discard=player.discard+player.hold - player.hold = [] - -class Throne_Room(Action_card): - def __init__(self): - Action_card.__init__(self,"Throne Room",4,0,0,0,0) - def play(self,player,players,supply,trash): - if "action" in catinlist(player.hand): - while True: - double = input("What card would you like to double?\n--> ") - c = getcard(double,supply,player.hand," your hand",["action"]) - if c: - c.use(player,trash) - c.augment(player) - c.play(player,players,supply,trash) - player.show() - c.augment(player) - c.play(player,players,supply,trash) - break - - -class Player(): - def __init__(self,name): - self.name = name - self.hand = [] - self.deck = [Copper()]*7 + [Estate()]*3 - random.shuffle(self.deck) - self.played = [] - self.discard = [] - self.aside = [] - self.hold = [] - for i in range(5): - self.draw() - - def other(self): - return self.played+self.discard+self.hold+self.aside - def stack(self): - return (self.deck + self.hand + self.played + self.discard + self.aside + self.hold) - def draw(self,dest=None): - #defualt destination is player's hand - if dest==None: - dest = self.hand - #Replenish deck if necessary. - if len(self.deck)==0: - self.deck = self.discard - self.discard = [] - random.shuffle(self.deck) - #If deck has cards, add card to destination list - if len(self.deck)>0: - c = self.deck.pop(0) - dest.append(c) - return c - def turn(self,players,supply,trash): - self.show() - self.actions = 1 - self.buys = 1 - self.purse = 0 - #action phase - while self.actions>0 and 'action' in catinlist(self.hand): - playthis = input("Which card would you like to play? You have " + - str(self.actions) + " action(s). \n-Hit enter for no play. --> ") - if playthis: - c = getcard(playthis,supply,self.hand,"your hand",['action']) - if c: - self.actions = self.actions - 1 - c.use(self,trash) - c.augment(self) - c.play(self,players,supply,trash) - self.show() - else: - self.actions=0 - #buy phase - for c in self.hand: - self.purse += c.buypower - while self.buys>0: - buy_string = "Buying power is " + str(self.purse) + ". You have " + str(self.buys) + " buy" - if self.buys>1: - buy_string += "s" - buy_string += "." - print( buy_string) - purchase = input("What would you like to purchase? -Hit enter for no purchase.-\n--> ") - if not purchase: - break - else: - c = getcard(purchase,supply,upto=self.purse) - if c: - self.discard.append(supply[purchase].pop()) - self.buys = self.buys -1 - self.purse = self.purse - c.cost - - #cleanup phase - self.discard = self.discard + self.played + self.hand + self.aside - self.played = [] - self.hand = [] - self.aside = [] - for i in range(5): - self.draw() - - def gaincard(self,supply,upto): - while True: - gain = input("What would you like to get? Any card up to " + str(upto) + "\n--> ") - c = getcard(gain,supply,upto=upto) - if c: - self.discard.append(c) - supply[gain].remove(c) - break - def yesnoinput(self,prompt,yesstring='',nostring=''): - print(prompt + "\n1 - Yes" + yesstring + "\n0 - No" + nostring) - while True: - r = input("--> ") - if r == "0": - return False - if r == "1": - return True - - def choose_discard(self,prompt): - return input(prompt) - - def show(self): - print (self.name) - print ("hand:", ", ".join(sorted(namesinlist(self.hand)))) - if len(self.deck)>0: - print ("deck (alphabetical order):", ", ".join(sorted(namesinlist(self.deck)))) - if len(self.discard)>0: - print ("discard:", ", ".join(sorted(namesinlist(self.discard)))) - if len(self.played)>0: - print ("played:", ", ".join(sorted(namesinlist(self.played)))) - if len(self.aside)>0: - print ("aside:", ", ".join(sorted(namesinlist(self.aside)))) - print ("\r") - - def action_balance(self): - balance = 0 - for c in self.stack(): - if c.category == "action": - balance = balance - 1 + c.actions - return 70*balance / len(self.stack()) - - def cardsummary(self): - summary = {} - for c in self.stack(): - if c.name in summary: - summary[c.name] += 1 - else: - summary[c.name] = 1 - summary['VICTORY POINTS']=self.calcpoints() - return summary - - def calcpoints(self): - tally = 0 - gardens = 0 - n = 0 - for c in self.stack(): - tally += c.vpoints - n += 1 - if c.name == "Gardens": - gardens+=1 - return tally + n//10 * gardens - -class ComputerPlayer(Player): - def __init__(self,name): - Player.__init__(self,name) - self.index = 0 - self.buygaintable = [] - #beginning and middle of game - self.buygaintable1 = ["Province","Gold","Laboratory","Festival","Witch", - "Council Room","Market","Militia","Adventurer","Smithy","Bureaucrat","Silver","Moat",""] - #end of game - self.buygaintable2 = ["Province","Gardens","Duchy","Estate","Gold","Silver",""] - #beginning and middle of the game, too many action cards - self.buygaintable3 = ["Province","Gold","Festival","Laboratory","Market","Village", - "Silver",""] - self.playtable1 = ["Village","Festival","Market","Laboratory","Witch", - "Council Room","Militia","Adventurer","Smithy","Bureaucrat","Moat",""] - self.discardtable1 = ["Gardens","Duchy","Province","Estate","Curse","Copper", - "Village","Bureaucrat","Silver","Militia","Smithy","Council Room","Witch", - "Festival","Market","Adventurer","Laboratory","Gold","Moat"] - - def turn(self,players,supply,trash): - self.show() - self.actions = 1 - self.buys = 1 - self.purse = 0 - #action phase - self.index = 0 - while self.actions>0 and 'action' in catinlist(self.hand): - playthis = self.playtable1[self.index] - if playthis: - c = self.getcard(playthis,supply,self.hand,"your hand",['action']) - if c: - print (self.name + " plays " + c.name) - self.actions = self.actions - 1 - c.use(self,trash) - self.index=0 - c.augment(self) - c.play(self,players,supply,trash) - self.show() - else: - self.index += 1 - else: - self.actions=0 - #buy phase - if len(supply["Province"])>len(players)+totalbuypower(self.deck)/8: - if self.action_balance()<-10: - self.buygaintable = self.buygaintable3 - else: - self.buygaintable = self.buygaintable1 - else: - self.buygaintable = self.buygaintable2 - self.index = 0 - for c in self.hand: - self.purse += c.buypower - while self.buys>0: - purchase = self.buygaintable[self.index] - if not purchase: - break - else: - c = self.getcard(purchase,supply,upto=self.purse) - if c: - self.discard.append(supply[purchase].pop()) - self.index = 0 - self.buys = self.buys -1 - self.purse = self.purse - c.cost - print (self.name + " bought " + c.name) - else: - self.index += 1 - - #cleanup phase - self.discard = self.discard + self.played + self.hand + self.aside - self.played = [] - self.hand = [] - self.aside = [] - for i in range(5): - self.draw() - - def getcard(self,name,supply,target_list=None,target_name= "the supply anymore",categories=['action','coin','curse','victory'],upto=100): - if not name in supply: - #print name + " is not in this game." - return None - if not target_list: - target_list = supply[name] - nameslist = namesinlist(target_list) - if not name in nameslist: - #print "There is no " + name + " in " + target_name - return None - i = nameslist.index(name) - c = target_list[i] - if c.category not in categories: - catstring = categories[0] - for i in categories[1:]: - catstring = catstring + " or " + categories[i] - #print name + " is not a " + catstring + " card." - return None - if c.cost > upto: - #print name + " costs " + str(c.cost) - return None - return c - - def choose_discard(self,prompt): - index = 0 - while True: - dis_card = self.discardtable1[index] - c = self.getcard(dis_card,[dis_card],self.hand) - if c: - return c.name - else: - index+=1 - - def yesnoinput(self,prompt,yesstring='',nostring=''): - return True - - def show(self): - pass - -class TablePlayer(ComputerPlayer): - def __init__(self,name): - ComputerPlayer.__init__(self,name) - self.index=0 - self.buygaintable=[] - q=re.match(r'([a-zA-Z]+)(\d+)',name) - if q: - self.number = q.group(2) - else: - print(name) - self.playtable1 = ["Village","Festival","Market","Laboratory","Witch", - "Council Room","Militia","Adventurer","Smithy","Bureaucrat","Moat",""] - self.discardtable1 = ["Gardens","Duchy","Province","Estate","Curse","Copper", - "Village","Bureaucrat","Silver","Militia","Smithy","Council Room","Witch", - "Festival","Market","Adventurer","Laboratory","Gold","Moat"] - - def turn(self,players,supply,trash): - self.show() - self.actions = 1 - self.buys = 1 - self.purse = 0 - #action phase - self.index = 0 - while self.actions>0 and 'action' in catinlist(self.hand): - playthis = self.playtable1[self.index] - if playthis: - c = self.getcard(playthis,supply,self.hand,"your hand",['action']) - if c: - #print (self.name + " plays " + c.name) - self.actions = self.actions - 1 - c.use(self,trash) - self.index=0 - c.augment(self) - c.play(self,players,supply,trash) - self.show() - else: - self.index += 1 - else: - self.actions=0 - #buy phase - v= self.number - csvstring = r"Dominionbuy" + str(v) + ".csv" - buydf=pandas.read_csv(csvstring,na_filter=False) - sortedbuydf=buydf.sort_values("Buyvalues",ascending=False) - ranktable = sortedbuydf.Cardname - self.index = 0 - for c in self.hand: - self.purse += c.buypower - while self.buys>0: - purchase = ranktable.iloc[self.index] - if not purchase: - break - else: - c = self.getcard(purchase,supply,upto=self.purse) - if c: - self.discard.append(supply[purchase].pop()) - self.index = 0 - self.buys = self.buys -1 - self.purse = self.purse - c.cost - else: - self.index += 1 - - #cleanup phase - self.discard = self.discard + self.played + self.hand + self.aside - self.played = [] - self.hand = [] - self.aside = [] - for i in range(5): - self.draw() - - -def gameover(supply): - if len(supply["Province"])==0: - return True - out = 0 - for stack in supply: - if len(supply[stack])==0: - out+=1 - if out>=3: - return True - return False - -def namesinlist(cardlist): - namelist = [] - for c in cardlist: - namelist.append(c.name) - return namelist - -def catinlist(cardlist): - catlist = [] - for c in cardlist: - catlist.append(c.category) - return catlist - -def getcard(name,supply,target_list=None,target_name= "the supply anymore",categories=['action','coin','curse','victory'],upto=100): - if not name in supply: - print( name + " is not in this game.") - return None - if not target_list: - target_list = supply[name] - nameslist = namesinlist(target_list) - if not name in nameslist: - print ("There is no " + name + " in " + target_name) - return None - i = nameslist.index(name) - c = target_list[i] - if c.category not in categories: - catstring = categories[0] - for i in categories[1:]: - catstring = catstring + " or " + categories[i] - print (name + " is not a " + catstring + " card.") - return None - if c.cost > upto: - print (name + " costs " + str(c.cost)) - return None - return c - -def totalbuypower(cardlist): - TBP = 0 - for c in cardlist: - TBP += c.buypower - if c.category == "action": - TBP += c.coins - return TBP - -def cardsummaries(players): - cardsums={} - for player in players: - cardsums[player.name]=player.cardsummary() - cardsdf = pandas.DataFrame(cardsums).fillna(0).sort_index() - vp=cardsdf.loc[['VICTORY POINTS']] - cardsdf.drop(['VICTORY POINTS'],inplace=True) - return pandas.concat([cardsdf,vp],axis=0).fillna(0).astype(int) - -def countsupply(supply,form): - return [len(supply[a]) for a in form] - -def countcards(cards,form): - dcount = Counter(namesinlist(cards)) - return [dcount[a] for a in form] - -def rankcards(form,vector): - od = OrderedDict(zip(form,vector)) - sd = OrderedDict(sorted(od.items(),key = itemgetter(1),reverse=True)) - return list(sd.keys()) \ No newline at end of file From 398f639b2d138abf79fd0fa2bb4cba896452da08 Mon Sep 17 00:00:00 2001 From: lieuraymond Date: Sat, 18 Jan 2020 16:21:06 -0800 Subject: [PATCH 04/18] Added correct copies --- projects/lieur/dominion/testDominion1.py | 119 +++++++++++++++++++++++ projects/lieur/dominion/testDominion2.py | 119 +++++++++++++++++++++++ 2 files changed, 238 insertions(+) create mode 100644 projects/lieur/dominion/testDominion1.py create mode 100644 projects/lieur/dominion/testDominion2.py diff --git a/projects/lieur/dominion/testDominion1.py b/projects/lieur/dominion/testDominion1.py new file mode 100644 index 0000000..b4d6021 --- /dev/null +++ b/projects/lieur/dominion/testDominion1.py @@ -0,0 +1,119 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue Oct 13 15:42:42 2015 + +@author: tfleck +""" + +import Dominion +import random +from collections import defaultdict + +#Get player names +player_names = ["Annie","*Ben","*Carla"] + +#number of curses and victory cards +if len(player_names)>2: + nV=12 +else: + nV=8 +nC = -10 + 10 * len(player_names) + +#Define box +box = {} +box["Woodcutter"]=[Dominion.Woodcutter()]*10 +box["Smithy"]=[Dominion.Smithy()]*10 +box["Laboratory"]=[Dominion.Laboratory()]*10 +box["Village"]=[Dominion.Village()]*10 +box["Festival"]=[Dominion.Festival()]*10 +box["Market"]=[Dominion.Market()]*10 +box["Chancellor"]=[Dominion.Chancellor()]*10 +box["Workshop"]=[Dominion.Workshop()]*10 +box["Moneylender"]=[Dominion.Moneylender()]*10 +box["Chapel"]=[Dominion.Chapel()]*10 +box["Cellar"]=[Dominion.Cellar()]*10 +box["Remodel"]=[Dominion.Remodel()]*10 +box["Adventurer"]=[Dominion.Adventurer()]*10 +box["Feast"]=[Dominion.Feast()]*10 +box["Mine"]=[Dominion.Mine()]*10 +box["Library"]=[Dominion.Library()]*10 +box["Gardens"]=[Dominion.Gardens()]*nV +box["Moat"]=[Dominion.Moat()]*10 +box["Council Room"]=[Dominion.Council_Room()]*10 +box["Witch"]=[Dominion.Witch()]*10 +box["Bureaucrat"]=[Dominion.Bureaucrat()]*10 +box["Militia"]=[Dominion.Militia()]*10 +box["Spy"]=[Dominion.Spy()]*10 +box["Thief"]=[Dominion.Thief()]*10 +box["Throne Room"]=[Dominion.Throne_Room()]*10 + +supply_order = {0:['Curse','Copper'],2:['Estate','Cellar','Chapel','Moat'], + 3:['Silver','Chancellor','Village','Woodcutter','Workshop'], + 4:['Gardens','Bureaucrat','Feast','Militia','Moneylender','Remodel','Smithy','Spy','Thief','Throne Room'], + 5:['Duchy','Market','Council Room','Festival','Laboratory','Library','Mine','Witch'], + 6:['Gold','Adventurer'],8:['Province']} + +#Pick 10 cards from box to be in the supply. +boxlist = [k for k in box] +random.shuffle(boxlist) +random10 = boxlist[:10] +supply = defaultdict(list,[(k,box[k]) for k in random10]) + + +#The supply always has these cards +supply["Copper"]=[Dominion.Copper()]*(60-len(player_names)*7) +supply["Silver"]=[Dominion.Silver()]*40 +supply["Gold"]=[Dominion.Gold()]*30 +supply["Estate"]=[Dominion.Estate()]*nV +supply["Duchy"]=[Dominion.Duchy()]*nV +supply["Province"]=[Dominion.Province()]*nV +supply["Curse"]=[Dominion.Curse()]*nC + +#initialize the trash +trash = [] + +#Costruct the Player objects +players = [] +for name in player_names: + if name[0]=="*": + players.append(Dominion.ComputerPlayer(name[1:])) + elif name[0]=="^": + players.append(Dominion.TablePlayer(name[1:])) + else: + players.append(Dominion.Player(name)) + +#Play the game +turn = 0 +while not Dominion.gameover(supply): + turn += 1 + print("\r") + for value in supply_order: + print (value) + for stack in supply_order[value]: + if stack in supply: + print (stack, len(supply[stack])) + print("\r") + for player in players: + print (player.name,player.calcpoints()) + print ("\rStart of turn " + str(turn)) + for player in players: + if not Dominion.gameover(supply): + print("\r") + player.turn(players,supply,trash) + + +#Final score +dcs=Dominion.cardsummaries(players) +vp=dcs.loc['VICTORY POINTS'] +vpmax=vp.max() +winners=[] +for i in vp.index: + if vp.loc[i]==vpmax: + winners.append(i) +if len(winners)>1: + winstring= ' and '.join(winners) + ' win!' +else: + winstring = ' '.join([winners[0],'wins!']) + +print("\nGAME OVER!!!\n"+winstring+"\n") +print(dcs) \ No newline at end of file diff --git a/projects/lieur/dominion/testDominion2.py b/projects/lieur/dominion/testDominion2.py new file mode 100644 index 0000000..b4d6021 --- /dev/null +++ b/projects/lieur/dominion/testDominion2.py @@ -0,0 +1,119 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue Oct 13 15:42:42 2015 + +@author: tfleck +""" + +import Dominion +import random +from collections import defaultdict + +#Get player names +player_names = ["Annie","*Ben","*Carla"] + +#number of curses and victory cards +if len(player_names)>2: + nV=12 +else: + nV=8 +nC = -10 + 10 * len(player_names) + +#Define box +box = {} +box["Woodcutter"]=[Dominion.Woodcutter()]*10 +box["Smithy"]=[Dominion.Smithy()]*10 +box["Laboratory"]=[Dominion.Laboratory()]*10 +box["Village"]=[Dominion.Village()]*10 +box["Festival"]=[Dominion.Festival()]*10 +box["Market"]=[Dominion.Market()]*10 +box["Chancellor"]=[Dominion.Chancellor()]*10 +box["Workshop"]=[Dominion.Workshop()]*10 +box["Moneylender"]=[Dominion.Moneylender()]*10 +box["Chapel"]=[Dominion.Chapel()]*10 +box["Cellar"]=[Dominion.Cellar()]*10 +box["Remodel"]=[Dominion.Remodel()]*10 +box["Adventurer"]=[Dominion.Adventurer()]*10 +box["Feast"]=[Dominion.Feast()]*10 +box["Mine"]=[Dominion.Mine()]*10 +box["Library"]=[Dominion.Library()]*10 +box["Gardens"]=[Dominion.Gardens()]*nV +box["Moat"]=[Dominion.Moat()]*10 +box["Council Room"]=[Dominion.Council_Room()]*10 +box["Witch"]=[Dominion.Witch()]*10 +box["Bureaucrat"]=[Dominion.Bureaucrat()]*10 +box["Militia"]=[Dominion.Militia()]*10 +box["Spy"]=[Dominion.Spy()]*10 +box["Thief"]=[Dominion.Thief()]*10 +box["Throne Room"]=[Dominion.Throne_Room()]*10 + +supply_order = {0:['Curse','Copper'],2:['Estate','Cellar','Chapel','Moat'], + 3:['Silver','Chancellor','Village','Woodcutter','Workshop'], + 4:['Gardens','Bureaucrat','Feast','Militia','Moneylender','Remodel','Smithy','Spy','Thief','Throne Room'], + 5:['Duchy','Market','Council Room','Festival','Laboratory','Library','Mine','Witch'], + 6:['Gold','Adventurer'],8:['Province']} + +#Pick 10 cards from box to be in the supply. +boxlist = [k for k in box] +random.shuffle(boxlist) +random10 = boxlist[:10] +supply = defaultdict(list,[(k,box[k]) for k in random10]) + + +#The supply always has these cards +supply["Copper"]=[Dominion.Copper()]*(60-len(player_names)*7) +supply["Silver"]=[Dominion.Silver()]*40 +supply["Gold"]=[Dominion.Gold()]*30 +supply["Estate"]=[Dominion.Estate()]*nV +supply["Duchy"]=[Dominion.Duchy()]*nV +supply["Province"]=[Dominion.Province()]*nV +supply["Curse"]=[Dominion.Curse()]*nC + +#initialize the trash +trash = [] + +#Costruct the Player objects +players = [] +for name in player_names: + if name[0]=="*": + players.append(Dominion.ComputerPlayer(name[1:])) + elif name[0]=="^": + players.append(Dominion.TablePlayer(name[1:])) + else: + players.append(Dominion.Player(name)) + +#Play the game +turn = 0 +while not Dominion.gameover(supply): + turn += 1 + print("\r") + for value in supply_order: + print (value) + for stack in supply_order[value]: + if stack in supply: + print (stack, len(supply[stack])) + print("\r") + for player in players: + print (player.name,player.calcpoints()) + print ("\rStart of turn " + str(turn)) + for player in players: + if not Dominion.gameover(supply): + print("\r") + player.turn(players,supply,trash) + + +#Final score +dcs=Dominion.cardsummaries(players) +vp=dcs.loc['VICTORY POINTS'] +vpmax=vp.max() +winners=[] +for i in vp.index: + if vp.loc[i]==vpmax: + winners.append(i) +if len(winners)>1: + winstring= ' and '.join(winners) + ' win!' +else: + winstring = ' '.join([winners[0],'wins!']) + +print("\nGAME OVER!!!\n"+winstring+"\n") +print(dcs) \ No newline at end of file From 33a381f29f6e8a7a8b8d9af93863f4f151d0b534 Mon Sep 17 00:00:00 2001 From: lieuraymond Date: Sat, 18 Jan 2020 16:27:47 -0800 Subject: [PATCH 05/18] Create testUtility.py --- projects/lieur/dominion/testUtility.py | 762 +++++++++++++++++++++++++ 1 file changed, 762 insertions(+) create mode 100644 projects/lieur/dominion/testUtility.py diff --git a/projects/lieur/dominion/testUtility.py b/projects/lieur/dominion/testUtility.py new file mode 100644 index 0000000..6a0a534 --- /dev/null +++ b/projects/lieur/dominion/testUtility.py @@ -0,0 +1,762 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue Oct 13 15:26:55 2015 + +@author: tfleck +""" +import random +from collections import Counter, OrderedDict +from operator import itemgetter +import re +import pandas + +class Card(): + def __init__(self,name,category,cost,buypower,vpoints): + self.name = name + self.category = category + self.cost = cost + self.buypower = buypower + self.vpoints = vpoints + def react(self,player): + return False + +class Coin_card(Card): + def __init__(self,name,cost,buypower): + Card.__init__(self,name,"coin",cost,buypower,0) + +class Copper(Coin_card): + def __init__(self): + Coin_card.__init__(self,"Copper",0,1) + +class Silver(Coin_card): + def __init__(self): + Coin_card.__init__(self,"Silver",3,2) + +class Gold(Coin_card): + def __init__(self): + Coin_card.__init__(self,"Gold",6,3) + +class Victory_card(Card): + def __init__(self,name,cost,vpoints): + Card.__init__(self,name,"victory",cost,0,vpoints) + +class Estate(Victory_card): + def __init__(self): + Victory_card.__init__(self,"Estate",2,1) + +class Duchy(Victory_card): + def __init__(self): + Victory_card.__init__(self,"Duchy",5,3) + +class Province(Victory_card): + def __init__(self): + Victory_card.__init__(self,"Province",8,6) + +class Gardens(Victory_card): + def __init__(self): + Victory_card.__init__(self,"Gardens",4,0) + +class Curse(Card): + def __init__(self): + Card.__init__(self,"Curse","curse",0,0,-1) + +class Action_card(Card): + def __init__(self,name,cost,actions,cards,buys,coins): + Card.__init__(self,name,"action",cost,0,0) + self.actions = actions + self.cards = cards + self.buys = buys + self.coins = coins + def use(self,player,trash): + player.played.append(self) + player.hand.remove(self) + def augment(self,player): + player.actions+=self.actions + player.buys+=self.buys + player.purse+=self.coins + for i in range(self.cards): + player.draw() + def play(self,player,players,supply,trash): + pass + +class Woodcutter(Action_card): + def __init__(self): + Action_card.__init__(self,"Woodcutter",3,0,0,1,2) + +class Smithy(Action_card): + def __init__(self): + Action_card.__init__(self,"Smithy",4,0,3,0,0) + +class Laboratory(Action_card): + def __init__(self): + Action_card.__init__(self,"Laboratory",5,1,2,0,0) + +class Village(Action_card): + def __init__(self): + Action_card.__init__(self,"Village",3,2,1,0,0) + +class Festival(Action_card): + def __init__(self): + Action_card.__init__(self,"Festival",5,2,0,1,2) + +class Market(Action_card): + def __init__(self): + Action_card.__init__(self,"Market",5,1,1,1,1) + +class Chancellor(Action_card): + def __init__(self): + Action_card.__init__(self,"Chancellor",3,0,0,0,2) + def play(self,player,players,supply,trash): + if player.yesnoinput('Would you like to discard your entire deck?'): + player.discard = player.discard + player.deck + player.deck = [] + +class Workshop(Action_card): + def __init__(self): + Action_card.__init__(self,"Workshop",3,0,0,0,0) + def play(self,player,players,supply,trash): + player.gaincard(supply,4) + +class Moneylender(Action_card): + def __init__(self): + Action_card.__init__(self,"Moneylender",4,0,0,0,0) + def play(self,player,players,supply,trash): + c = getcard("Copper",supply,player.hand,"your hand") + if c: + trash.append(c) + player.hand.remove(c) + player.purse += 3 + +class Chapel(Action_card): + def __init__(self): + Action_card.__init__(self,"Chapel",2,0,0,0,0) + def play(self,player,players,supply,trash): + trashed=0 + while trashed<4 and len(player.hand)>0: + trashcard = input("Choose a card from your hand to trash: ") + if not trashcard: + break + c = getcard(trashcard,supply,player.hand,"your hand") + if c: + trash.append(c) + player.hand.remove(c) + trashed+=1 + +class Cellar(Action_card): + def __init__(self): + Action_card.__init__(self,"Cellar",2,1,0,0,0) + def play(self,player,players,supply,trash): + discarded=0 + while len(player.hand)>0: + dis_card=input("Choose a card from your hand to discard: ") + if not dis_card: + break + c = getcard(dis_card,supply,player.hand,"your hand") + if c: + player.discard.append(c) + player.hand.remove(c) + discarded+=1 + for j in range(discarded): + player.draw() + +class Remodel(Action_card): + def __init__(self): + Action_card.__init__(self,"Remodel",4,0,0,0,0) + def play(self,player,players,supply,trash): + while len(player.hand)>0: + this_card = input("Choose a card from your hand to remodel: ") + c = getcard(this_card,supply,player.hand,"your hand") + if c: + trash.append(c) + player.hand.remove(c) + player.gaincard(supply,c.cost+2) + break + +class Adventurer(Action_card): + def __init__(self): + Action_card.__init__(self,"Adventurer",6,0,0,0,0) + def play(self,player,players,supply,trash): + coins_added = 0 + while (player.deck or player.discard) and coins_added <2: + player.draw() + if player.hand[-1].category == "coin": + coins_added +=1 + else: + player.aside.append(player.hand.pop()) + +class Feast(Action_card): + def __init__(self): + Action_card.__init__(self,"Feast",4,0,0,0,0) + def use(self,player,trash): + trash.append(self) + player.hand.remove(self) + def play(self,player,players,supply,trash): + player.gaincard(supply,5) + +class Mine(Action_card): + def __init__(self): + Action_card.__init__(self,"Mine",5,0,0,0,0) + def play(self,player,players,supply,trash): + while "coin" in catinlist(player.hand): + this_card = input("Choose a coin from your hand to upgrade: ") + c = getcard(this_card,supply,player.hand,"your hand",["coin"]) + if c: + trash.append(c) + player.hand.remove(c) + while c.cost>2 or len(supply["Copper"])>0 or len(supply["Silver"])>0: + pick = input("Choose a coin to gain. Any coin up to " + str(c.cost+3)+": ") + g = getcard(pick,supply,categories=["coin"],upto=c.cost+3) + if g: + player.hand.append(g) + supply[pick].remove(g) + break + break + +class Library(Action_card): + def __init__(self): + Action_card.__init__(self,"Library",5,0,0,0,0) + def play(self,player,players,supply,trash): + while (player.deck or player.discard) and len(player.hand) <7: + player.draw(player.hold) + if (player.hold[-1].category == "action" and not player.yesnoinput("You drew " + player.hold[-1].name + ". Would you like to keep it?",", add to my hand", ", set it aside")): + player.aside.append(player.hold.pop()) + else: + player.hand.append(player.hold.pop()) + +class Moat(Action_card): + def __init__(self): + Action_card.__init__(self,"Moat",2,0,2,0,0) + def react(self,player): + player.show() + return player.yesnoinput(player.name + ", you have a " + self.name + + " in your hand. Do you want to block the attack?") + +class Council_Room(Action_card): + def __init__(self): + Action_card.__init__(self,"Council Room",5,0,3,1,0) + def play(self,this_player,players,supply,trash): + for player in players: + player.draw() + +class Witch(Action_card): + def __init__(self): + Action_card.__init__(self,"Witch",5,0,2,0,0) + def play(self,this_player,players,supply,trash): + if len(supply["Curse"])>0: + for player in players: + if player==this_player: + pass + else: + for c in player.hand: + if c.react(player): + break + else: + if len(supply["Curse"])>0: + player.discard.append(supply["Curse"].pop()) + +class Bureaucrat(Action_card): + def __init__(self): + Action_card.__init__(self,"Bureaucrat",4,0,0,0,0) + def play(self,this_player,players,supply,trash): + if len(supply["Silver"])>0: + this_player.deck.insert(0,supply["Silver"].pop()) + for player in players: + if (not player==this_player) and ("victory" in catinlist(player.hand)): + for c in player.hand: + if c.react(player): + break + else: + player.show() + while True: + putback = player.choose_discard(player.name + ", which victory card" + + " do you want to put on top of your deck?\n--> ") + c = getcard(putback,supply,player.hand,"your hand",["victory"]) + if c: + player.hand.remove(c) + player.deck.insert(0,c) + break + +class Militia(Action_card): + def __init__(self): + Action_card.__init__(self,"Militia",4,0,0,0,2) + def play(self,this_player,players,supply,trash): + for player in players: + if (not player==this_player) and len(player.hand)>3: + for c in player.hand: + if c.react(player): + break + else: + player.show() + while len(player.hand)>3: + dis_card=player.choose_discard(player.name + ", choose a card from your hand to discard: ") + if dis_card: + c = getcard(dis_card,supply,player.hand,"your hand") + if c: + player.hand.remove(c) + player.discard.append(c) + +class Spy(Action_card): + def __init__(self): + Action_card.__init__(self,"Spy",4,1,1,0,0) + def play(self,this_player,players,supply,trash): + for player in players: + for c in player.hand: + if c.react(player): + break + else: + b = player.draw([]) + if not b: + continue + else: + print("The first card in the deck of " + player.name + " is " + b.name) + if this_player.yesnoinput(this_player.name + ", do you want " + player.name + " to discard this?", + ", discard",", keep"): + player.discard.append(b) + else: + player.deck.insert(0,b) + #check logic of this structure + +class Thief(Action_card): + def __init__(self): + Action_card.__init__(self,"Thief",4,0,0,0,0) + def play(self,this_player,players,supply,trash): + for player in players: + if player == this_player: + continue + for c in player.hand: + if c.react(player): + break + else: + for i in range(2): + player.draw(player.hold) + print( player.name, namesinlist(player.hold)) + if "coin" in catinlist(player.hold): + while True: + burn = input("Which card would you like " + player.name + " to trash?\n-->") + c = getcard(burn,supply,player.hold," the top 2 cards",["coin"]) + if c: + player.hold.remove(c) + break + if this_player.yesnoinput("Do you want to steal it?",", it's mine!",", leave it in the trash."): + this_player.discard.append(c) + else: + trash.append(c) + player.discard=player.discard+player.hold + player.hold = [] + +class Throne_Room(Action_card): + def __init__(self): + Action_card.__init__(self,"Throne Room",4,0,0,0,0) + def play(self,player,players,supply,trash): + if "action" in catinlist(player.hand): + while True: + double = input("What card would you like to double?\n--> ") + c = getcard(double,supply,player.hand," your hand",["action"]) + if c: + c.use(player,trash) + c.augment(player) + c.play(player,players,supply,trash) + player.show() + c.augment(player) + c.play(player,players,supply,trash) + break + + +class Player(): + def __init__(self,name): + self.name = name + self.hand = [] + self.deck = [Copper()]*7 + [Estate()]*3 + random.shuffle(self.deck) + self.played = [] + self.discard = [] + self.aside = [] + self.hold = [] + for i in range(5): + self.draw() + + def other(self): + return self.played+self.discard+self.hold+self.aside + def stack(self): + return (self.deck + self.hand + self.played + self.discard + self.aside + self.hold) + def draw(self,dest=None): + #defualt destination is player's hand + if dest==None: + dest = self.hand + #Replenish deck if necessary. + if len(self.deck)==0: + self.deck = self.discard + self.discard = [] + random.shuffle(self.deck) + #If deck has cards, add card to destination list + if len(self.deck)>0: + c = self.deck.pop(0) + dest.append(c) + return c + def turn(self,players,supply,trash): + self.show() + self.actions = 1 + self.buys = 1 + self.purse = 0 + #action phase + while self.actions>0 and 'action' in catinlist(self.hand): + playthis = input("Which card would you like to play? You have " + + str(self.actions) + " action(s). \n-Hit enter for no play. --> ") + if playthis: + c = getcard(playthis,supply,self.hand,"your hand",['action']) + if c: + self.actions = self.actions - 1 + c.use(self,trash) + c.augment(self) + c.play(self,players,supply,trash) + self.show() + else: + self.actions=0 + #buy phase + for c in self.hand: + self.purse += c.buypower + while self.buys>0: + buy_string = "Buying power is " + str(self.purse) + ". You have " + str(self.buys) + " buy" + if self.buys>1: + buy_string += "s" + buy_string += "." + print( buy_string) + purchase = input("What would you like to purchase? -Hit enter for no purchase.-\n--> ") + if not purchase: + break + else: + c = getcard(purchase,supply,upto=self.purse) + if c: + self.discard.append(supply[purchase].pop()) + self.buys = self.buys -1 + self.purse = self.purse - c.cost + + #cleanup phase + self.discard = self.discard + self.played + self.hand + self.aside + self.played = [] + self.hand = [] + self.aside = [] + for i in range(5): + self.draw() + + def gaincard(self,supply,upto): + while True: + gain = input("What would you like to get? Any card up to " + str(upto) + "\n--> ") + c = getcard(gain,supply,upto=upto) + if c: + self.discard.append(c) + supply[gain].remove(c) + break + def yesnoinput(self,prompt,yesstring='',nostring=''): + print(prompt + "\n1 - Yes" + yesstring + "\n0 - No" + nostring) + while True: + r = input("--> ") + if r == "0": + return False + if r == "1": + return True + + def choose_discard(self,prompt): + return input(prompt) + + def show(self): + print (self.name) + print ("hand:", ", ".join(sorted(namesinlist(self.hand)))) + if len(self.deck)>0: + print ("deck (alphabetical order):", ", ".join(sorted(namesinlist(self.deck)))) + if len(self.discard)>0: + print ("discard:", ", ".join(sorted(namesinlist(self.discard)))) + if len(self.played)>0: + print ("played:", ", ".join(sorted(namesinlist(self.played)))) + if len(self.aside)>0: + print ("aside:", ", ".join(sorted(namesinlist(self.aside)))) + print ("\r") + + def action_balance(self): + balance = 0 + for c in self.stack(): + if c.category == "action": + balance = balance - 1 + c.actions + return 70*balance / len(self.stack()) + + def cardsummary(self): + summary = {} + for c in self.stack(): + if c.name in summary: + summary[c.name] += 1 + else: + summary[c.name] = 1 + summary['VICTORY POINTS']=self.calcpoints() + return summary + + def calcpoints(self): + tally = 0 + gardens = 0 + n = 0 + for c in self.stack(): + tally += c.vpoints + n += 1 + if c.name == "Gardens": + gardens+=1 + return tally + n//10 * gardens + +class ComputerPlayer(Player): + def __init__(self,name): + Player.__init__(self,name) + self.index = 0 + self.buygaintable = [] + #beginning and middle of game + self.buygaintable1 = ["Province","Gold","Laboratory","Festival","Witch", + "Council Room","Market","Militia","Adventurer","Smithy","Bureaucrat","Silver","Moat",""] + #end of game + self.buygaintable2 = ["Province","Gardens","Duchy","Estate","Gold","Silver",""] + #beginning and middle of the game, too many action cards + self.buygaintable3 = ["Province","Gold","Festival","Laboratory","Market","Village", + "Silver",""] + self.playtable1 = ["Village","Festival","Market","Laboratory","Witch", + "Council Room","Militia","Adventurer","Smithy","Bureaucrat","Moat",""] + self.discardtable1 = ["Gardens","Duchy","Province","Estate","Curse","Copper", + "Village","Bureaucrat","Silver","Militia","Smithy","Council Room","Witch", + "Festival","Market","Adventurer","Laboratory","Gold","Moat"] + + def turn(self,players,supply,trash): + self.show() + self.actions = 1 + self.buys = 1 + self.purse = 0 + #action phase + self.index = 0 + while self.actions>0 and 'action' in catinlist(self.hand): + playthis = self.playtable1[self.index] + if playthis: + c = self.getcard(playthis,supply,self.hand,"your hand",['action']) + if c: + print (self.name + " plays " + c.name) + self.actions = self.actions - 1 + c.use(self,trash) + self.index=0 + c.augment(self) + c.play(self,players,supply,trash) + self.show() + else: + self.index += 1 + else: + self.actions=0 + #buy phase + if len(supply["Province"])>len(players)+totalbuypower(self.deck)/8: + if self.action_balance()<-10: + self.buygaintable = self.buygaintable3 + else: + self.buygaintable = self.buygaintable1 + else: + self.buygaintable = self.buygaintable2 + self.index = 0 + for c in self.hand: + self.purse += c.buypower + while self.buys>0: + purchase = self.buygaintable[self.index] + if not purchase: + break + else: + c = self.getcard(purchase,supply,upto=self.purse) + if c: + self.discard.append(supply[purchase].pop()) + self.index = 0 + self.buys = self.buys -1 + self.purse = self.purse - c.cost + print (self.name + " bought " + c.name) + else: + self.index += 1 + + #cleanup phase + self.discard = self.discard + self.played + self.hand + self.aside + self.played = [] + self.hand = [] + self.aside = [] + for i in range(5): + self.draw() + + def getcard(self,name,supply,target_list=None,target_name= "the supply anymore",categories=['action','coin','curse','victory'],upto=100): + if not name in supply: + #print name + " is not in this game." + return None + if not target_list: + target_list = supply[name] + nameslist = namesinlist(target_list) + if not name in nameslist: + #print "There is no " + name + " in " + target_name + return None + i = nameslist.index(name) + c = target_list[i] + if c.category not in categories: + catstring = categories[0] + for i in categories[1:]: + catstring = catstring + " or " + categories[i] + #print name + " is not a " + catstring + " card." + return None + if c.cost > upto: + #print name + " costs " + str(c.cost) + return None + return c + + def choose_discard(self,prompt): + index = 0 + while True: + dis_card = self.discardtable1[index] + c = self.getcard(dis_card,[dis_card],self.hand) + if c: + return c.name + else: + index+=1 + + def yesnoinput(self,prompt,yesstring='',nostring=''): + return True + + def show(self): + pass + +class TablePlayer(ComputerPlayer): + def __init__(self,name): + ComputerPlayer.__init__(self,name) + self.index=0 + self.buygaintable=[] + q=re.match(r'([a-zA-Z]+)(\d+)',name) + if q: + self.number = q.group(2) + else: + print(name) + self.playtable1 = ["Village","Festival","Market","Laboratory","Witch", + "Council Room","Militia","Adventurer","Smithy","Bureaucrat","Moat",""] + self.discardtable1 = ["Gardens","Duchy","Province","Estate","Curse","Copper", + "Village","Bureaucrat","Silver","Militia","Smithy","Council Room","Witch", + "Festival","Market","Adventurer","Laboratory","Gold","Moat"] + + def turn(self,players,supply,trash): + self.show() + self.actions = 1 + self.buys = 1 + self.purse = 0 + #action phase + self.index = 0 + while self.actions>0 and 'action' in catinlist(self.hand): + playthis = self.playtable1[self.index] + if playthis: + c = self.getcard(playthis,supply,self.hand,"your hand",['action']) + if c: + #print (self.name + " plays " + c.name) + self.actions = self.actions - 1 + c.use(self,trash) + self.index=0 + c.augment(self) + c.play(self,players,supply,trash) + self.show() + else: + self.index += 1 + else: + self.actions=0 + #buy phase + v= self.number + csvstring = r"Dominionbuy" + str(v) + ".csv" + buydf=pandas.read_csv(csvstring,na_filter=False) + sortedbuydf=buydf.sort_values("Buyvalues",ascending=False) + ranktable = sortedbuydf.Cardname + self.index = 0 + for c in self.hand: + self.purse += c.buypower + while self.buys>0: + purchase = ranktable.iloc[self.index] + if not purchase: + break + else: + c = self.getcard(purchase,supply,upto=self.purse) + if c: + self.discard.append(supply[purchase].pop()) + self.index = 0 + self.buys = self.buys -1 + self.purse = self.purse - c.cost + else: + self.index += 1 + + #cleanup phase + self.discard = self.discard + self.played + self.hand + self.aside + self.played = [] + self.hand = [] + self.aside = [] + for i in range(5): + self.draw() + + +def gameover(supply): + if len(supply["Province"])==0: + return True + out = 0 + for stack in supply: + if len(supply[stack])==0: + out+=1 + if out>=3: + return True + return False + +def namesinlist(cardlist): + namelist = [] + for c in cardlist: + namelist.append(c.name) + return namelist + +def catinlist(cardlist): + catlist = [] + for c in cardlist: + catlist.append(c.category) + return catlist + +def getcard(name,supply,target_list=None,target_name= "the supply anymore",categories=['action','coin','curse','victory'],upto=100): + if not name in supply: + print( name + " is not in this game.") + return None + if not target_list: + target_list = supply[name] + nameslist = namesinlist(target_list) + if not name in nameslist: + print ("There is no " + name + " in " + target_name) + return None + i = nameslist.index(name) + c = target_list[i] + if c.category not in categories: + catstring = categories[0] + for i in categories[1:]: + catstring = catstring + " or " + categories[i] + print (name + " is not a " + catstring + " card.") + return None + if c.cost > upto: + print (name + " costs " + str(c.cost)) + return None + return c + +def totalbuypower(cardlist): + TBP = 0 + for c in cardlist: + TBP += c.buypower + if c.category == "action": + TBP += c.coins + return TBP + +def cardsummaries(players): + cardsums={} + for player in players: + cardsums[player.name]=player.cardsummary() + cardsdf = pandas.DataFrame(cardsums).fillna(0).sort_index() + vp=cardsdf.loc[['VICTORY POINTS']] + cardsdf.drop(['VICTORY POINTS'],inplace=True) + return pandas.concat([cardsdf,vp],axis=0).fillna(0).astype(int) + +def countsupply(supply,form): + return [len(supply[a]) for a in form] + +def countcards(cards,form): + dcount = Counter(namesinlist(cards)) + return [dcount[a] for a in form] + +def rankcards(form,vector): + od = OrderedDict(zip(form,vector)) + sd = OrderedDict(sorted(od.items(),key = itemgetter(1),reverse=True)) + return list(sd.keys()) \ No newline at end of file From 989788e19d676142912aab3f4e074d0872910726 Mon Sep 17 00:00:00 2001 From: lieuraymond Date: Sat, 18 Jan 2020 18:29:55 -0800 Subject: [PATCH 06/18] Update which file to refactor --- projects/lieur/dominion/testUtility.py | 865 ++++--------------------- 1 file changed, 111 insertions(+), 754 deletions(-) diff --git a/projects/lieur/dominion/testUtility.py b/projects/lieur/dominion/testUtility.py index 6a0a534..b4d6021 100644 --- a/projects/lieur/dominion/testUtility.py +++ b/projects/lieur/dominion/testUtility.py @@ -1,762 +1,119 @@ # -*- coding: utf-8 -*- """ -Created on Tue Oct 13 15:26:55 2015 +Created on Tue Oct 13 15:42:42 2015 @author: tfleck """ -import random -from collections import Counter, OrderedDict -from operator import itemgetter -import re -import pandas - -class Card(): - def __init__(self,name,category,cost,buypower,vpoints): - self.name = name - self.category = category - self.cost = cost - self.buypower = buypower - self.vpoints = vpoints - def react(self,player): - return False - -class Coin_card(Card): - def __init__(self,name,cost,buypower): - Card.__init__(self,name,"coin",cost,buypower,0) - -class Copper(Coin_card): - def __init__(self): - Coin_card.__init__(self,"Copper",0,1) - -class Silver(Coin_card): - def __init__(self): - Coin_card.__init__(self,"Silver",3,2) - -class Gold(Coin_card): - def __init__(self): - Coin_card.__init__(self,"Gold",6,3) - -class Victory_card(Card): - def __init__(self,name,cost,vpoints): - Card.__init__(self,name,"victory",cost,0,vpoints) - -class Estate(Victory_card): - def __init__(self): - Victory_card.__init__(self,"Estate",2,1) - -class Duchy(Victory_card): - def __init__(self): - Victory_card.__init__(self,"Duchy",5,3) - -class Province(Victory_card): - def __init__(self): - Victory_card.__init__(self,"Province",8,6) - -class Gardens(Victory_card): - def __init__(self): - Victory_card.__init__(self,"Gardens",4,0) - -class Curse(Card): - def __init__(self): - Card.__init__(self,"Curse","curse",0,0,-1) - -class Action_card(Card): - def __init__(self,name,cost,actions,cards,buys,coins): - Card.__init__(self,name,"action",cost,0,0) - self.actions = actions - self.cards = cards - self.buys = buys - self.coins = coins - def use(self,player,trash): - player.played.append(self) - player.hand.remove(self) - def augment(self,player): - player.actions+=self.actions - player.buys+=self.buys - player.purse+=self.coins - for i in range(self.cards): - player.draw() - def play(self,player,players,supply,trash): - pass - -class Woodcutter(Action_card): - def __init__(self): - Action_card.__init__(self,"Woodcutter",3,0,0,1,2) - -class Smithy(Action_card): - def __init__(self): - Action_card.__init__(self,"Smithy",4,0,3,0,0) - -class Laboratory(Action_card): - def __init__(self): - Action_card.__init__(self,"Laboratory",5,1,2,0,0) - -class Village(Action_card): - def __init__(self): - Action_card.__init__(self,"Village",3,2,1,0,0) - -class Festival(Action_card): - def __init__(self): - Action_card.__init__(self,"Festival",5,2,0,1,2) - -class Market(Action_card): - def __init__(self): - Action_card.__init__(self,"Market",5,1,1,1,1) - -class Chancellor(Action_card): - def __init__(self): - Action_card.__init__(self,"Chancellor",3,0,0,0,2) - def play(self,player,players,supply,trash): - if player.yesnoinput('Would you like to discard your entire deck?'): - player.discard = player.discard + player.deck - player.deck = [] - -class Workshop(Action_card): - def __init__(self): - Action_card.__init__(self,"Workshop",3,0,0,0,0) - def play(self,player,players,supply,trash): - player.gaincard(supply,4) - -class Moneylender(Action_card): - def __init__(self): - Action_card.__init__(self,"Moneylender",4,0,0,0,0) - def play(self,player,players,supply,trash): - c = getcard("Copper",supply,player.hand,"your hand") - if c: - trash.append(c) - player.hand.remove(c) - player.purse += 3 - -class Chapel(Action_card): - def __init__(self): - Action_card.__init__(self,"Chapel",2,0,0,0,0) - def play(self,player,players,supply,trash): - trashed=0 - while trashed<4 and len(player.hand)>0: - trashcard = input("Choose a card from your hand to trash: ") - if not trashcard: - break - c = getcard(trashcard,supply,player.hand,"your hand") - if c: - trash.append(c) - player.hand.remove(c) - trashed+=1 - -class Cellar(Action_card): - def __init__(self): - Action_card.__init__(self,"Cellar",2,1,0,0,0) - def play(self,player,players,supply,trash): - discarded=0 - while len(player.hand)>0: - dis_card=input("Choose a card from your hand to discard: ") - if not dis_card: - break - c = getcard(dis_card,supply,player.hand,"your hand") - if c: - player.discard.append(c) - player.hand.remove(c) - discarded+=1 - for j in range(discarded): - player.draw() - -class Remodel(Action_card): - def __init__(self): - Action_card.__init__(self,"Remodel",4,0,0,0,0) - def play(self,player,players,supply,trash): - while len(player.hand)>0: - this_card = input("Choose a card from your hand to remodel: ") - c = getcard(this_card,supply,player.hand,"your hand") - if c: - trash.append(c) - player.hand.remove(c) - player.gaincard(supply,c.cost+2) - break - -class Adventurer(Action_card): - def __init__(self): - Action_card.__init__(self,"Adventurer",6,0,0,0,0) - def play(self,player,players,supply,trash): - coins_added = 0 - while (player.deck or player.discard) and coins_added <2: - player.draw() - if player.hand[-1].category == "coin": - coins_added +=1 - else: - player.aside.append(player.hand.pop()) - -class Feast(Action_card): - def __init__(self): - Action_card.__init__(self,"Feast",4,0,0,0,0) - def use(self,player,trash): - trash.append(self) - player.hand.remove(self) - def play(self,player,players,supply,trash): - player.gaincard(supply,5) - -class Mine(Action_card): - def __init__(self): - Action_card.__init__(self,"Mine",5,0,0,0,0) - def play(self,player,players,supply,trash): - while "coin" in catinlist(player.hand): - this_card = input("Choose a coin from your hand to upgrade: ") - c = getcard(this_card,supply,player.hand,"your hand",["coin"]) - if c: - trash.append(c) - player.hand.remove(c) - while c.cost>2 or len(supply["Copper"])>0 or len(supply["Silver"])>0: - pick = input("Choose a coin to gain. Any coin up to " + str(c.cost+3)+": ") - g = getcard(pick,supply,categories=["coin"],upto=c.cost+3) - if g: - player.hand.append(g) - supply[pick].remove(g) - break - break - -class Library(Action_card): - def __init__(self): - Action_card.__init__(self,"Library",5,0,0,0,0) - def play(self,player,players,supply,trash): - while (player.deck or player.discard) and len(player.hand) <7: - player.draw(player.hold) - if (player.hold[-1].category == "action" and not player.yesnoinput("You drew " + player.hold[-1].name + ". Would you like to keep it?",", add to my hand", ", set it aside")): - player.aside.append(player.hold.pop()) - else: - player.hand.append(player.hold.pop()) - -class Moat(Action_card): - def __init__(self): - Action_card.__init__(self,"Moat",2,0,2,0,0) - def react(self,player): - player.show() - return player.yesnoinput(player.name + ", you have a " + self.name + - " in your hand. Do you want to block the attack?") -class Council_Room(Action_card): - def __init__(self): - Action_card.__init__(self,"Council Room",5,0,3,1,0) - def play(self,this_player,players,supply,trash): - for player in players: - player.draw() - -class Witch(Action_card): - def __init__(self): - Action_card.__init__(self,"Witch",5,0,2,0,0) - def play(self,this_player,players,supply,trash): - if len(supply["Curse"])>0: - for player in players: - if player==this_player: - pass - else: - for c in player.hand: - if c.react(player): - break - else: - if len(supply["Curse"])>0: - player.discard.append(supply["Curse"].pop()) - -class Bureaucrat(Action_card): - def __init__(self): - Action_card.__init__(self,"Bureaucrat",4,0,0,0,0) - def play(self,this_player,players,supply,trash): - if len(supply["Silver"])>0: - this_player.deck.insert(0,supply["Silver"].pop()) - for player in players: - if (not player==this_player) and ("victory" in catinlist(player.hand)): - for c in player.hand: - if c.react(player): - break - else: - player.show() - while True: - putback = player.choose_discard(player.name + ", which victory card" + - " do you want to put on top of your deck?\n--> ") - c = getcard(putback,supply,player.hand,"your hand",["victory"]) - if c: - player.hand.remove(c) - player.deck.insert(0,c) - break - -class Militia(Action_card): - def __init__(self): - Action_card.__init__(self,"Militia",4,0,0,0,2) - def play(self,this_player,players,supply,trash): - for player in players: - if (not player==this_player) and len(player.hand)>3: - for c in player.hand: - if c.react(player): - break - else: - player.show() - while len(player.hand)>3: - dis_card=player.choose_discard(player.name + ", choose a card from your hand to discard: ") - if dis_card: - c = getcard(dis_card,supply,player.hand,"your hand") - if c: - player.hand.remove(c) - player.discard.append(c) - -class Spy(Action_card): - def __init__(self): - Action_card.__init__(self,"Spy",4,1,1,0,0) - def play(self,this_player,players,supply,trash): - for player in players: - for c in player.hand: - if c.react(player): - break - else: - b = player.draw([]) - if not b: - continue - else: - print("The first card in the deck of " + player.name + " is " + b.name) - if this_player.yesnoinput(this_player.name + ", do you want " + player.name + " to discard this?", - ", discard",", keep"): - player.discard.append(b) - else: - player.deck.insert(0,b) - #check logic of this structure - -class Thief(Action_card): - def __init__(self): - Action_card.__init__(self,"Thief",4,0,0,0,0) - def play(self,this_player,players,supply,trash): - for player in players: - if player == this_player: - continue - for c in player.hand: - if c.react(player): - break - else: - for i in range(2): - player.draw(player.hold) - print( player.name, namesinlist(player.hold)) - if "coin" in catinlist(player.hold): - while True: - burn = input("Which card would you like " + player.name + " to trash?\n-->") - c = getcard(burn,supply,player.hold," the top 2 cards",["coin"]) - if c: - player.hold.remove(c) - break - if this_player.yesnoinput("Do you want to steal it?",", it's mine!",", leave it in the trash."): - this_player.discard.append(c) - else: - trash.append(c) - player.discard=player.discard+player.hold - player.hold = [] - -class Throne_Room(Action_card): - def __init__(self): - Action_card.__init__(self,"Throne Room",4,0,0,0,0) - def play(self,player,players,supply,trash): - if "action" in catinlist(player.hand): - while True: - double = input("What card would you like to double?\n--> ") - c = getcard(double,supply,player.hand," your hand",["action"]) - if c: - c.use(player,trash) - c.augment(player) - c.play(player,players,supply,trash) - player.show() - c.augment(player) - c.play(player,players,supply,trash) - break - - -class Player(): - def __init__(self,name): - self.name = name - self.hand = [] - self.deck = [Copper()]*7 + [Estate()]*3 - random.shuffle(self.deck) - self.played = [] - self.discard = [] - self.aside = [] - self.hold = [] - for i in range(5): - self.draw() - - def other(self): - return self.played+self.discard+self.hold+self.aside - def stack(self): - return (self.deck + self.hand + self.played + self.discard + self.aside + self.hold) - def draw(self,dest=None): - #defualt destination is player's hand - if dest==None: - dest = self.hand - #Replenish deck if necessary. - if len(self.deck)==0: - self.deck = self.discard - self.discard = [] - random.shuffle(self.deck) - #If deck has cards, add card to destination list - if len(self.deck)>0: - c = self.deck.pop(0) - dest.append(c) - return c - def turn(self,players,supply,trash): - self.show() - self.actions = 1 - self.buys = 1 - self.purse = 0 - #action phase - while self.actions>0 and 'action' in catinlist(self.hand): - playthis = input("Which card would you like to play? You have " + - str(self.actions) + " action(s). \n-Hit enter for no play. --> ") - if playthis: - c = getcard(playthis,supply,self.hand,"your hand",['action']) - if c: - self.actions = self.actions - 1 - c.use(self,trash) - c.augment(self) - c.play(self,players,supply,trash) - self.show() - else: - self.actions=0 - #buy phase - for c in self.hand: - self.purse += c.buypower - while self.buys>0: - buy_string = "Buying power is " + str(self.purse) + ". You have " + str(self.buys) + " buy" - if self.buys>1: - buy_string += "s" - buy_string += "." - print( buy_string) - purchase = input("What would you like to purchase? -Hit enter for no purchase.-\n--> ") - if not purchase: - break - else: - c = getcard(purchase,supply,upto=self.purse) - if c: - self.discard.append(supply[purchase].pop()) - self.buys = self.buys -1 - self.purse = self.purse - c.cost - - #cleanup phase - self.discard = self.discard + self.played + self.hand + self.aside - self.played = [] - self.hand = [] - self.aside = [] - for i in range(5): - self.draw() - - def gaincard(self,supply,upto): - while True: - gain = input("What would you like to get? Any card up to " + str(upto) + "\n--> ") - c = getcard(gain,supply,upto=upto) - if c: - self.discard.append(c) - supply[gain].remove(c) - break - def yesnoinput(self,prompt,yesstring='',nostring=''): - print(prompt + "\n1 - Yes" + yesstring + "\n0 - No" + nostring) - while True: - r = input("--> ") - if r == "0": - return False - if r == "1": - return True - - def choose_discard(self,prompt): - return input(prompt) - - def show(self): - print (self.name) - print ("hand:", ", ".join(sorted(namesinlist(self.hand)))) - if len(self.deck)>0: - print ("deck (alphabetical order):", ", ".join(sorted(namesinlist(self.deck)))) - if len(self.discard)>0: - print ("discard:", ", ".join(sorted(namesinlist(self.discard)))) - if len(self.played)>0: - print ("played:", ", ".join(sorted(namesinlist(self.played)))) - if len(self.aside)>0: - print ("aside:", ", ".join(sorted(namesinlist(self.aside)))) - print ("\r") - - def action_balance(self): - balance = 0 - for c in self.stack(): - if c.category == "action": - balance = balance - 1 + c.actions - return 70*balance / len(self.stack()) - - def cardsummary(self): - summary = {} - for c in self.stack(): - if c.name in summary: - summary[c.name] += 1 - else: - summary[c.name] = 1 - summary['VICTORY POINTS']=self.calcpoints() - return summary - - def calcpoints(self): - tally = 0 - gardens = 0 - n = 0 - for c in self.stack(): - tally += c.vpoints - n += 1 - if c.name == "Gardens": - gardens+=1 - return tally + n//10 * gardens - -class ComputerPlayer(Player): - def __init__(self,name): - Player.__init__(self,name) - self.index = 0 - self.buygaintable = [] - #beginning and middle of game - self.buygaintable1 = ["Province","Gold","Laboratory","Festival","Witch", - "Council Room","Market","Militia","Adventurer","Smithy","Bureaucrat","Silver","Moat",""] - #end of game - self.buygaintable2 = ["Province","Gardens","Duchy","Estate","Gold","Silver",""] - #beginning and middle of the game, too many action cards - self.buygaintable3 = ["Province","Gold","Festival","Laboratory","Market","Village", - "Silver",""] - self.playtable1 = ["Village","Festival","Market","Laboratory","Witch", - "Council Room","Militia","Adventurer","Smithy","Bureaucrat","Moat",""] - self.discardtable1 = ["Gardens","Duchy","Province","Estate","Curse","Copper", - "Village","Bureaucrat","Silver","Militia","Smithy","Council Room","Witch", - "Festival","Market","Adventurer","Laboratory","Gold","Moat"] - - def turn(self,players,supply,trash): - self.show() - self.actions = 1 - self.buys = 1 - self.purse = 0 - #action phase - self.index = 0 - while self.actions>0 and 'action' in catinlist(self.hand): - playthis = self.playtable1[self.index] - if playthis: - c = self.getcard(playthis,supply,self.hand,"your hand",['action']) - if c: - print (self.name + " plays " + c.name) - self.actions = self.actions - 1 - c.use(self,trash) - self.index=0 - c.augment(self) - c.play(self,players,supply,trash) - self.show() - else: - self.index += 1 - else: - self.actions=0 - #buy phase - if len(supply["Province"])>len(players)+totalbuypower(self.deck)/8: - if self.action_balance()<-10: - self.buygaintable = self.buygaintable3 - else: - self.buygaintable = self.buygaintable1 - else: - self.buygaintable = self.buygaintable2 - self.index = 0 - for c in self.hand: - self.purse += c.buypower - while self.buys>0: - purchase = self.buygaintable[self.index] - if not purchase: - break - else: - c = self.getcard(purchase,supply,upto=self.purse) - if c: - self.discard.append(supply[purchase].pop()) - self.index = 0 - self.buys = self.buys -1 - self.purse = self.purse - c.cost - print (self.name + " bought " + c.name) - else: - self.index += 1 - - #cleanup phase - self.discard = self.discard + self.played + self.hand + self.aside - self.played = [] - self.hand = [] - self.aside = [] - for i in range(5): - self.draw() - - def getcard(self,name,supply,target_list=None,target_name= "the supply anymore",categories=['action','coin','curse','victory'],upto=100): - if not name in supply: - #print name + " is not in this game." - return None - if not target_list: - target_list = supply[name] - nameslist = namesinlist(target_list) - if not name in nameslist: - #print "There is no " + name + " in " + target_name - return None - i = nameslist.index(name) - c = target_list[i] - if c.category not in categories: - catstring = categories[0] - for i in categories[1:]: - catstring = catstring + " or " + categories[i] - #print name + " is not a " + catstring + " card." - return None - if c.cost > upto: - #print name + " costs " + str(c.cost) - return None - return c - - def choose_discard(self,prompt): - index = 0 - while True: - dis_card = self.discardtable1[index] - c = self.getcard(dis_card,[dis_card],self.hand) - if c: - return c.name - else: - index+=1 - - def yesnoinput(self,prompt,yesstring='',nostring=''): - return True - - def show(self): - pass - -class TablePlayer(ComputerPlayer): - def __init__(self,name): - ComputerPlayer.__init__(self,name) - self.index=0 - self.buygaintable=[] - q=re.match(r'([a-zA-Z]+)(\d+)',name) - if q: - self.number = q.group(2) - else: - print(name) - self.playtable1 = ["Village","Festival","Market","Laboratory","Witch", - "Council Room","Militia","Adventurer","Smithy","Bureaucrat","Moat",""] - self.discardtable1 = ["Gardens","Duchy","Province","Estate","Curse","Copper", - "Village","Bureaucrat","Silver","Militia","Smithy","Council Room","Witch", - "Festival","Market","Adventurer","Laboratory","Gold","Moat"] - - def turn(self,players,supply,trash): - self.show() - self.actions = 1 - self.buys = 1 - self.purse = 0 - #action phase - self.index = 0 - while self.actions>0 and 'action' in catinlist(self.hand): - playthis = self.playtable1[self.index] - if playthis: - c = self.getcard(playthis,supply,self.hand,"your hand",['action']) - if c: - #print (self.name + " plays " + c.name) - self.actions = self.actions - 1 - c.use(self,trash) - self.index=0 - c.augment(self) - c.play(self,players,supply,trash) - self.show() - else: - self.index += 1 - else: - self.actions=0 - #buy phase - v= self.number - csvstring = r"Dominionbuy" + str(v) + ".csv" - buydf=pandas.read_csv(csvstring,na_filter=False) - sortedbuydf=buydf.sort_values("Buyvalues",ascending=False) - ranktable = sortedbuydf.Cardname - self.index = 0 - for c in self.hand: - self.purse += c.buypower - while self.buys>0: - purchase = ranktable.iloc[self.index] - if not purchase: - break - else: - c = self.getcard(purchase,supply,upto=self.purse) - if c: - self.discard.append(supply[purchase].pop()) - self.index = 0 - self.buys = self.buys -1 - self.purse = self.purse - c.cost - else: - self.index += 1 - - #cleanup phase - self.discard = self.discard + self.played + self.hand + self.aside - self.played = [] - self.hand = [] - self.aside = [] - for i in range(5): - self.draw() - - -def gameover(supply): - if len(supply["Province"])==0: - return True - out = 0 - for stack in supply: - if len(supply[stack])==0: - out+=1 - if out>=3: - return True - return False - -def namesinlist(cardlist): - namelist = [] - for c in cardlist: - namelist.append(c.name) - return namelist - -def catinlist(cardlist): - catlist = [] - for c in cardlist: - catlist.append(c.category) - return catlist - -def getcard(name,supply,target_list=None,target_name= "the supply anymore",categories=['action','coin','curse','victory'],upto=100): - if not name in supply: - print( name + " is not in this game.") - return None - if not target_list: - target_list = supply[name] - nameslist = namesinlist(target_list) - if not name in nameslist: - print ("There is no " + name + " in " + target_name) - return None - i = nameslist.index(name) - c = target_list[i] - if c.category not in categories: - catstring = categories[0] - for i in categories[1:]: - catstring = catstring + " or " + categories[i] - print (name + " is not a " + catstring + " card.") - return None - if c.cost > upto: - print (name + " costs " + str(c.cost)) - return None - return c - -def totalbuypower(cardlist): - TBP = 0 - for c in cardlist: - TBP += c.buypower - if c.category == "action": - TBP += c.coins - return TBP - -def cardsummaries(players): - cardsums={} +import Dominion +import random +from collections import defaultdict + +#Get player names +player_names = ["Annie","*Ben","*Carla"] + +#number of curses and victory cards +if len(player_names)>2: + nV=12 +else: + nV=8 +nC = -10 + 10 * len(player_names) + +#Define box +box = {} +box["Woodcutter"]=[Dominion.Woodcutter()]*10 +box["Smithy"]=[Dominion.Smithy()]*10 +box["Laboratory"]=[Dominion.Laboratory()]*10 +box["Village"]=[Dominion.Village()]*10 +box["Festival"]=[Dominion.Festival()]*10 +box["Market"]=[Dominion.Market()]*10 +box["Chancellor"]=[Dominion.Chancellor()]*10 +box["Workshop"]=[Dominion.Workshop()]*10 +box["Moneylender"]=[Dominion.Moneylender()]*10 +box["Chapel"]=[Dominion.Chapel()]*10 +box["Cellar"]=[Dominion.Cellar()]*10 +box["Remodel"]=[Dominion.Remodel()]*10 +box["Adventurer"]=[Dominion.Adventurer()]*10 +box["Feast"]=[Dominion.Feast()]*10 +box["Mine"]=[Dominion.Mine()]*10 +box["Library"]=[Dominion.Library()]*10 +box["Gardens"]=[Dominion.Gardens()]*nV +box["Moat"]=[Dominion.Moat()]*10 +box["Council Room"]=[Dominion.Council_Room()]*10 +box["Witch"]=[Dominion.Witch()]*10 +box["Bureaucrat"]=[Dominion.Bureaucrat()]*10 +box["Militia"]=[Dominion.Militia()]*10 +box["Spy"]=[Dominion.Spy()]*10 +box["Thief"]=[Dominion.Thief()]*10 +box["Throne Room"]=[Dominion.Throne_Room()]*10 + +supply_order = {0:['Curse','Copper'],2:['Estate','Cellar','Chapel','Moat'], + 3:['Silver','Chancellor','Village','Woodcutter','Workshop'], + 4:['Gardens','Bureaucrat','Feast','Militia','Moneylender','Remodel','Smithy','Spy','Thief','Throne Room'], + 5:['Duchy','Market','Council Room','Festival','Laboratory','Library','Mine','Witch'], + 6:['Gold','Adventurer'],8:['Province']} + +#Pick 10 cards from box to be in the supply. +boxlist = [k for k in box] +random.shuffle(boxlist) +random10 = boxlist[:10] +supply = defaultdict(list,[(k,box[k]) for k in random10]) + + +#The supply always has these cards +supply["Copper"]=[Dominion.Copper()]*(60-len(player_names)*7) +supply["Silver"]=[Dominion.Silver()]*40 +supply["Gold"]=[Dominion.Gold()]*30 +supply["Estate"]=[Dominion.Estate()]*nV +supply["Duchy"]=[Dominion.Duchy()]*nV +supply["Province"]=[Dominion.Province()]*nV +supply["Curse"]=[Dominion.Curse()]*nC + +#initialize the trash +trash = [] + +#Costruct the Player objects +players = [] +for name in player_names: + if name[0]=="*": + players.append(Dominion.ComputerPlayer(name[1:])) + elif name[0]=="^": + players.append(Dominion.TablePlayer(name[1:])) + else: + players.append(Dominion.Player(name)) + +#Play the game +turn = 0 +while not Dominion.gameover(supply): + turn += 1 + print("\r") + for value in supply_order: + print (value) + for stack in supply_order[value]: + if stack in supply: + print (stack, len(supply[stack])) + print("\r") for player in players: - cardsums[player.name]=player.cardsummary() - cardsdf = pandas.DataFrame(cardsums).fillna(0).sort_index() - vp=cardsdf.loc[['VICTORY POINTS']] - cardsdf.drop(['VICTORY POINTS'],inplace=True) - return pandas.concat([cardsdf,vp],axis=0).fillna(0).astype(int) - -def countsupply(supply,form): - return [len(supply[a]) for a in form] - -def countcards(cards,form): - dcount = Counter(namesinlist(cards)) - return [dcount[a] for a in form] + print (player.name,player.calcpoints()) + print ("\rStart of turn " + str(turn)) + for player in players: + if not Dominion.gameover(supply): + print("\r") + player.turn(players,supply,trash) + -def rankcards(form,vector): - od = OrderedDict(zip(form,vector)) - sd = OrderedDict(sorted(od.items(),key = itemgetter(1),reverse=True)) - return list(sd.keys()) \ No newline at end of file +#Final score +dcs=Dominion.cardsummaries(players) +vp=dcs.loc['VICTORY POINTS'] +vpmax=vp.max() +winners=[] +for i in vp.index: + if vp.loc[i]==vpmax: + winners.append(i) +if len(winners)>1: + winstring= ' and '.join(winners) + ' win!' +else: + winstring = ' '.join([winners[0],'wins!']) + +print("\nGAME OVER!!!\n"+winstring+"\n") +print(dcs) \ No newline at end of file From e82f38f4384e483d267cfd4e6e849b564dbbf068 Mon Sep 17 00:00:00 2001 From: lieuraymond Date: Sun, 19 Jan 2020 01:02:41 -0800 Subject: [PATCH 07/18] Refactor --- projects/lieur/dominion/testDominion1.py | 85 ++--------- projects/lieur/dominion/testUtility.py | 187 ++++++++++------------- 2 files changed, 93 insertions(+), 179 deletions(-) diff --git a/projects/lieur/dominion/testDominion1.py b/projects/lieur/dominion/testDominion1.py index b4d6021..5b39c19 100644 --- a/projects/lieur/dominion/testDominion1.py +++ b/projects/lieur/dominion/testDominion1.py @@ -1,11 +1,12 @@ # -*- coding: utf-8 -*- """ -Created on Tue Oct 13 15:42:42 2015 +Created on Saturday, January 18, 2020 -@author: tfleck +@author: lieur """ import Dominion +import testUtility import random from collections import defaultdict @@ -13,74 +14,19 @@ player_names = ["Annie","*Ben","*Carla"] #number of curses and victory cards -if len(player_names)>2: - nV=12 -else: - nV=8 -nC = -10 + 10 * len(player_names) +nV, nC = testUtility.set_vc_number(player_names) #Define box -box = {} -box["Woodcutter"]=[Dominion.Woodcutter()]*10 -box["Smithy"]=[Dominion.Smithy()]*10 -box["Laboratory"]=[Dominion.Laboratory()]*10 -box["Village"]=[Dominion.Village()]*10 -box["Festival"]=[Dominion.Festival()]*10 -box["Market"]=[Dominion.Market()]*10 -box["Chancellor"]=[Dominion.Chancellor()]*10 -box["Workshop"]=[Dominion.Workshop()]*10 -box["Moneylender"]=[Dominion.Moneylender()]*10 -box["Chapel"]=[Dominion.Chapel()]*10 -box["Cellar"]=[Dominion.Cellar()]*10 -box["Remodel"]=[Dominion.Remodel()]*10 -box["Adventurer"]=[Dominion.Adventurer()]*10 -box["Feast"]=[Dominion.Feast()]*10 -box["Mine"]=[Dominion.Mine()]*10 -box["Library"]=[Dominion.Library()]*10 -box["Gardens"]=[Dominion.Gardens()]*nV -box["Moat"]=[Dominion.Moat()]*10 -box["Council Room"]=[Dominion.Council_Room()]*10 -box["Witch"]=[Dominion.Witch()]*10 -box["Bureaucrat"]=[Dominion.Bureaucrat()]*10 -box["Militia"]=[Dominion.Militia()]*10 -box["Spy"]=[Dominion.Spy()]*10 -box["Thief"]=[Dominion.Thief()]*10 -box["Throne Room"]=[Dominion.Throne_Room()]*10 +box, supply_order = testUtility.define_box(nV) -supply_order = {0:['Curse','Copper'],2:['Estate','Cellar','Chapel','Moat'], - 3:['Silver','Chancellor','Village','Woodcutter','Workshop'], - 4:['Gardens','Bureaucrat','Feast','Militia','Moneylender','Remodel','Smithy','Spy','Thief','Throne Room'], - 5:['Duchy','Market','Council Room','Festival','Laboratory','Library','Mine','Witch'], - 6:['Gold','Adventurer'],8:['Province']} - -#Pick 10 cards from box to be in the supply. -boxlist = [k for k in box] -random.shuffle(boxlist) -random10 = boxlist[:10] -supply = defaultdict(list,[(k,box[k]) for k in random10]) - - -#The supply always has these cards -supply["Copper"]=[Dominion.Copper()]*(60-len(player_names)*7) -supply["Silver"]=[Dominion.Silver()]*40 -supply["Gold"]=[Dominion.Gold()]*30 -supply["Estate"]=[Dominion.Estate()]*nV -supply["Duchy"]=[Dominion.Duchy()]*nV -supply["Province"]=[Dominion.Province()]*nV -supply["Curse"]=[Dominion.Curse()]*nC +#Set supply +supply = testUtility.set_supply(box, player_names, nV, nC) #initialize the trash trash = [] #Costruct the Player objects -players = [] -for name in player_names: - if name[0]=="*": - players.append(Dominion.ComputerPlayer(name[1:])) - elif name[0]=="^": - players.append(Dominion.TablePlayer(name[1:])) - else: - players.append(Dominion.Player(name)) +players = testUtility.set_players(player_names) #Play the game turn = 0 @@ -103,17 +49,4 @@ #Final score -dcs=Dominion.cardsummaries(players) -vp=dcs.loc['VICTORY POINTS'] -vpmax=vp.max() -winners=[] -for i in vp.index: - if vp.loc[i]==vpmax: - winners.append(i) -if len(winners)>1: - winstring= ' and '.join(winners) + ' win!' -else: - winstring = ' '.join([winners[0],'wins!']) - -print("\nGAME OVER!!!\n"+winstring+"\n") -print(dcs) \ No newline at end of file +testUtility.display_game_results(players) \ No newline at end of file diff --git a/projects/lieur/dominion/testUtility.py b/projects/lieur/dominion/testUtility.py index b4d6021..73dfde0 100644 --- a/projects/lieur/dominion/testUtility.py +++ b/projects/lieur/dominion/testUtility.py @@ -1,119 +1,100 @@ # -*- coding: utf-8 -*- """ -Created on Tue Oct 13 15:42:42 2015 +Created on Saturday, January 18, 2020 -@author: tfleck +@author: lieur """ import Dominion import random from collections import defaultdict -#Get player names -player_names = ["Annie","*Ben","*Carla"] - -#number of curses and victory cards -if len(player_names)>2: - nV=12 -else: - nV=8 -nC = -10 + 10 * len(player_names) - -#Define box -box = {} -box["Woodcutter"]=[Dominion.Woodcutter()]*10 -box["Smithy"]=[Dominion.Smithy()]*10 -box["Laboratory"]=[Dominion.Laboratory()]*10 -box["Village"]=[Dominion.Village()]*10 -box["Festival"]=[Dominion.Festival()]*10 -box["Market"]=[Dominion.Market()]*10 -box["Chancellor"]=[Dominion.Chancellor()]*10 -box["Workshop"]=[Dominion.Workshop()]*10 -box["Moneylender"]=[Dominion.Moneylender()]*10 -box["Chapel"]=[Dominion.Chapel()]*10 -box["Cellar"]=[Dominion.Cellar()]*10 -box["Remodel"]=[Dominion.Remodel()]*10 -box["Adventurer"]=[Dominion.Adventurer()]*10 -box["Feast"]=[Dominion.Feast()]*10 -box["Mine"]=[Dominion.Mine()]*10 -box["Library"]=[Dominion.Library()]*10 -box["Gardens"]=[Dominion.Gardens()]*nV -box["Moat"]=[Dominion.Moat()]*10 -box["Council Room"]=[Dominion.Council_Room()]*10 -box["Witch"]=[Dominion.Witch()]*10 -box["Bureaucrat"]=[Dominion.Bureaucrat()]*10 -box["Militia"]=[Dominion.Militia()]*10 -box["Spy"]=[Dominion.Spy()]*10 -box["Thief"]=[Dominion.Thief()]*10 -box["Throne Room"]=[Dominion.Throne_Room()]*10 - -supply_order = {0:['Curse','Copper'],2:['Estate','Cellar','Chapel','Moat'], - 3:['Silver','Chancellor','Village','Woodcutter','Workshop'], - 4:['Gardens','Bureaucrat','Feast','Militia','Moneylender','Remodel','Smithy','Spy','Thief','Throne Room'], - 5:['Duchy','Market','Council Room','Festival','Laboratory','Library','Mine','Witch'], - 6:['Gold','Adventurer'],8:['Province']} - -#Pick 10 cards from box to be in the supply. -boxlist = [k for k in box] -random.shuffle(boxlist) -random10 = boxlist[:10] -supply = defaultdict(list,[(k,box[k]) for k in random10]) +def set_vc_number(player_names): + if len(player_names)>2: + nV=12 + else: + nV=8 + nC = -10 + 10 * len(player_names) + return nV, nC +#Define definebox +def define_box(nV): + box = {} + box["Woodcutter"]=[Dominion.Woodcutter()]*10 + box["Smithy"]=[Dominion.Smithy()]*10 + box["Laboratory"]=[Dominion.Laboratory()]*10 + box["Village"]=[Dominion.Village()]*10 + box["Festival"]=[Dominion.Festival()]*10 + box["Market"]=[Dominion.Market()]*10 + box["Chancellor"]=[Dominion.Chancellor()]*10 + box["Workshop"]=[Dominion.Workshop()]*10 + box["Moneylender"]=[Dominion.Moneylender()]*10 + box["Chapel"]=[Dominion.Chapel()]*10 + box["Cellar"]=[Dominion.Cellar()]*10 + box["Remodel"]=[Dominion.Remodel()]*10 + box["Adventurer"]=[Dominion.Adventurer()]*10 + box["Feast"]=[Dominion.Feast()]*10 + box["Mine"]=[Dominion.Mine()]*10 + box["Library"]=[Dominion.Library()]*10 + box["Gardens"]=[Dominion.Gardens()]*nV + box["Moat"]=[Dominion.Moat()]*10 + box["Council Room"]=[Dominion.Council_Room()]*10 + box["Witch"]=[Dominion.Witch()]*10 + box["Bureaucrat"]=[Dominion.Bureaucrat()]*10 + box["Militia"]=[Dominion.Militia()]*10 + box["Spy"]=[Dominion.Spy()]*10 + box["Thief"]=[Dominion.Thief()]*10 + box["Throne Room"]=[Dominion.Throne_Room()]*10 -#The supply always has these cards -supply["Copper"]=[Dominion.Copper()]*(60-len(player_names)*7) -supply["Silver"]=[Dominion.Silver()]*40 -supply["Gold"]=[Dominion.Gold()]*30 -supply["Estate"]=[Dominion.Estate()]*nV -supply["Duchy"]=[Dominion.Duchy()]*nV -supply["Province"]=[Dominion.Province()]*nV -supply["Curse"]=[Dominion.Curse()]*nC + supply_order = {0: ['Curse', 'Copper'], 2: ['Estate', 'Cellar', 'Chapel', 'Moat'], + 3: ['Silver', 'Chancellor', 'Village', 'Woodcutter', 'Workshop'], + 4: ['Gardens', 'Bureaucrat', 'Feast', 'Militia', 'Moneylender', 'Remodel', 'Smithy', 'Spy', 'Thief', + 'Throne Room'], + 5: ['Duchy', 'Market', 'Council Room', 'Festival', 'Laboratory', 'Library', 'Mine', 'Witch'], + 6: ['Gold', 'Adventurer'], 8: ['Province']} + return box, supply_order -#initialize the trash -trash = [] +# +def set_supply(box, player_names, nV, nC): + #Pick 10 cards from box to be in the supply. + boxlist = [k for k in box] + random.shuffle(boxlist) + random10 = boxlist[:10] + supply = defaultdict(list,[(k,box[k]) for k in random10]) + #The supply always has these cards + supply["Copper"]=[Dominion.Copper()]*(60-len(player_names)*7) + supply["Silver"]=[Dominion.Silver()]*40 + supply["Gold"]=[Dominion.Gold()]*30 + supply["Estate"]=[Dominion.Estate()]*nV + supply["Duchy"]=[Dominion.Duchy()]*nV + supply["Province"]=[Dominion.Province()]*nV + supply["Curse"]=[Dominion.Curse()]*nC + return supply -#Costruct the Player objects -players = [] -for name in player_names: - if name[0]=="*": - players.append(Dominion.ComputerPlayer(name[1:])) - elif name[0]=="^": - players.append(Dominion.TablePlayer(name[1:])) +#Define display_game_results +def display_game_results(players): + dcs = Dominion.cardsummaries(players) + vp = dcs.loc['VICTORY POINTS'] + vpmax = vp.max() + winners = [] + for i in vp.index: + if vp.loc[i] == vpmax: + winners.append(i) + if len(winners) > 1: + winstring = ' and '.join(winners) + ' win!' else: - players.append(Dominion.Player(name)) - -#Play the game -turn = 0 -while not Dominion.gameover(supply): - turn += 1 - print("\r") - for value in supply_order: - print (value) - for stack in supply_order[value]: - if stack in supply: - print (stack, len(supply[stack])) - print("\r") - for player in players: - print (player.name,player.calcpoints()) - print ("\rStart of turn " + str(turn)) - for player in players: - if not Dominion.gameover(supply): - print("\r") - player.turn(players,supply,trash) - + winstring = ' '.join([winners[0], 'wins!']) -#Final score -dcs=Dominion.cardsummaries(players) -vp=dcs.loc['VICTORY POINTS'] -vpmax=vp.max() -winners=[] -for i in vp.index: - if vp.loc[i]==vpmax: - winners.append(i) -if len(winners)>1: - winstring= ' and '.join(winners) + ' win!' -else: - winstring = ' '.join([winners[0],'wins!']) + print("\nGAME OVER!!!\n" + winstring + "\n") + print(dcs) -print("\nGAME OVER!!!\n"+winstring+"\n") -print(dcs) \ No newline at end of file +def set_players(player_names): + players = [] + for name in player_names: + if name[0] == "*": + players.append(Dominion.ComputerPlayer(name[1:])) + elif name[0] == "^": + players.append(Dominion.TablePlayer(name[1:])) + else: + players.append(Dominion.Player(name)) + return players \ No newline at end of file From 0e75e7b76ce0f1a244520034813f6da6e1d17ace Mon Sep 17 00:00:00 2001 From: lieuraymond Date: Sun, 19 Jan 2020 01:06:23 -0800 Subject: [PATCH 08/18] Refactor testDominion2 --- projects/lieur/dominion/testDominion1.py | 2 +- projects/lieur/dominion/testDominion2.py | 87 +++--------------------- 2 files changed, 11 insertions(+), 78 deletions(-) diff --git a/projects/lieur/dominion/testDominion1.py b/projects/lieur/dominion/testDominion1.py index 5b39c19..972d3db 100644 --- a/projects/lieur/dominion/testDominion1.py +++ b/projects/lieur/dominion/testDominion1.py @@ -13,7 +13,7 @@ #Get player names player_names = ["Annie","*Ben","*Carla"] -#number of curses and victory cards +#Set number of curses and victory cards nV, nC = testUtility.set_vc_number(player_names) #Define box diff --git a/projects/lieur/dominion/testDominion2.py b/projects/lieur/dominion/testDominion2.py index b4d6021..972d3db 100644 --- a/projects/lieur/dominion/testDominion2.py +++ b/projects/lieur/dominion/testDominion2.py @@ -1,86 +1,32 @@ # -*- coding: utf-8 -*- """ -Created on Tue Oct 13 15:42:42 2015 +Created on Saturday, January 18, 2020 -@author: tfleck +@author: lieur """ import Dominion +import testUtility import random from collections import defaultdict #Get player names player_names = ["Annie","*Ben","*Carla"] -#number of curses and victory cards -if len(player_names)>2: - nV=12 -else: - nV=8 -nC = -10 + 10 * len(player_names) +#Set number of curses and victory cards +nV, nC = testUtility.set_vc_number(player_names) #Define box -box = {} -box["Woodcutter"]=[Dominion.Woodcutter()]*10 -box["Smithy"]=[Dominion.Smithy()]*10 -box["Laboratory"]=[Dominion.Laboratory()]*10 -box["Village"]=[Dominion.Village()]*10 -box["Festival"]=[Dominion.Festival()]*10 -box["Market"]=[Dominion.Market()]*10 -box["Chancellor"]=[Dominion.Chancellor()]*10 -box["Workshop"]=[Dominion.Workshop()]*10 -box["Moneylender"]=[Dominion.Moneylender()]*10 -box["Chapel"]=[Dominion.Chapel()]*10 -box["Cellar"]=[Dominion.Cellar()]*10 -box["Remodel"]=[Dominion.Remodel()]*10 -box["Adventurer"]=[Dominion.Adventurer()]*10 -box["Feast"]=[Dominion.Feast()]*10 -box["Mine"]=[Dominion.Mine()]*10 -box["Library"]=[Dominion.Library()]*10 -box["Gardens"]=[Dominion.Gardens()]*nV -box["Moat"]=[Dominion.Moat()]*10 -box["Council Room"]=[Dominion.Council_Room()]*10 -box["Witch"]=[Dominion.Witch()]*10 -box["Bureaucrat"]=[Dominion.Bureaucrat()]*10 -box["Militia"]=[Dominion.Militia()]*10 -box["Spy"]=[Dominion.Spy()]*10 -box["Thief"]=[Dominion.Thief()]*10 -box["Throne Room"]=[Dominion.Throne_Room()]*10 +box, supply_order = testUtility.define_box(nV) -supply_order = {0:['Curse','Copper'],2:['Estate','Cellar','Chapel','Moat'], - 3:['Silver','Chancellor','Village','Woodcutter','Workshop'], - 4:['Gardens','Bureaucrat','Feast','Militia','Moneylender','Remodel','Smithy','Spy','Thief','Throne Room'], - 5:['Duchy','Market','Council Room','Festival','Laboratory','Library','Mine','Witch'], - 6:['Gold','Adventurer'],8:['Province']} - -#Pick 10 cards from box to be in the supply. -boxlist = [k for k in box] -random.shuffle(boxlist) -random10 = boxlist[:10] -supply = defaultdict(list,[(k,box[k]) for k in random10]) - - -#The supply always has these cards -supply["Copper"]=[Dominion.Copper()]*(60-len(player_names)*7) -supply["Silver"]=[Dominion.Silver()]*40 -supply["Gold"]=[Dominion.Gold()]*30 -supply["Estate"]=[Dominion.Estate()]*nV -supply["Duchy"]=[Dominion.Duchy()]*nV -supply["Province"]=[Dominion.Province()]*nV -supply["Curse"]=[Dominion.Curse()]*nC +#Set supply +supply = testUtility.set_supply(box, player_names, nV, nC) #initialize the trash trash = [] #Costruct the Player objects -players = [] -for name in player_names: - if name[0]=="*": - players.append(Dominion.ComputerPlayer(name[1:])) - elif name[0]=="^": - players.append(Dominion.TablePlayer(name[1:])) - else: - players.append(Dominion.Player(name)) +players = testUtility.set_players(player_names) #Play the game turn = 0 @@ -103,17 +49,4 @@ #Final score -dcs=Dominion.cardsummaries(players) -vp=dcs.loc['VICTORY POINTS'] -vpmax=vp.max() -winners=[] -for i in vp.index: - if vp.loc[i]==vpmax: - winners.append(i) -if len(winners)>1: - winstring= ' and '.join(winners) + ' win!' -else: - winstring = ' '.join([winners[0],'wins!']) - -print("\nGAME OVER!!!\n"+winstring+"\n") -print(dcs) \ No newline at end of file +testUtility.display_game_results(players) \ No newline at end of file From fc312edafe77237bd98b3690f67b1ab30d7e666c Mon Sep 17 00:00:00 2001 From: lieuraymond Date: Sun, 19 Jan 2020 19:48:50 -0800 Subject: [PATCH 09/18] Refactor --- projects/lieur/dominion/testDominion1.py | 36 ++++++++++++------------ projects/lieur/dominion/testUtility.py | 26 +++++++++-------- 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/projects/lieur/dominion/testDominion1.py b/projects/lieur/dominion/testDominion1.py index 972d3db..211ea0e 100644 --- a/projects/lieur/dominion/testDominion1.py +++ b/projects/lieur/dominion/testDominion1.py @@ -10,43 +10,43 @@ import random from collections import defaultdict -#Get player names -player_names = ["Annie","*Ben","*Carla"] +# Get player names +player_names = ["Annie", "*Ben", "*Carla"] -#Set number of curses and victory cards +# Set number of curses and victory cards nV, nC = testUtility.set_vc_number(player_names) -#Define box +# Define box box, supply_order = testUtility.define_box(nV) -#Set supply +# Set supply supply = testUtility.set_supply(box, player_names, nV, nC) -#initialize the trash +# initialize the trash trash = [] -#Costruct the Player objects +# Costruct the Player objects players = testUtility.set_players(player_names) -#Play the game -turn = 0 +# Play the game +turn = 0 while not Dominion.gameover(supply): - turn += 1 - print("\r") + turn += 1 + print("\r") for value in supply_order: - print (value) + print(value) for stack in supply_order[value]: if stack in supply: - print (stack, len(supply[stack])) + + print(stack, len(supply[stack])) print("\r") for player in players: - print (player.name,player.calcpoints()) - print ("\rStart of turn " + str(turn)) + print(player.name, player.calcpoints()) + print("\rStart of turn " + str(turn)) for player in players: if not Dominion.gameover(supply): print("\r") - player.turn(players,supply,trash) - + player.turn(players, supply, trash) -#Final score +# Final score testUtility.display_game_results(players) \ No newline at end of file diff --git a/projects/lieur/dominion/testUtility.py b/projects/lieur/dominion/testUtility.py index 73dfde0..52c0617 100644 --- a/projects/lieur/dominion/testUtility.py +++ b/projects/lieur/dominion/testUtility.py @@ -40,8 +40,8 @@ def define_box(nV): box["Moat"]=[Dominion.Moat()]*10 box["Council Room"]=[Dominion.Council_Room()]*10 box["Witch"]=[Dominion.Witch()]*10 - box["Bureaucrat"]=[Dominion.Bureaucrat()]*10 - box["Militia"]=[Dominion.Militia()]*10 + #box["Bureaucrat"]=[Dominion.Bureaucrat()]*10 + #box["Militia"]=[Dominion.Militia()]*10 box["Spy"]=[Dominion.Spy()]*10 box["Thief"]=[Dominion.Thief()]*10 box["Throne Room"]=[Dominion.Throne_Room()]*10 @@ -71,6 +71,18 @@ def set_supply(box, player_names, nV, nC): supply["Curse"]=[Dominion.Curse()]*nC return supply +#Define set_players +def set_players(player_names): + players = [] + for name in player_names: + if name[0] == "*": + players.append(Dominion.ComputerPlayer(name[1:])) + elif name[0] == "^": + players.append(Dominion.TablePlayer(name[1:])) + else: + players.append(Dominion.Player(name)) + return players + #Define display_game_results def display_game_results(players): dcs = Dominion.cardsummaries(players) @@ -88,13 +100,3 @@ def display_game_results(players): print("\nGAME OVER!!!\n" + winstring + "\n") print(dcs) -def set_players(player_names): - players = [] - for name in player_names: - if name[0] == "*": - players.append(Dominion.ComputerPlayer(name[1:])) - elif name[0] == "^": - players.append(Dominion.TablePlayer(name[1:])) - else: - players.append(Dominion.Player(name)) - return players \ No newline at end of file From 93782de29af7b9a9b032d7e9f0de5aa3a86c121a Mon Sep 17 00:00:00 2001 From: lieuraymond Date: Sun, 19 Jan 2020 20:44:50 -0800 Subject: [PATCH 10/18] Test cases added --- projects/lieur/dominion/testDominion1.py | 19 +++++++--- projects/lieur/dominion/testDominion2.py | 48 ++++++++++++++---------- 2 files changed, 41 insertions(+), 26 deletions(-) diff --git a/projects/lieur/dominion/testDominion1.py b/projects/lieur/dominion/testDominion1.py index 211ea0e..bbde1c1 100644 --- a/projects/lieur/dominion/testDominion1.py +++ b/projects/lieur/dominion/testDominion1.py @@ -1,9 +1,13 @@ # -*- coding: utf-8 -*- -""" +"""" Created on Saturday, January 18, 2020 @author: lieur -""" + +This test case sets the random supply box to null, meaning only victory cards +and money exist. This allows us to test the coin buying and victory conditions of +when the provinces are all sold out. +""""" import Dominion import testUtility @@ -16,16 +20,19 @@ # Set number of curses and victory cards nV, nC = testUtility.set_vc_number(player_names) -# Define box +# Define box and supply_order box, supply_order = testUtility.define_box(nV) -# Set supply +#Test no box +box = {} + +# Choose and set supply cards supply = testUtility.set_supply(box, player_names, nV, nC) -# initialize the trash +# Initialize the trash trash = [] -# Costruct the Player objects +# Construct the Player objects players = testUtility.set_players(player_names) # Play the game diff --git a/projects/lieur/dominion/testDominion2.py b/projects/lieur/dominion/testDominion2.py index 972d3db..6fc1a3c 100644 --- a/projects/lieur/dominion/testDominion2.py +++ b/projects/lieur/dominion/testDominion2.py @@ -1,52 +1,60 @@ # -*- coding: utf-8 -*- -""" +"""" Created on Saturday, January 18, 2020 @author: lieur -""" + +This test case sets silver and gold to 0, which in most cases prevent the computer from +buying provinces. This tests to see if the game ends when one more supply car hits 0 (since +silver and gold are already at 0 and the game ends when 3 supply deck hits 0) +""""" import Dominion import testUtility import random from collections import defaultdict -#Get player names -player_names = ["Annie","*Ben","*Carla"] +# Get player names +player_names = ["Annie", "*Ben", "*Carla"] -#Set number of curses and victory cards +# Set number of curses and victory cards nV, nC = testUtility.set_vc_number(player_names) -#Define box +# Define box and supply_order box, supply_order = testUtility.define_box(nV) -#Set supply + +# Choose and set supply cards supply = testUtility.set_supply(box, player_names, nV, nC) -#initialize the trash +# Initialize the trash trash = [] -#Costruct the Player objects +supply["Copper"]=[Dominion.Copper()]*(60-len(player_names)*7) +supply["Silver"]=[Dominion.Silver()]*0 +supply["Gold"]=[Dominion.Gold()]*0 +# Construct the Player objects players = testUtility.set_players(player_names) -#Play the game -turn = 0 +# Play the game +turn = 0 while not Dominion.gameover(supply): - turn += 1 - print("\r") + turn += 1 + print("\r") for value in supply_order: - print (value) + print(value) for stack in supply_order[value]: if stack in supply: - print (stack, len(supply[stack])) + + print(stack, len(supply[stack])) print("\r") for player in players: - print (player.name,player.calcpoints()) - print ("\rStart of turn " + str(turn)) + print(player.name, player.calcpoints()) + print("\rStart of turn " + str(turn)) for player in players: if not Dominion.gameover(supply): print("\r") - player.turn(players,supply,trash) - + player.turn(players, supply, trash) -#Final score +# Final score testUtility.display_game_results(players) \ No newline at end of file From bbac3785bd31bcd30f37c89b9ae465908e30de8a Mon Sep 17 00:00:00 2001 From: lieuraymond Date: Sun, 19 Jan 2020 20:47:01 -0800 Subject: [PATCH 11/18] Edit readme --- projects/README.md | 2 +- projects/lieur/dominion/README.md | 11 +---------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/projects/README.md b/projects/README.md index 54abfba..fe8676d 100644 --- a/projects/README.md +++ b/projects/README.md @@ -1 +1 @@ -You should create a directory with your ONID similar to instructor's ONID at this location. \ No newline at end of file +#Raymond Lieu, lieur \ No newline at end of file diff --git a/projects/lieur/dominion/README.md b/projects/lieur/dominion/README.md index 9e00834..fe8676d 100644 --- a/projects/lieur/dominion/README.md +++ b/projects/lieur/dominion/README.md @@ -1,10 +1 @@ -# Dominion -complete Dominion game in python, text-only - -Dominion is a popular deck-building game, for 2-4 players. Each card in the deck gives a player points or money, or lets a player perform a certain action when played. Each player tries to get the most points before the end of the game. As of July 2016, I have only programmed the base version. - -There are two versions of the game--one that uses a module and a main page, and one that includes all the code in one main page, useful for sharing with a friend who doesn't have python. (It can be executed in an online REPL, hence the name.) - -The list of players is hard-coded, so edit to play. Add a * at the beginning of the name for a computer player. - -The computer (currently) plays a very simple direct strategy. Its main advantage is that is has a perfect memory of every transaction, and an accurate, dispassionate calculation of when the game is likely to end. +#Raymond Lieu, lieur \ No newline at end of file From 7b26f0bba9a4b4f6d4ba7ac697721a9bbef1d727 Mon Sep 17 00:00:00 2001 From: lieuraymond Date: Sun, 19 Jan 2020 21:09:27 -0800 Subject: [PATCH 12/18] Refactored play game and added back bureaucrat and militia --- projects/lieur/dominion/testDominion1.py | 20 ++------------------ projects/lieur/dominion/testDominion2.py | 22 +++------------------- projects/lieur/dominion/testUtility.py | 23 +++++++++++++++++++++-- 3 files changed, 26 insertions(+), 39 deletions(-) diff --git a/projects/lieur/dominion/testDominion1.py b/projects/lieur/dominion/testDominion1.py index bbde1c1..f533ba8 100644 --- a/projects/lieur/dominion/testDominion1.py +++ b/projects/lieur/dominion/testDominion1.py @@ -36,24 +36,8 @@ players = testUtility.set_players(player_names) # Play the game -turn = 0 -while not Dominion.gameover(supply): - turn += 1 - print("\r") - for value in supply_order: - print(value) - for stack in supply_order[value]: - if stack in supply: - - print(stack, len(supply[stack])) - print("\r") - for player in players: - print(player.name, player.calcpoints()) - print("\rStart of turn " + str(turn)) - for player in players: - if not Dominion.gameover(supply): - print("\r") - player.turn(players, supply, trash) +testUtility.play_game(supply, supply_order, players, trash) + # Final score testUtility.display_game_results(players) \ No newline at end of file diff --git a/projects/lieur/dominion/testDominion2.py b/projects/lieur/dominion/testDominion2.py index 6fc1a3c..b7423e4 100644 --- a/projects/lieur/dominion/testDominion2.py +++ b/projects/lieur/dominion/testDominion2.py @@ -29,32 +29,16 @@ # Initialize the trash trash = [] - +# Test silver and gold = 0 supply["Copper"]=[Dominion.Copper()]*(60-len(player_names)*7) supply["Silver"]=[Dominion.Silver()]*0 supply["Gold"]=[Dominion.Gold()]*0 + # Construct the Player objects players = testUtility.set_players(player_names) # Play the game -turn = 0 -while not Dominion.gameover(supply): - turn += 1 - print("\r") - for value in supply_order: - print(value) - for stack in supply_order[value]: - if stack in supply: - - print(stack, len(supply[stack])) - print("\r") - for player in players: - print(player.name, player.calcpoints()) - print("\rStart of turn " + str(turn)) - for player in players: - if not Dominion.gameover(supply): - print("\r") - player.turn(players, supply, trash) +testUtility.play_game(supply, supply_order, players, trash) # Final score testUtility.display_game_results(players) \ No newline at end of file diff --git a/projects/lieur/dominion/testUtility.py b/projects/lieur/dominion/testUtility.py index 52c0617..9d19c58 100644 --- a/projects/lieur/dominion/testUtility.py +++ b/projects/lieur/dominion/testUtility.py @@ -40,8 +40,8 @@ def define_box(nV): box["Moat"]=[Dominion.Moat()]*10 box["Council Room"]=[Dominion.Council_Room()]*10 box["Witch"]=[Dominion.Witch()]*10 - #box["Bureaucrat"]=[Dominion.Bureaucrat()]*10 - #box["Militia"]=[Dominion.Militia()]*10 + box["Bureaucrat"]=[Dominion.Bureaucrat()]*10 + box["Militia"]=[Dominion.Militia()]*10 box["Spy"]=[Dominion.Spy()]*10 box["Thief"]=[Dominion.Thief()]*10 box["Throne Room"]=[Dominion.Throne_Room()]*10 @@ -82,6 +82,25 @@ def set_players(player_names): else: players.append(Dominion.Player(name)) return players +def play_game(supply, supply_order, players, trash): + turn = 0 + while not Dominion.gameover(supply): + turn += 1 + print("\r") + for value in supply_order: + print(value) + for stack in supply_order[value]: + if stack in supply: + + print(stack, len(supply[stack])) + print("\r") + for player in players: + print(player.name, player.calcpoints()) + print("\rStart of turn " + str(turn)) + for player in players: + if not Dominion.gameover(supply): + print("\r") + player.turn(players, supply, trash) #Define display_game_results def display_game_results(players): From 2762ff90f53ab9ef8d51790efef8221485dac324 Mon Sep 17 00:00:00 2001 From: lieuraymond Date: Sat, 1 Feb 2020 21:06:12 -0800 Subject: [PATCH 13/18] Update testUtility.py --- projects/lieur/dominion/testUtility.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/projects/lieur/dominion/testUtility.py b/projects/lieur/dominion/testUtility.py index 9d19c58..34c2e6f 100644 --- a/projects/lieur/dominion/testUtility.py +++ b/projects/lieur/dominion/testUtility.py @@ -79,9 +79,11 @@ def set_players(player_names): players.append(Dominion.ComputerPlayer(name[1:])) elif name[0] == "^": players.append(Dominion.TablePlayer(name[1:])) - else: + else players.append(Dominion.Player(name)) return players + +#define play game def play_game(supply, supply_order, players, trash): turn = 0 while not Dominion.gameover(supply): From a6e8f60a0d59740326e6bc80330689c184cdf8ad Mon Sep 17 00:00:00 2001 From: lieuraymond Date: Sun, 2 Feb 2020 19:21:02 -0800 Subject: [PATCH 14/18] Added unit tests --- .idea/.gitignore | 2 + .../inspectionProfiles/profiles_settings.xml | 6 + .idea/lieur-assignment-2.iml | 11 ++ .idea/misc.xml | 4 + .idea/modules.xml | 8 ++ .idea/vcs.xml | 6 + projects/__init__.py | 0 projects/lieur/__init__.py | 0 projects/lieur/dominion/__init__.py | 0 projects/lieur/dominion/testUtility.py | 2 +- projects/lieur/dominion/test_Dominion.py | 118 ++++++++++++++++++ projects/lieur/dominion/testunit_Dominion.py | 28 +++++ 12 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/lieur-assignment-2.iml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 projects/__init__.py create mode 100644 projects/lieur/__init__.py create mode 100644 projects/lieur/dominion/__init__.py create mode 100644 projects/lieur/dominion/test_Dominion.py create mode 100644 projects/lieur/dominion/testunit_Dominion.py diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..e7e9d11 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,2 @@ +# Default ignored files +/workspace.xml diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/lieur-assignment-2.iml b/.idea/lieur-assignment-2.iml new file mode 100644 index 0000000..ab292dd --- /dev/null +++ b/.idea/lieur-assignment-2.iml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7a84efc --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..ec4b828 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/projects/__init__.py b/projects/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/projects/lieur/__init__.py b/projects/lieur/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/projects/lieur/dominion/__init__.py b/projects/lieur/dominion/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/projects/lieur/dominion/testUtility.py b/projects/lieur/dominion/testUtility.py index 34c2e6f..3e4da46 100644 --- a/projects/lieur/dominion/testUtility.py +++ b/projects/lieur/dominion/testUtility.py @@ -79,7 +79,7 @@ def set_players(player_names): players.append(Dominion.ComputerPlayer(name[1:])) elif name[0] == "^": players.append(Dominion.TablePlayer(name[1:])) - else + else: players.append(Dominion.Player(name)) return players diff --git a/projects/lieur/dominion/test_Dominion.py b/projects/lieur/dominion/test_Dominion.py new file mode 100644 index 0000000..2de7a37 --- /dev/null +++ b/projects/lieur/dominion/test_Dominion.py @@ -0,0 +1,118 @@ +from unittest import TestCase +import Dominion +import testUtility + +class TestAction_card(TestCase): + def setup_card(self): + self.name = "Abracadabra" + self.cost = 1 + self.actions = 10 + self.cards = 3 + self.buys = 5 + self.coins = 2 + self.test_action_card = Dominion.Action_card(self.name, self.cost, self.actions, self.cards, self.buys, self.coins) + self.player = Dominion.Player("Bob") + self.player.actions = 0 + self.player.buys = 0 + self.player.purse = 0 + + def test_init(self): + self.setup_card() + self.assertEqual(self.name, self.test_action_card.name) + self.assertEqual(self.cost, self.test_action_card.cost) + self.assertEqual(self.actions, self.test_action_card.actions) + self.assertEqual(self.cards, self.test_action_card.cards) + self.assertEqual(self.buys, self.test_action_card.buys) + self.assertEqual(self.coins, self.test_action_card.coins) + + def test_use(self): + self.setup_card() + self.trash = [] + self.player.hand.append(self.test_action_card) + self.assertIn(self.test_action_card, self.player.hand) + self.assertEqual(6, len(self.player.hand)) + self.test_action_card.use(self.player, self.trash) + self.assertEqual(5, len(self.player.hand)) + self.assertNotIn(self.test_action_card, self.player.hand) + self.assertEqual(1, len(self.player.played)) + self.assertEqual(self.test_action_card.name, self.player.played[0].name) + + def test_augment(self): + self.setup_card() + self.test_action_card.augment(self.player) + self.assertEqual(self.player.actions, self.test_action_card.actions) + self.assertEqual(self.player.buys, self.test_action_card.buys) + self.assertEqual(self.player.purse, self.test_action_card.coins) + self.assertEqual(8, len(self.player.hand)) + + +class TestPlayer(TestCase): + def test_draw(self): + self.player = Dominion.Player("Bob") + self.assertEqual(5, len(self.player.hand)) + self.assertEqual(5, len(self.player.deck)) + self.assertEqual(0, len(self.player.discard)) + self.player.draw() + self.assertEqual(6, len(self.player.hand)) + self.assertEqual(4, len(self.player.deck)) + self.assertEqual(0, len(self.player.discard)) + self.player.draw(self.player.discard) + self.assertEqual(6, len(self.player.hand)) + self.assertEqual(3, len(self.player.deck)) + self.assertEqual(1, len(self.player.discard)) + self.player.deck = [] + self.player.draw() + self.assertEqual(7, len(self.player.hand)) + self.assertEqual(0, len(self.player.deck)) + self.assertEqual(0, len(self.player.discard)) + + def test_action_balance(self): + self.player = Dominion.Player("Bob") + self.test_action_card = Dominion.Action_card("test", 2, 3, 0, 0, 0) + self.test_action_card2 = Dominion.Action_card("test", 2, 0, 0, 0, 0) + self.player.hand.append(self.test_action_card) + self.assertEqual(self.player.action_balance(), 140/11) + self.player.hand.append(self.test_action_card2) + self.assertEqual(self.player.action_balance(), 70/ 12) + + + def test_cardsummary(self): + self.player = Dominion.Player("Bob") + self.testSummary = {} + self.testSummary['Copper'] = 7 + self.testSummary['Estate'] = 3 + self.testSummary['VICTORY POINTS'] = 3 + self.assertEqual(self.testSummary, self.player.cardsummary()) + self.test_hand_card = Dominion.Action_card('Hand', 2, 3, 0, 0, 0) + self.test_discard_card = Dominion.Action_card('Discard', 2, 3, 0, 0, 0) + self.test_played_card = Dominion.Action_card('Played', 2, 3, 0, 0, 0) + self.test_aside_card = Dominion.Action_card('Aside', 2, 3, 0, 0, 0) + self.test_hold_card = Dominion.Action_card('Hold', 2, 3, 0, 0, 0) + self.player.hand.append(self.test_hand_card) + self.testSummary['Hand'] = 1 + self.assertEqual(self.testSummary, self.player.cardsummary()) + self.player.hand.append(self.test_discard_card) + self.testSummary['Discard'] = 1 + self.player.played.append(self.test_played_card) + self.testSummary['Played'] = 1 + self.player.aside.append(self.test_aside_card) + self.testSummary['Aside'] = 1 + self.player.hold.append(self.test_hold_card) + self.testSummary['Hold'] = 1 + + def test_calcpoints(self): + self.player = Dominion.Player("Bob") + self.assertEqual(3, self.player.calcpoints()) + self.player.hand.append(Dominion.Estate()) + self.assertEqual(4, self.player.calcpoints()) + self.player.deck.append(Dominion.Estate()) + self.assertEqual(5, self.player.calcpoints()) + self.player.discard.append(Dominion.Estate()) + self.assertEqual(6, self.player.calcpoints()) + for i in range(7): + self.assertEqual(6 + i, self.player.calcpoints()) + self.player.hand.append(Dominion.Gardens()) + self.assertEqual(20, self.player.calcpoints()) + + + diff --git a/projects/lieur/dominion/testunit_Dominion.py b/projects/lieur/dominion/testunit_Dominion.py new file mode 100644 index 0000000..688e52f --- /dev/null +++ b/projects/lieur/dominion/testunit_Dominion.py @@ -0,0 +1,28 @@ +from unittest import TestCase +import Dominion +import testUtility + +class TestCard(TestCase): + def setUp(self): + self.player_names = ["Annie", "*Ben", "*Carla"] + self.nV, self.nC = testUtility.set_vc_number(self.player_names) + self.box, self.supply_order = testUtility.define_box(self.nV) + self.supply = testUtility.set_supply(self.box, self.player_names, self.nV, self.nC) + self.trash = [] + self.players = testUtility.set_players(self.player_names) + self.players = testUtility.set_players(self.player_names) + self.player = Dominion.Player('Bob') + def test_unit(self): + self.setUp() + cost = 1 + buypower = 5 + card = Dominion.Coin_card(self.player.name, cost, buypower) + self.assertEqual("Bob", card.name) + self.assertEqual(buypower, card.buypower) + self.assertEqual(cost, card.cost) + self.assertEqual("coin", card.category) + self.assertEqual(0, card.vpoints) + + def test_react(self): + pass + From 7d9a4bd1f16e24dc82512e781511a267f5cccb54 Mon Sep 17 00:00:00 2001 From: lieuraymond Date: Sun, 23 Feb 2020 20:58:52 -0800 Subject: [PATCH 15/18] Revert "Added unit tests" --- .idea/.gitignore | 2 - .../inspectionProfiles/profiles_settings.xml | 6 - .idea/lieur-assignment-2.iml | 11 -- .idea/misc.xml | 4 - .idea/modules.xml | 8 -- .idea/vcs.xml | 6 - projects/__init__.py | 0 projects/lieur/__init__.py | 0 projects/lieur/dominion/__init__.py | 0 projects/lieur/dominion/testUtility.py | 2 +- projects/lieur/dominion/test_Dominion.py | 118 ------------------ projects/lieur/dominion/testunit_Dominion.py | 28 ----- 12 files changed, 1 insertion(+), 184 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/inspectionProfiles/profiles_settings.xml delete mode 100644 .idea/lieur-assignment-2.iml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml delete mode 100644 projects/__init__.py delete mode 100644 projects/lieur/__init__.py delete mode 100644 projects/lieur/dominion/__init__.py delete mode 100644 projects/lieur/dominion/test_Dominion.py delete mode 100644 projects/lieur/dominion/testunit_Dominion.py diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index e7e9d11..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Default ignored files -/workspace.xml diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 105ce2d..0000000 --- a/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/lieur-assignment-2.iml b/.idea/lieur-assignment-2.iml deleted file mode 100644 index ab292dd..0000000 --- a/.idea/lieur-assignment-2.iml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 7a84efc..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index ec4b828..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/projects/__init__.py b/projects/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/projects/lieur/__init__.py b/projects/lieur/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/projects/lieur/dominion/__init__.py b/projects/lieur/dominion/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/projects/lieur/dominion/testUtility.py b/projects/lieur/dominion/testUtility.py index 3e4da46..34c2e6f 100644 --- a/projects/lieur/dominion/testUtility.py +++ b/projects/lieur/dominion/testUtility.py @@ -79,7 +79,7 @@ def set_players(player_names): players.append(Dominion.ComputerPlayer(name[1:])) elif name[0] == "^": players.append(Dominion.TablePlayer(name[1:])) - else: + else players.append(Dominion.Player(name)) return players diff --git a/projects/lieur/dominion/test_Dominion.py b/projects/lieur/dominion/test_Dominion.py deleted file mode 100644 index 2de7a37..0000000 --- a/projects/lieur/dominion/test_Dominion.py +++ /dev/null @@ -1,118 +0,0 @@ -from unittest import TestCase -import Dominion -import testUtility - -class TestAction_card(TestCase): - def setup_card(self): - self.name = "Abracadabra" - self.cost = 1 - self.actions = 10 - self.cards = 3 - self.buys = 5 - self.coins = 2 - self.test_action_card = Dominion.Action_card(self.name, self.cost, self.actions, self.cards, self.buys, self.coins) - self.player = Dominion.Player("Bob") - self.player.actions = 0 - self.player.buys = 0 - self.player.purse = 0 - - def test_init(self): - self.setup_card() - self.assertEqual(self.name, self.test_action_card.name) - self.assertEqual(self.cost, self.test_action_card.cost) - self.assertEqual(self.actions, self.test_action_card.actions) - self.assertEqual(self.cards, self.test_action_card.cards) - self.assertEqual(self.buys, self.test_action_card.buys) - self.assertEqual(self.coins, self.test_action_card.coins) - - def test_use(self): - self.setup_card() - self.trash = [] - self.player.hand.append(self.test_action_card) - self.assertIn(self.test_action_card, self.player.hand) - self.assertEqual(6, len(self.player.hand)) - self.test_action_card.use(self.player, self.trash) - self.assertEqual(5, len(self.player.hand)) - self.assertNotIn(self.test_action_card, self.player.hand) - self.assertEqual(1, len(self.player.played)) - self.assertEqual(self.test_action_card.name, self.player.played[0].name) - - def test_augment(self): - self.setup_card() - self.test_action_card.augment(self.player) - self.assertEqual(self.player.actions, self.test_action_card.actions) - self.assertEqual(self.player.buys, self.test_action_card.buys) - self.assertEqual(self.player.purse, self.test_action_card.coins) - self.assertEqual(8, len(self.player.hand)) - - -class TestPlayer(TestCase): - def test_draw(self): - self.player = Dominion.Player("Bob") - self.assertEqual(5, len(self.player.hand)) - self.assertEqual(5, len(self.player.deck)) - self.assertEqual(0, len(self.player.discard)) - self.player.draw() - self.assertEqual(6, len(self.player.hand)) - self.assertEqual(4, len(self.player.deck)) - self.assertEqual(0, len(self.player.discard)) - self.player.draw(self.player.discard) - self.assertEqual(6, len(self.player.hand)) - self.assertEqual(3, len(self.player.deck)) - self.assertEqual(1, len(self.player.discard)) - self.player.deck = [] - self.player.draw() - self.assertEqual(7, len(self.player.hand)) - self.assertEqual(0, len(self.player.deck)) - self.assertEqual(0, len(self.player.discard)) - - def test_action_balance(self): - self.player = Dominion.Player("Bob") - self.test_action_card = Dominion.Action_card("test", 2, 3, 0, 0, 0) - self.test_action_card2 = Dominion.Action_card("test", 2, 0, 0, 0, 0) - self.player.hand.append(self.test_action_card) - self.assertEqual(self.player.action_balance(), 140/11) - self.player.hand.append(self.test_action_card2) - self.assertEqual(self.player.action_balance(), 70/ 12) - - - def test_cardsummary(self): - self.player = Dominion.Player("Bob") - self.testSummary = {} - self.testSummary['Copper'] = 7 - self.testSummary['Estate'] = 3 - self.testSummary['VICTORY POINTS'] = 3 - self.assertEqual(self.testSummary, self.player.cardsummary()) - self.test_hand_card = Dominion.Action_card('Hand', 2, 3, 0, 0, 0) - self.test_discard_card = Dominion.Action_card('Discard', 2, 3, 0, 0, 0) - self.test_played_card = Dominion.Action_card('Played', 2, 3, 0, 0, 0) - self.test_aside_card = Dominion.Action_card('Aside', 2, 3, 0, 0, 0) - self.test_hold_card = Dominion.Action_card('Hold', 2, 3, 0, 0, 0) - self.player.hand.append(self.test_hand_card) - self.testSummary['Hand'] = 1 - self.assertEqual(self.testSummary, self.player.cardsummary()) - self.player.hand.append(self.test_discard_card) - self.testSummary['Discard'] = 1 - self.player.played.append(self.test_played_card) - self.testSummary['Played'] = 1 - self.player.aside.append(self.test_aside_card) - self.testSummary['Aside'] = 1 - self.player.hold.append(self.test_hold_card) - self.testSummary['Hold'] = 1 - - def test_calcpoints(self): - self.player = Dominion.Player("Bob") - self.assertEqual(3, self.player.calcpoints()) - self.player.hand.append(Dominion.Estate()) - self.assertEqual(4, self.player.calcpoints()) - self.player.deck.append(Dominion.Estate()) - self.assertEqual(5, self.player.calcpoints()) - self.player.discard.append(Dominion.Estate()) - self.assertEqual(6, self.player.calcpoints()) - for i in range(7): - self.assertEqual(6 + i, self.player.calcpoints()) - self.player.hand.append(Dominion.Gardens()) - self.assertEqual(20, self.player.calcpoints()) - - - diff --git a/projects/lieur/dominion/testunit_Dominion.py b/projects/lieur/dominion/testunit_Dominion.py deleted file mode 100644 index 688e52f..0000000 --- a/projects/lieur/dominion/testunit_Dominion.py +++ /dev/null @@ -1,28 +0,0 @@ -from unittest import TestCase -import Dominion -import testUtility - -class TestCard(TestCase): - def setUp(self): - self.player_names = ["Annie", "*Ben", "*Carla"] - self.nV, self.nC = testUtility.set_vc_number(self.player_names) - self.box, self.supply_order = testUtility.define_box(self.nV) - self.supply = testUtility.set_supply(self.box, self.player_names, self.nV, self.nC) - self.trash = [] - self.players = testUtility.set_players(self.player_names) - self.players = testUtility.set_players(self.player_names) - self.player = Dominion.Player('Bob') - def test_unit(self): - self.setUp() - cost = 1 - buypower = 5 - card = Dominion.Coin_card(self.player.name, cost, buypower) - self.assertEqual("Bob", card.name) - self.assertEqual(buypower, card.buypower) - self.assertEqual(cost, card.cost) - self.assertEqual("coin", card.category) - self.assertEqual(0, card.vpoints) - - def test_react(self): - pass - From 939c4b7764bf77cecf6be8c4fd4356996d21c8af Mon Sep 17 00:00:00 2001 From: lieuraymond Date: Sun, 23 Feb 2020 23:14:28 -0800 Subject: [PATCH 16/18] Assignment4 --- projects/lieur/Assignment4/.idea/.gitignore | 2 + .../lieur/Assignment4/.idea/Assignment4.iml | 8 ++ .../inspectionProfiles/profiles_settings.xml | 6 ++ projects/lieur/Assignment4/.idea/misc.xml | 7 ++ projects/lieur/Assignment4/.idea/modules.xml | 8 ++ projects/lieur/Assignment4/.idea/vcs.xml | 6 ++ .../lieur/Assignment4/classroom_manager.py | 55 ++++++++++++ .../Assignment4/test_classroom_manager.py | 83 +++++++++++++++++++ 8 files changed, 175 insertions(+) create mode 100644 projects/lieur/Assignment4/.idea/.gitignore create mode 100644 projects/lieur/Assignment4/.idea/Assignment4.iml create mode 100644 projects/lieur/Assignment4/.idea/inspectionProfiles/profiles_settings.xml create mode 100644 projects/lieur/Assignment4/.idea/misc.xml create mode 100644 projects/lieur/Assignment4/.idea/modules.xml create mode 100644 projects/lieur/Assignment4/.idea/vcs.xml create mode 100644 projects/lieur/Assignment4/classroom_manager.py create mode 100644 projects/lieur/Assignment4/test_classroom_manager.py diff --git a/projects/lieur/Assignment4/.idea/.gitignore b/projects/lieur/Assignment4/.idea/.gitignore new file mode 100644 index 0000000..e7e9d11 --- /dev/null +++ b/projects/lieur/Assignment4/.idea/.gitignore @@ -0,0 +1,2 @@ +# Default ignored files +/workspace.xml diff --git a/projects/lieur/Assignment4/.idea/Assignment4.iml b/projects/lieur/Assignment4/.idea/Assignment4.iml new file mode 100644 index 0000000..0b51991 --- /dev/null +++ b/projects/lieur/Assignment4/.idea/Assignment4.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/projects/lieur/Assignment4/.idea/inspectionProfiles/profiles_settings.xml b/projects/lieur/Assignment4/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/projects/lieur/Assignment4/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/projects/lieur/Assignment4/.idea/misc.xml b/projects/lieur/Assignment4/.idea/misc.xml new file mode 100644 index 0000000..a043e76 --- /dev/null +++ b/projects/lieur/Assignment4/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/projects/lieur/Assignment4/.idea/modules.xml b/projects/lieur/Assignment4/.idea/modules.xml new file mode 100644 index 0000000..112b71c --- /dev/null +++ b/projects/lieur/Assignment4/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/projects/lieur/Assignment4/.idea/vcs.xml b/projects/lieur/Assignment4/.idea/vcs.xml new file mode 100644 index 0000000..c2365ab --- /dev/null +++ b/projects/lieur/Assignment4/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/projects/lieur/Assignment4/classroom_manager.py b/projects/lieur/Assignment4/classroom_manager.py new file mode 100644 index 0000000..819549d --- /dev/null +++ b/projects/lieur/Assignment4/classroom_manager.py @@ -0,0 +1,55 @@ +# CS362 Assignment 4 +# Classroom Manager + +#Student class +class Student: + def __init__(self, id, first_name, last_name): + self.id = id + self.first_name = first_name + self.last_name = last_name + self.assignments = [] + + def get_full_name(self): + return str(self.first_name + " " + self.last_name) + + def submit_assignment(self, assignment): + self.assignments.append(assignment) + + + def get_assignments(self): + return self.assignments + + def get_assignment(self, name): + for a in self.assignments: + if a.name == name: + return a + return + + def get_average(self): + sum_grades = 0 + total_assignments = 0 + for a in self.assignments: + if a.grade != None: + sum_grades = sum_grades + a.grade + total_assignments = total_assignments + 1 + average = sum_grades / total_assignments + return average + + def remove_assignment(self, name): + for a in self.assignments: + if a.name == name: + self.assignments.remove(a) + return + +#Assignment class +class Assignment: + def __init__(self, name, max_score): + self.name = name + self.max_score = max_score + self.grade = -1 + + def assign_grade(self, grade): + self.grade = grade + if grade >= self.max_score: + self.grade = -1 + return diff --git a/projects/lieur/Assignment4/test_classroom_manager.py b/projects/lieur/Assignment4/test_classroom_manager.py new file mode 100644 index 0000000..6f7821c --- /dev/null +++ b/projects/lieur/Assignment4/test_classroom_manager.py @@ -0,0 +1,83 @@ +from unittest import TestCase +import classroom_manager + + +class TestStudent(TestCase): + def setUp(self): + self.student_id = 1 + self.first_name = 'Raymond' + self.last_name = 'Lieu' + self.rl = classroom_manager.Student(self.student_id, self.first_name, self.last_name) + self.assignment1 = classroom_manager.Assignment('assignment1', 17) + self.assignment2 = classroom_manager.Assignment('assignment2', 19) + + def test_student(self): + self.setUp() + self.assertEqual(self.rl.last_name, self.last_name) + self.assertEqual(self.rl.first_name, self.first_name) + self.assertEqual(self.rl.id, self.student_id) + + def test_get_full_name(self): + self.setUp() + self.assertEqual(self.first_name + " " + self.last_name, self.rl.get_full_name()) + + def test_submit_assignment(self): + self.setUp() + self.assertEqual([], self.rl.assignments) + self.rl.submit_assignment(self.assignment1) + self.assertEqual(self.assignment1, self.rl.assignments[0]) + self.rl.submit_assignment(self.assignment2) + self.assertEqual(self.assignment2, self.rl.assignments[1]) + + def test_get_assignments(self): + self.setUp() + self.assertEqual([], self.rl.get_assignments()) + self.rl.submit_assignment(self.assignment1) + self.rl.submit_assignment(self.assignment2) + rl_assignments = [self.assignment1, self.assignment2] + self.assertEqual(rl_assignments, self.rl.get_assignments()) + + def test_get_assignment(self): + self.setUp() + self.assertEqual(None, self.rl.get_assignment('assignment1')) + self.rl.submit_assignment(self.assignment1) + self.assertEqual(self.assignment1, self.rl.get_assignment('assignment1')) + self.assertEqual(None, self.rl.get_assignment('assignment2')) + + + def test_get_average(self): + self.setUp() + self.assertEqual([], self.rl.get_assignments()) + self.assignment1.assign_grade(14) + self.assignment2.assign_grade(16) + self.rl.submit_assignment(self.assignment1) + self.rl.submit_assignment(self.assignment2) + self.assertEqual(15, self.rl.get_average()) + + def test_remove_assignment(self): + self.setUp() + self.assertEqual(None, self.rl.get_assignment('assignment1')) + self.rl.submit_assignment(self.assignment1) + self.assertEqual(self.assignment1, self.rl.get_assignment('assignment1')) + self.rl.remove_assignment('assignment1') + self.assertEqual(None, self.rl.get_assignment('assignment1')) + +class TestAssignment(TestCase): + def setUp(self): + self.max_score = 11 + self.name = 'assignment7' + self.assignment7 = classroom_manager.Assignment(self.name, self.max_score) + + def test_assignment(self): + self.setUp() + self.assertEqual(self.assignment7.name, self.name) + self.assertEqual(self.assignment7.max_score, self.max_score) + self.assertEqual(self.assignment7.grade, -1) + + def test_assign_grade(self): + self.setUp() + self.assertEqual(self.assignment7.grade, -1) + self.assignment7.assign_grade(9) + self.assertEqual(self.assignment7.grade, 9) + self.assignment7.assign_grade(12) + self.assertEqual(-1, self.assignment7.grade) From 1af50951d57f5412805ca9ba95fb5aab1342c3f9 Mon Sep 17 00:00:00 2001 From: lieuraymond Date: Sun, 23 Feb 2020 23:41:19 -0800 Subject: [PATCH 17/18] Fixed a typo --- projects/lieur/Assignment4/classroom_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/lieur/Assignment4/classroom_manager.py b/projects/lieur/Assignment4/classroom_manager.py index 819549d..a71cd84 100644 --- a/projects/lieur/Assignment4/classroom_manager.py +++ b/projects/lieur/Assignment4/classroom_manager.py @@ -51,5 +51,5 @@ def __init__(self, name, max_score): def assign_grade(self, grade): self.grade = grade if grade >= self.max_score: - self.grade = -1 + self.grade = None return From 4b5fed8d5b62610ecc28d03d2f3ec5f5d307a6c3 Mon Sep 17 00:00:00 2001 From: lieuraymond Date: Sun, 23 Feb 2020 23:41:43 -0800 Subject: [PATCH 18/18] Fixed None instead of -1 --- projects/lieur/Assignment4/test_classroom_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/lieur/Assignment4/test_classroom_manager.py b/projects/lieur/Assignment4/test_classroom_manager.py index 6f7821c..5ddbfca 100644 --- a/projects/lieur/Assignment4/test_classroom_manager.py +++ b/projects/lieur/Assignment4/test_classroom_manager.py @@ -80,4 +80,4 @@ def test_assign_grade(self): self.assignment7.assign_grade(9) self.assertEqual(self.assignment7.grade, 9) self.assignment7.assign_grade(12) - self.assertEqual(-1, self.assignment7.grade) + self.assertEqual(None, self.assignment7.grade)