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)