From b310cce63adb7d84ac52ec3e37749ca4804d4da6 Mon Sep 17 00:00:00 2001 From: broku13 <47550930+broku13@users.noreply.github.com> Date: Sun, 12 Jan 2020 14:46:28 -0800 Subject: [PATCH 1/7] Create empty --- projects/simhap/empty | 1 + 1 file changed, 1 insertion(+) create mode 100644 projects/simhap/empty diff --git a/projects/simhap/empty b/projects/simhap/empty new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/projects/simhap/empty @@ -0,0 +1 @@ + From 8d91d79da8dfd3e0b96e259bd18e821ccc5e892d Mon Sep 17 00:00:00 2001 From: broku13 <47550930+broku13@users.noreply.github.com> Date: Sun, 12 Jan 2020 14:50:07 -0800 Subject: [PATCH 2/7] Rename projects/roberwen/README.md to projects/simhap/README.md --- projects/{roberwen => simhap}/README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename projects/{roberwen => simhap}/README.md (100%) diff --git a/projects/roberwen/README.md b/projects/simhap/README.md similarity index 100% rename from projects/roberwen/README.md rename to projects/simhap/README.md From 9a1be8ff233b1e4a6dccc1217f322392e2834ce5 Mon Sep 17 00:00:00 2001 From: broku13 <47550930+broku13@users.noreply.github.com> Date: Sun, 12 Jan 2020 14:51:23 -0800 Subject: [PATCH 3/7] Rename projects/simhap/README.md to projects/roberwen/README.md --- projects/{simhap => roberwen}/README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename projects/{simhap => roberwen}/README.md (100%) diff --git a/projects/simhap/README.md b/projects/roberwen/README.md similarity index 100% rename from projects/simhap/README.md rename to projects/roberwen/README.md From 731b3468399e72cb4993255d24b621528b9bd6fd Mon Sep 17 00:00:00 2001 From: broku13 <47550930+broku13@users.noreply.github.com> Date: Sun, 12 Jan 2020 15:12:31 -0800 Subject: [PATCH 4/7] copied shit --- projects/simhap/README.md | 1 + projects/simhap/dominion/Dominion.py | 762 ++++++++++++++++++++ projects/simhap/dominion/README.md | 10 + projects/simhap/dominion/REPLdominion.py | 853 +++++++++++++++++++++++ projects/simhap/dominion/playDominion.py | 119 ++++ projects/simhap/empty | 1 - 6 files changed, 1745 insertions(+), 1 deletion(-) create mode 100644 projects/simhap/README.md create mode 100644 projects/simhap/dominion/Dominion.py create mode 100644 projects/simhap/dominion/README.md create mode 100644 projects/simhap/dominion/REPLdominion.py create mode 100644 projects/simhap/dominion/playDominion.py delete mode 100644 projects/simhap/empty diff --git a/projects/simhap/README.md b/projects/simhap/README.md new file mode 100644 index 0000000..264b047 --- /dev/null +++ b/projects/simhap/README.md @@ -0,0 +1 @@ +#Your onid folder should contain a readme file that contains your name and your ONID. diff --git a/projects/simhap/dominion/Dominion.py b/projects/simhap/dominion/Dominion.py new file mode 100644 index 0000000..6a0a534 --- /dev/null +++ b/projects/simhap/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/simhap/dominion/README.md b/projects/simhap/dominion/README.md new file mode 100644 index 0000000..9e00834 --- /dev/null +++ b/projects/simhap/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/simhap/dominion/REPLdominion.py b/projects/simhap/dominion/REPLdominion.py new file mode 100644 index 0000000..5499972 --- /dev/null +++ b/projects/simhap/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/simhap/dominion/playDominion.py b/projects/simhap/dominion/playDominion.py new file mode 100644 index 0000000..b4d6021 --- /dev/null +++ b/projects/simhap/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 diff --git a/projects/simhap/empty b/projects/simhap/empty deleted file mode 100644 index 8b13789..0000000 --- a/projects/simhap/empty +++ /dev/null @@ -1 +0,0 @@ - From 71243ffc379865af957fafc3f38f30dcc69030a2 Mon Sep 17 00:00:00 2001 From: broku13 <47550930+broku13@users.noreply.github.com> Date: Sun, 12 Jan 2020 15:19:27 -0800 Subject: [PATCH 5/7] Update README.md --- projects/simhap/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/simhap/README.md b/projects/simhap/README.md index 264b047..10e4762 100644 --- a/projects/simhap/README.md +++ b/projects/simhap/README.md @@ -1 +1 @@ -#Your onid folder should contain a readme file that contains your name and your ONID. +#Pranav Simha, simhap \ No newline at end of file From 07e2611331da6879f95b825a98286a0dce062bf0 Mon Sep 17 00:00:00 2001 From: broku13 <47550930+broku13@users.noreply.github.com> Date: Sun, 19 Jan 2020 16:23:39 -0800 Subject: [PATCH 6/7] Finished --- dominion/.vs/ProjectSettings.json | 3 ++ dominion/.vs/dominion/v16/.suo | Bin 0 -> 25088 bytes dominion/.vs/slnx.sqlite | Bin 0 -> 102400 bytes dominion/testDominion1.py | 85 ++++++++++++++++++++++++++++++ dominion/testDominion2.py | 85 ++++++++++++++++++++++++++++++ dominion/testUtility.py | 61 +++++++++++++++++++++ 6 files changed, 234 insertions(+) create mode 100644 dominion/.vs/ProjectSettings.json create mode 100644 dominion/.vs/dominion/v16/.suo create mode 100644 dominion/.vs/slnx.sqlite create mode 100644 dominion/testDominion1.py create mode 100644 dominion/testDominion2.py create mode 100644 dominion/testUtility.py diff --git a/dominion/.vs/ProjectSettings.json b/dominion/.vs/ProjectSettings.json new file mode 100644 index 0000000..f8b4888 --- /dev/null +++ b/dominion/.vs/ProjectSettings.json @@ -0,0 +1,3 @@ +{ + "CurrentProjectSetting": null +} \ No newline at end of file diff --git a/dominion/.vs/dominion/v16/.suo b/dominion/.vs/dominion/v16/.suo new file mode 100644 index 0000000000000000000000000000000000000000..8cc9bd4c7945edc6f3c2e5b7a9237e46af264f70 GIT binary patch literal 25088 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 WZ2N=%-`W4+a`69qn#A0$_kRFqmQ57^ literal 0 HcmV?d00001 diff --git a/dominion/.vs/slnx.sqlite b/dominion/.vs/slnx.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..d19f43c17cd5aa2072a62ea4fc60be567dd52c59 GIT binary patch literal 102400 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: + nV=12 +else: + nV=8 +nC = -10 + 10 * len(player_names) + +#Define box +box = testUtility.getBoxes(nV) + + +supply_order = testUtility.getOrders(nV) + +#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 +testUtility.getSupplies(supply, player_names, nV, nC) + +#initialize the trash +trash = [] + +#Costruct the Player objects +players = [] +for name in player_names: + if name[0]=="*": + players.append(Dominion.ComputerPlayer(name[1:])) + elif name[0]=="^": + players.append(Dominion.TablePlayer(name[1:])) + else: + players.append(Dominion.Player(name)) + +#Play the game +turn = 0 +while not Dominion.gameover(supply): + turn += 1 + print("\r") + for value in supply_order: + print (value) + for stack in supply_order[value]: + if stack in supply: + print (stack, len(supply[stack])) + print("\r") + for player in players: + print (player.name,player.calcpoints()) + print ("\rStart of turn " + str(turn)) + for player in players: + if not Dominion.gameover(supply): + print("\r") + player.turn(players,supply,trash) + + +#Final score +dcs=Dominion.cardsummaries(players) +vp=dcs.loc['VICTORY POINTS'] +vpmax=vp.max() +winners=[] +for i in vp.index: + if vp.loc[i]<=vpmax: + winners.append(i) +if len(winners)>1: + winstring= ' and '.join(winners) + ' win!' +else: + winstring = ' '.join([winners[0],'wins!']) + +print("\nGAME OVER!!!\n"+winstring+"\n") +print(dcs) \ No newline at end of file diff --git a/dominion/testDominion2.py b/dominion/testDominion2.py new file mode 100644 index 0000000..7b97d60 --- /dev/null +++ b/dominion/testDominion2.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue Oct 13 15:42:42 2015 + +@author: tfleck +""" +import testUtility +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 = testUtility.getBoxes(nV) + + +supply_order = testUtility.getOrders(nV) + +#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 +testUtility.getSupplies(supply, player_names, nV, nC) + +#initialize the trash +trash = [] + +#Costruct the Player objects +players = [] +for name in player_names: + if name[0]=="*": + players.append(Dominion.ComputerPlayer(name[1:])) + elif name[0]=="^": + players.append(Dominion.TablePlayer(name[1:])) + else: + players.append(Dominion.Player(name)) + +#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.min() +winners=[] +for i in vp.index: + if vp.loc[i]==vpmax: + winners.append(i) +if len(winners)>1: + winstring= ' and '.join(winners) + ' win!' +else: + winstring = ' '.join([winners[0],'wins!']) + +print("\nGAME OVER!!!\n"+winstring+"\n") +print(dcs) \ No newline at end of file diff --git a/dominion/testUtility.py b/dominion/testUtility.py new file mode 100644 index 0000000..3a61b7c --- /dev/null +++ b/dominion/testUtility.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue Oct 13 15:42:42 2015 + +@author: tfleck +""" + +import Dominion +import random +from collections import defaultdict + + + +def getBoxes(nV): + box = {} + box["Woodcutter"]=[Dominion.Woodcutter()]*10 + box["Smithy"]=[Dominion.Smithy()]*10 + box["Laboratory"]=[Dominion.Laboratory()]*10 + box["Village"]=[Dominion.Village()]*10 + box["Festival"]=[Dominion.Festival()]*10 + box["Market"]=[Dominion.Market()]*10 + box["Chancellor"]=[Dominion.Chancellor()]*10 + box["Workshop"]=[Dominion.Workshop()]*10 + box["Moneylender"]=[Dominion.Moneylender()]*10 + box["Chapel"]=[Dominion.Chapel()]*10 + box["Cellar"]=[Dominion.Cellar()]*10 + box["Remodel"]=[Dominion.Remodel()]*10 + box["Adventurer"]=[Dominion.Adventurer()]*10 + box["Feast"]=[Dominion.Feast()]*10 + box["Mine"]=[Dominion.Mine()]*10 + box["Library"]=[Dominion.Library()]*10 + box["Gardens"]=[Dominion.Gardens()]*nV + box["Moat"]=[Dominion.Moat()]*10 + box["Council Room"]=[Dominion.Council_Room()]*10 + box["Witch"]=[Dominion.Witch()]*10 + box["Bureaucrat"]=[Dominion.Bureaucrat()]*10 + box["Militia"]=[Dominion.Militia()]*10 + box["Spy"]=[Dominion.Spy()]*10 + box["Thief"]=[Dominion.Thief()]*10 + box["Throne Room"]=[Dominion.Throne_Room()]*10 + return box + + +def getOrders(nV): + supply_order = {0:['Curse','Copper'],2:['Estate','Cellar','Chapel','Moat'], + 3:['Silver','Chancellor','Village','Woodcutter','Workshop'], + 4:['Gardens','Bureaucrat','Feast','Militia','Moneylender','Remodel','Smithy','Spy','Thief','Throne Room'], + 5:['Duchy','Market','Council Room','Festival','Laboratory','Library','Mine','Witch'], + 6:['Gold','Adventurer'],8:['Province']} + return supply_order + + +#The supply always has these cards +def getSupplies(supply, player_names, nV, nC): + 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 From 91ac84976d267db55a5098840173b140dc843d10 Mon Sep 17 00:00:00 2001 From: broku13 <47550930+broku13@users.noreply.github.com> Date: Sat, 1 Feb 2020 20:29:12 -0800 Subject: [PATCH 7/7] Update .suo --- dominion/.vs/dominion/v16/.suo | Bin 25088 -> 27648 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/dominion/.vs/dominion/v16/.suo b/dominion/.vs/dominion/v16/.suo index 8cc9bd4c7945edc6f3c2e5b7a9237e46af264f70..96f325cb08d1d7ccc5103c4ee3ba07dd5a53c044 100644 GIT binary patch delta 756 zcmZWn&rj2E6#ss^w%c4wIxAbJJ77W#LFYCh9nL^T=tWo@)t$T<;-Myt#Z4kRNWqJG zFk|oF(a6Pk0_??`OXRK>6K?n)m>5Y^qV>HdC5SKi^u6!r^}X-+{cv}=yT`kQAr^|p zn2a_@{PBICXtHvVf0B) z%$|uOmq5f2l<^d5D2T(^F*MQ$1Cc?TMVvzv5F7S>@K^{T4=Xe8|?;Lz^{c^W<~7e zMK~{H_$W-LYoMhjVuKhNruN!XHLh|R0nH?&B^rO-`2fmpXz%`qR{Ul>l zzrbEWKUYTYVQw5A<;LKB?hQ7V_JqW#obZbRvrbS032SN5X*f%b%gvQakV*ZI@m}V) zS0`+OP)QhaM@X;w83oYa`ST&!*mkDF@ JDu}cY050}Kx8ipO z_Wff8nyj#kQ!z#3#=5ZYra_Be7al&!dt8VsG}3D+GK-`VsZ8Q{^h*J3W(mUF4U2hL zmaywj^+a*@E+~_td;1~Y~&L)a4Tu71bm|WrD zPyJ5wI{fQj57Wk{ZV+f5!DhtE6>bPB{O&}mePo}