From 8abd8994ded59a77343f2fd342f6ad60f3394b8f Mon Sep 17 00:00:00 2001 From: nraymon <49170505+nraymon@users.noreply.github.com> Date: Thu, 9 Jan 2020 14:23:14 -0800 Subject: [PATCH 1/4] Assignmet 1, onid folder Created own folder with name of my onid. copied the dominion folder and readme file from the already existing folder and modified the readme to have my name and onid information. --- projects/raymonn/README.md | 1 + projects/raymonn/dominion/Dominion.py | 762 +++++++++++++++++++ projects/raymonn/dominion/README.md | 10 + projects/raymonn/dominion/REPLdominion.py | 853 ++++++++++++++++++++++ projects/raymonn/dominion/playDominion.py | 119 +++ 5 files changed, 1745 insertions(+) create mode 100644 projects/raymonn/README.md create mode 100644 projects/raymonn/dominion/Dominion.py create mode 100644 projects/raymonn/dominion/README.md create mode 100644 projects/raymonn/dominion/REPLdominion.py create mode 100644 projects/raymonn/dominion/playDominion.py diff --git a/projects/raymonn/README.md b/projects/raymonn/README.md new file mode 100644 index 0000000..ae7325b --- /dev/null +++ b/projects/raymonn/README.md @@ -0,0 +1 @@ +#Nathan Raymon, raymonn diff --git a/projects/raymonn/dominion/Dominion.py b/projects/raymonn/dominion/Dominion.py new file mode 100644 index 0000000..6a0a534 --- /dev/null +++ b/projects/raymonn/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/raymonn/dominion/README.md b/projects/raymonn/dominion/README.md new file mode 100644 index 0000000..9e00834 --- /dev/null +++ b/projects/raymonn/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/raymonn/dominion/REPLdominion.py b/projects/raymonn/dominion/REPLdominion.py new file mode 100644 index 0000000..5499972 --- /dev/null +++ b/projects/raymonn/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/raymonn/dominion/playDominion.py b/projects/raymonn/dominion/playDominion.py new file mode 100644 index 0000000..b4d6021 --- /dev/null +++ b/projects/raymonn/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 acc8f9ef9ca5f21e929873035a42d8345b9be842 Mon Sep 17 00:00:00 2001 From: nraymon <49170505+nraymon@users.noreply.github.com> Date: Thu, 16 Jan 2020 14:04:22 -0800 Subject: [PATCH 2/4] not sure not sure --- .idea/.gitignore | 2 + .idea/CS362-W2020.iml | 8 + .../inspectionProfiles/profiles_settings.xml | 6 + .idea/misc.xml | 4 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + projects/raymonn/dominion/Dominion.py | 604 ++++++++++-------- projects/raymonn/dominion/playDominion.py | 143 ++--- 8 files changed, 446 insertions(+), 335 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/CS362-W2020.iml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml 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/CS362-W2020.iml b/.idea/CS362-W2020.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/CS362-W2020.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file 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/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7ba73c2 --- /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..182f80d --- /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/raymonn/dominion/Dominion.py b/projects/raymonn/dominion/Dominion.py index 6a0a534..1734db4 100644 --- a/projects/raymonn/dominion/Dominion.py +++ b/projects/raymonn/dominion/Dominion.py @@ -10,295 +10,352 @@ import re import pandas + class Card(): - def __init__(self,name,category,cost,buypower,vpoints): + 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): + + def react(self, player): return False + class Coin_card(Card): - def __init__(self,name,cost,buypower): - Card.__init__(self,name,"coin",cost,buypower,0) + 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) - + Coin_card.__init__(self, "Copper", 0, 1) + + class Silver(Coin_card): def __init__(self): - Coin_card.__init__(self,"Silver",3,2) - + Coin_card.__init__(self, "Silver", 3, 2) + + class Gold(Coin_card): def __init__(self): - Coin_card.__init__(self,"Gold",6,3) + 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) + 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) - + Victory_card.__init__(self, "Estate", 2, 1) + + class Duchy(Victory_card): def __init__(self): - Victory_card.__init__(self,"Duchy",5,3) - + Victory_card.__init__(self, "Duchy", 5, 3) + + class Province(Victory_card): def __init__(self): - Victory_card.__init__(self,"Province",8,6) + Victory_card.__init__(self, "Province", 8, 6) + class Gardens(Victory_card): def __init__(self): - Victory_card.__init__(self,"Gardens",4,0) + Victory_card.__init__(self, "Gardens", 4, 0) + class Curse(Card): def __init__(self): - Card.__init__(self,"Curse","curse",0,0,-1) + 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) + 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): + + 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 + + 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): + + 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) + 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) + 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) + 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) + 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) + 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) + 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): + 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) + 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") + 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: + 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") + c = getcard(trashcard, supply, player.hand, "your hand") if c: trash.append(c) player.hand.remove(c) - trashed+=1 + 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: ") + 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") + c = getcard(dis_card, supply, player.hand, "your hand") if c: player.discard.append(c) player.hand.remove(c) - discarded+=1 + 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: + 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") + c = getcard(this_card, supply, player.hand, "your hand") if c: trash.append(c) player.hand.remove(c) - player.gaincard(supply,c.cost+2) + 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): + 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: + while (player.deck or player.discard) and coins_added < 2: player.draw() if player.hand[-1].category == "coin": - coins_added +=1 + 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): + 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) + + 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): + 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"]) + 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) + 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: + 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")): + 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() + 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?") + " 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): + 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: + 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: + if player == this_player: pass else: for c in player.hand: if c.react(player): break else: - if len(supply["Curse"])>0: + 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()) + 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)): + 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: + 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"]) + " 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) + 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): + 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: + 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: ") + 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") + 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): + 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): @@ -306,20 +363,22 @@ def play(self,this_player,players,supply,trash): else: b = player.draw([]) if not b: - continue + 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"): + ", discard", ", keep"): player.discard.append(b) else: - player.deck.insert(0,b) - #check logic of this structure + 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): + 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 @@ -329,44 +388,46 @@ def play(self,this_player,players,supply,trash): else: for i in range(2): player.draw(player.hold) - print( player.name, namesinlist(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"]) + 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."): + 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.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): + 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"]) + 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.use(player, trash) c.augment(player) - c.play(player,players,supply,trash) + c.play(player, players, supply, trash) player.show() c.augment(player) - c.play(player,players,supply,trash) + c.play(player, players, supply, trash) break - + class Player(): - def __init__(self,name): + def __init__(self, name): self.name = name self.hand = [] - self.deck = [Copper()]*7 + [Estate()]*3 + self.deck = [Copper()] * 7 + [Estate()] * 3 random.shuffle(self.deck) self.played = [] self.discard = [] @@ -376,62 +437,65 @@ def __init__(self,name): self.draw() def other(self): - return self.played+self.discard+self.hold+self.aside + 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: + + 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: + # 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: + # 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): + + 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): + # 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. --> ") + str(self.actions) + " action(s). \n-Hit enter for no play. --> ") if playthis: - c = getcard(playthis,supply,self.hand,"your hand",['action']) + c = getcard(playthis, supply, self.hand, "your hand", ['action']) if c: - self.actions = self.actions - 1 - c.use(self,trash) + self.actions = self.actions - 1 + c.use(self, trash) c.augment(self) - c.play(self,players,supply,trash) + c.play(self, players, supply, trash) self.show() else: - self.actions=0 - #buy phase + self.actions = 0 + # buy phase for c in self.hand: self.purse += c.buypower - while self.buys>0: + while self.buys > 0: buy_string = "Buying power is " + str(self.purse) + ". You have " + str(self.buys) + " buy" - if self.buys>1: + if self.buys > 1: buy_string += "s" buy_string += "." - print( 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) + c = getcard(purchase, supply, upto=self.purse) if c: self.discard.append(supply[purchase].pop()) - self.buys = self.buys -1 + self.buys = self.buys - 1 self.purse = self.purse - c.cost - - #cleanup phase + + # cleanup phase self.discard = self.discard + self.played + self.hand + self.aside self.played = [] self.hand = [] @@ -439,45 +503,46 @@ def turn(self,players,supply,trash): for i in range(5): self.draw() - def gaincard(self,supply,upto): + 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) + c = getcard(gain, supply, upto=upto) if c: self.discard.append(c) supply[gain].remove(c) break - def yesnoinput(self,prompt,yesstring='',nostring=''): + + def yesnoinput(self, prompt, yesstring='', nostring=''): print(prompt + "\n1 - Yes" + yesstring + "\n0 - No" + nostring) while True: - r = input("--> ") + r = input("--> ") if r == "0": return False if r == "1": - return True - - def choose_discard(self,prompt): + 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: + if len(self.deck) > 0: print ("deck (alphabetical order):", ", ".join(sorted(namesinlist(self.deck)))) - if len(self.discard)>0: + if len(self.discard) > 0: print ("discard:", ", ".join(sorted(namesinlist(self.discard)))) - if len(self.played)>0: + if len(self.played) > 0: print ("played:", ", ".join(sorted(namesinlist(self.played)))) - if len(self.aside)>0: + 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()) + return 70 * balance / len(self.stack()) def cardsummary(self): summary = {} @@ -486,7 +551,7 @@ def cardsummary(self): summary[c.name] += 1 else: summary[c.name] = 1 - summary['VICTORY POINTS']=self.calcpoints() + summary['VICTORY POINTS'] = self.calcpoints() return summary def calcpoints(self): @@ -497,54 +562,56 @@ def calcpoints(self): tally += c.vpoints n += 1 if c.name == "Gardens": - gardens+=1 - return tally + n//10 * gardens + gardens += 1 + return tally + n // 10 * gardens + class ComputerPlayer(Player): - def __init__(self,name): - Player.__init__(self,name) + 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): + # 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 + # action phase self.index = 0 - while self.actions>0 and 'action' in catinlist(self.hand): + 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']) + 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.use(self, trash) + self.index = 0 c.augment(self) - c.play(self,players,supply,trash) + 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.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 @@ -553,38 +620,39 @@ def turn(self,players,supply,trash): self.index = 0 for c in self.hand: self.purse += c.buypower - while self.buys>0: + while self.buys > 0: purchase = self.buygaintable[self.index] if not purchase: break else: - c = self.getcard(purchase,supply,upto=self.purse) + 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.buys = self.buys - 1 self.purse = self.purse - c.cost print (self.name + " bought " + c.name) else: self.index += 1 - - #cleanup phase + + # 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): + + 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." + # 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 + # print "There is no " + name + " in " + target_name return None i = nameslist.index(name) c = target_list[i] @@ -592,126 +660,131 @@ def getcard(self,name,supply,target_list=None,target_name= "the supply anymore", catstring = categories[0] for i in categories[1:]: catstring = catstring + " or " + categories[i] - #print name + " is not a " + catstring + " card." + # print name + " is not a " + catstring + " card." return None if c.cost > upto: - #print name + " costs " + str(c.cost) + # print name + " costs " + str(c.cost) return None return c - - def choose_discard(self,prompt): - index = 0 + + def choose_discard(self, prompt): + index = 0 while True: dis_card = self.discardtable1[index] - c = self.getcard(dis_card,[dis_card],self.hand) + c = self.getcard(dis_card, [dis_card], self.hand) if c: return c.name else: - index+=1 - - def yesnoinput(self,prompt,yesstring='',nostring=''): + 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) + 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.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 + # action phase self.index = 0 - while self.actions>0 and 'action' in catinlist(self.hand): + 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']) + c = self.getcard(playthis, supply, self.hand, "your hand", ['action']) if c: - #print (self.name + " plays " + c.name) + # print (self.name + " plays " + c.name) self.actions = self.actions - 1 - c.use(self,trash) - self.index=0 + c.use(self, trash) + self.index = 0 c.augment(self) - c.play(self,players,supply,trash) + c.play(self, players, supply, trash) self.show() else: self.index += 1 else: - self.actions=0 - #buy phase - v= self.number + 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) + 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: + while self.buys > 0: purchase = ranktable.iloc[self.index] if not purchase: break else: - c = self.getcard(purchase,supply,upto=self.purse) + 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.buys = self.buys - 1 self.purse = self.purse - c.cost else: self.index += 1 - - #cleanup phase + + # 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: + if len(supply["Province"]) == 0: return True out = 0 for stack in supply: - if len(supply[stack])==0: - out+=1 - if out>=3: + if len(supply[stack]) == 0: + out += 1 + if out >= 3: return True return False + def namesinlist(cardlist): - namelist = [] + 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): + +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.") + print(name + " is not in this game.") return None if not target_list: target_list = supply[name] @@ -732,6 +805,7 @@ def getcard(name,supply,target_list=None,target_name= "the supply anymore",categ return None return c + def totalbuypower(cardlist): TBP = 0 for c in cardlist: @@ -740,23 +814,27 @@ def totalbuypower(cardlist): TBP += c.coins return TBP + def cardsummaries(players): - cardsums={} + cardsums = {} for player in players: - cardsums[player.name]=player.cardsummary() + 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) + 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): + +def countsupply(supply, form): return [len(supply[a]) for a in form] -def countcards(cards,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 + +def rankcards(form, vector): + od = OrderedDict(zip(form, vector)) + sd = OrderedDict(sorted(od.items(), key=itemgetter(1), reverse=True)) + return list(sd.keys()) diff --git a/projects/raymonn/dominion/playDominion.py b/projects/raymonn/dominion/playDominion.py index b4d6021..7d1f4cf 100644 --- a/projects/raymonn/dominion/playDominion.py +++ b/projects/raymonn/dominion/playDominion.py @@ -9,111 +9,110 @@ import random from collections import defaultdict -#Get player names -player_names = ["Annie","*Ben","*Carla"] +# Get player names +player_names = ["Annie", "*Ben", "*Carla"] -#number of curses and victory cards -if len(player_names)>2: - nV=12 +# number of curses and victory cards +if len(player_names) > 2: + nV = 12 else: - nV=8 + nV = 8 nC = -10 + 10 * len(player_names) -#Define box +# 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["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']} +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. +# 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]) +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 -#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 +# initialize the trash trash = [] -#Costruct the Player objects +# Costruct the Player objects players = [] for name in player_names: - if name[0]=="*": + if name[0] == "*": players.append(Dominion.ComputerPlayer(name[1:])) - elif name[0]=="^": + elif name[0] == "^": players.append(Dominion.TablePlayer(name[1:])) else: players.append(Dominion.Player(name)) -#Play the game -turn = 0 +# Play the game +turn = 0 while not Dominion.gameover(supply): - turn += 1 - print("\r") - for value in supply_order: + 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)) + 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 -dcs=Dominion.cardsummaries(players) -vp=dcs.loc['VICTORY POINTS'] -vpmax=vp.max() -winners=[] +# 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: + if vp.loc[i] == vpmax: winners.append(i) -if len(winners)>1: - winstring= ' and '.join(winners) + ' win!' +if len(winners) > 1: + winstring = ' and '.join(winners) + ' win!' else: - winstring = ' '.join([winners[0],'wins!']) + winstring = ' '.join([winners[0], 'wins!']) -print("\nGAME OVER!!!\n"+winstring+"\n") -print(dcs) \ No newline at end of file +print("\nGAME OVER!!!\n" + winstring + "\n") +print(dcs) From 086c5dfb6b6102b3a04e0a65f0479394f5cea78f Mon Sep 17 00:00:00 2001 From: nraymon <49170505+nraymon@users.noreply.github.com> Date: Sun, 19 Jan 2020 16:04:49 -0800 Subject: [PATCH 3/4] Assignment 2 Refactored some starter code from playDominion to testUtility and introduced some test scenarioes to testDom1 and testDom2 that broke some rules of the game, introducing bugs. --- projects/raymonn/dominion/playDominion.py | 2 +- projects/raymonn/dominion/testDominion1.py | 77 ++ projects/raymonn/dominion/testDominion2.py | 78 ++ projects/raymonn/dominion/testUtility.py | 900 +++++++++++++++++++++ 4 files changed, 1056 insertions(+), 1 deletion(-) create mode 100644 projects/raymonn/dominion/testDominion1.py create mode 100644 projects/raymonn/dominion/testDominion2.py create mode 100644 projects/raymonn/dominion/testUtility.py diff --git a/projects/raymonn/dominion/playDominion.py b/projects/raymonn/dominion/playDominion.py index 7d1f4cf..f3d5070 100644 --- a/projects/raymonn/dominion/playDominion.py +++ b/projects/raymonn/dominion/playDominion.py @@ -87,7 +87,7 @@ while not Dominion.gameover(supply): turn += 1 print("\r") - for value in supply_order:) + for value in supply_order: print (value) for stack in supply_order[value]: if stack in supply: diff --git a/projects/raymonn/dominion/testDominion1.py b/projects/raymonn/dominion/testDominion1.py new file mode 100644 index 0000000..0412e01 --- /dev/null +++ b/projects/raymonn/dominion/testDominion1.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- +""" +Created on Thur Jan 16 2019 + +@author: raymonn +""" + +import Dominion +import random +from collections import defaultdict +import testUtility + +# 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) + +box = testUtility.GetBoxes(nV) +box["Militia"] = [Dominion.Woodcutter()] * 10 + +supply_order = testUtility.Supplies() + +# 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 = testUtility.SupplySetup(supply, nV, nC, player_names) + +# initialize the trash +trash = [] + +# Costruct the Player objects +players = [] +players = testUtility.PlayerConstructor(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) + +# 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) diff --git a/projects/raymonn/dominion/testDominion2.py b/projects/raymonn/dominion/testDominion2.py new file mode 100644 index 0000000..ff1f46c --- /dev/null +++ b/projects/raymonn/dominion/testDominion2.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +""" +Created on Thur Jan 16 2019 + +@author: raymonn +""" + +import Dominion +import random +from collections import defaultdict +import testUtility + +# 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) + +box = testUtility.GetBoxes(nV) + +supply_order = testUtility.Supplies() + +# 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 = testUtility.SupplySetup(supply, nV, nC, player_names) +supply["Duchy"] = [Dominion.Estate()] * 10 + +# initialize the trash +trash = [] + +# Costruct the Player objects +players = [] +player_names.append("Chris") +players = testUtility.PlayerConstructor(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) + +# 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) diff --git a/projects/raymonn/dominion/testUtility.py b/projects/raymonn/dominion/testUtility.py new file mode 100644 index 0000000..9a57531 --- /dev/null +++ b/projects/raymonn/dominion/testUtility.py @@ -0,0 +1,900 @@ +# -*- 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 +import Dominion + +def GetBoxes(nV): + # 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 + return box + +def Supplies(): + supply = {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 supply + +def SupplySetup(supply, nV, nC, player_names): + 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 + +def PlayerConstructor(players, player_names): + 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 + +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()) From aabae12dbf12a753d94e97499460d1a14c1d4091 Mon Sep 17 00:00:00 2001 From: nraymon <49170505+nraymon@users.noreply.github.com> Date: Sun, 19 Jan 2020 16:24:40 -0800 Subject: [PATCH 4/4] Assignment 2 Refactored some starter code from playDominion to testUtility and introduced some test scenarioes to testDom1 and testDom2 that broke some rules of the game, introducing bugs. --- projects/raymonn/dominion/testDominion1.py | 4 ++++ projects/raymonn/dominion/testDominion2.py | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/projects/raymonn/dominion/testDominion1.py b/projects/raymonn/dominion/testDominion1.py index 0412e01..5210093 100644 --- a/projects/raymonn/dominion/testDominion1.py +++ b/projects/raymonn/dominion/testDominion1.py @@ -20,9 +20,12 @@ nV = 8 nC = -10 + 10 * len(player_names) +#Refactored to testUtility.GetBoxes box = testUtility.GetBoxes(nV) +#Test Scenario box["Militia"] = [Dominion.Woodcutter()] * 10 +#Refactored to testUtility.Supplies supply_order = testUtility.Supplies() # Pick 10 cards from box to be in the supply. @@ -32,6 +35,7 @@ supply = defaultdict(list, [(k, box[k]) for k in random10]) # The supply always has these cards +#Refactored to testUtility.SupplySetup supply = testUtility.SupplySetup(supply, nV, nC, player_names) # initialize the trash diff --git a/projects/raymonn/dominion/testDominion2.py b/projects/raymonn/dominion/testDominion2.py index ff1f46c..6775772 100644 --- a/projects/raymonn/dominion/testDominion2.py +++ b/projects/raymonn/dominion/testDominion2.py @@ -20,8 +20,10 @@ nV = 8 nC = -10 + 10 * len(player_names) +#Refactored to testUtility.GetBoxes box = testUtility.GetBoxes(nV) +#Refactored to testUtility.Supplies supply_order = testUtility.Supplies() # Pick 10 cards from box to be in the supply. @@ -31,7 +33,9 @@ supply = defaultdict(list, [(k, box[k]) for k in random10]) # The supply always has these cards +#Refactored to testUtility.SupplySetup supply = testUtility.SupplySetup(supply, nV, nC, player_names) +#Test Scenario supply["Duchy"] = [Dominion.Estate()] * 10 # initialize the trash @@ -39,6 +43,7 @@ # Costruct the Player objects players = [] +#Test Scenario player_names.append("Chris") players = testUtility.PlayerConstructor(players, player_names)