diff --git a/projects/README.md b/projects/README.md
index 54abfba..fe8676d 100644
--- a/projects/README.md
+++ b/projects/README.md
@@ -1 +1 @@
-You should create a directory with your ONID similar to instructor's ONID at this location.
\ No newline at end of file
+#Raymond Lieu, lieur
\ No newline at end of file
diff --git a/projects/lieur/Assignment4/.idea/.gitignore b/projects/lieur/Assignment4/.idea/.gitignore
new file mode 100644
index 0000000..e7e9d11
--- /dev/null
+++ b/projects/lieur/Assignment4/.idea/.gitignore
@@ -0,0 +1,2 @@
+# Default ignored files
+/workspace.xml
diff --git a/projects/lieur/Assignment4/.idea/Assignment4.iml b/projects/lieur/Assignment4/.idea/Assignment4.iml
new file mode 100644
index 0000000..0b51991
--- /dev/null
+++ b/projects/lieur/Assignment4/.idea/Assignment4.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/lieur/Assignment4/.idea/inspectionProfiles/profiles_settings.xml b/projects/lieur/Assignment4/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/projects/lieur/Assignment4/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/lieur/Assignment4/.idea/misc.xml b/projects/lieur/Assignment4/.idea/misc.xml
new file mode 100644
index 0000000..a043e76
--- /dev/null
+++ b/projects/lieur/Assignment4/.idea/misc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/lieur/Assignment4/.idea/modules.xml b/projects/lieur/Assignment4/.idea/modules.xml
new file mode 100644
index 0000000..112b71c
--- /dev/null
+++ b/projects/lieur/Assignment4/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/lieur/Assignment4/.idea/vcs.xml b/projects/lieur/Assignment4/.idea/vcs.xml
new file mode 100644
index 0000000..c2365ab
--- /dev/null
+++ b/projects/lieur/Assignment4/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/lieur/Assignment4/classroom_manager.py b/projects/lieur/Assignment4/classroom_manager.py
new file mode 100644
index 0000000..a71cd84
--- /dev/null
+++ b/projects/lieur/Assignment4/classroom_manager.py
@@ -0,0 +1,55 @@
+# CS362 Assignment 4
+# Classroom Manager
+
+#Student class
+class Student:
+ def __init__(self, id, first_name, last_name):
+ self.id = id
+ self.first_name = first_name
+ self.last_name = last_name
+ self.assignments = []
+
+ def get_full_name(self):
+ return str(self.first_name + " " + self.last_name)
+
+ def submit_assignment(self, assignment):
+ self.assignments.append(assignment)
+
+
+ def get_assignments(self):
+ return self.assignments
+
+ def get_assignment(self, name):
+ for a in self.assignments:
+ if a.name == name:
+ return a
+ return
+
+ def get_average(self):
+ sum_grades = 0
+ total_assignments = 0
+ for a in self.assignments:
+ if a.grade != None:
+ sum_grades = sum_grades + a.grade
+ total_assignments = total_assignments + 1
+ average = sum_grades / total_assignments
+ return average
+
+ def remove_assignment(self, name):
+ for a in self.assignments:
+ if a.name == name:
+ self.assignments.remove(a)
+ return
+
+#Assignment class
+class Assignment:
+ def __init__(self, name, max_score):
+ self.name = name
+ self.max_score = max_score
+ self.grade = -1
+
+ def assign_grade(self, grade):
+ self.grade = grade
+ if grade >= self.max_score:
+ self.grade = None
+ return
diff --git a/projects/lieur/Assignment4/test_classroom_manager.py b/projects/lieur/Assignment4/test_classroom_manager.py
new file mode 100644
index 0000000..5ddbfca
--- /dev/null
+++ b/projects/lieur/Assignment4/test_classroom_manager.py
@@ -0,0 +1,83 @@
+from unittest import TestCase
+import classroom_manager
+
+
+class TestStudent(TestCase):
+ def setUp(self):
+ self.student_id = 1
+ self.first_name = 'Raymond'
+ self.last_name = 'Lieu'
+ self.rl = classroom_manager.Student(self.student_id, self.first_name, self.last_name)
+ self.assignment1 = classroom_manager.Assignment('assignment1', 17)
+ self.assignment2 = classroom_manager.Assignment('assignment2', 19)
+
+ def test_student(self):
+ self.setUp()
+ self.assertEqual(self.rl.last_name, self.last_name)
+ self.assertEqual(self.rl.first_name, self.first_name)
+ self.assertEqual(self.rl.id, self.student_id)
+
+ def test_get_full_name(self):
+ self.setUp()
+ self.assertEqual(self.first_name + " " + self.last_name, self.rl.get_full_name())
+
+ def test_submit_assignment(self):
+ self.setUp()
+ self.assertEqual([], self.rl.assignments)
+ self.rl.submit_assignment(self.assignment1)
+ self.assertEqual(self.assignment1, self.rl.assignments[0])
+ self.rl.submit_assignment(self.assignment2)
+ self.assertEqual(self.assignment2, self.rl.assignments[1])
+
+ def test_get_assignments(self):
+ self.setUp()
+ self.assertEqual([], self.rl.get_assignments())
+ self.rl.submit_assignment(self.assignment1)
+ self.rl.submit_assignment(self.assignment2)
+ rl_assignments = [self.assignment1, self.assignment2]
+ self.assertEqual(rl_assignments, self.rl.get_assignments())
+
+ def test_get_assignment(self):
+ self.setUp()
+ self.assertEqual(None, self.rl.get_assignment('assignment1'))
+ self.rl.submit_assignment(self.assignment1)
+ self.assertEqual(self.assignment1, self.rl.get_assignment('assignment1'))
+ self.assertEqual(None, self.rl.get_assignment('assignment2'))
+
+
+ def test_get_average(self):
+ self.setUp()
+ self.assertEqual([], self.rl.get_assignments())
+ self.assignment1.assign_grade(14)
+ self.assignment2.assign_grade(16)
+ self.rl.submit_assignment(self.assignment1)
+ self.rl.submit_assignment(self.assignment2)
+ self.assertEqual(15, self.rl.get_average())
+
+ def test_remove_assignment(self):
+ self.setUp()
+ self.assertEqual(None, self.rl.get_assignment('assignment1'))
+ self.rl.submit_assignment(self.assignment1)
+ self.assertEqual(self.assignment1, self.rl.get_assignment('assignment1'))
+ self.rl.remove_assignment('assignment1')
+ self.assertEqual(None, self.rl.get_assignment('assignment1'))
+
+class TestAssignment(TestCase):
+ def setUp(self):
+ self.max_score = 11
+ self.name = 'assignment7'
+ self.assignment7 = classroom_manager.Assignment(self.name, self.max_score)
+
+ def test_assignment(self):
+ self.setUp()
+ self.assertEqual(self.assignment7.name, self.name)
+ self.assertEqual(self.assignment7.max_score, self.max_score)
+ self.assertEqual(self.assignment7.grade, -1)
+
+ def test_assign_grade(self):
+ self.setUp()
+ self.assertEqual(self.assignment7.grade, -1)
+ self.assignment7.assign_grade(9)
+ self.assertEqual(self.assignment7.grade, 9)
+ self.assignment7.assign_grade(12)
+ self.assertEqual(None, self.assignment7.grade)
diff --git a/projects/lieur/README.md b/projects/lieur/README.md
new file mode 100644
index 0000000..fe8676d
--- /dev/null
+++ b/projects/lieur/README.md
@@ -0,0 +1 @@
+#Raymond Lieu, lieur
\ No newline at end of file
diff --git a/projects/lieur/dominion/Dominion.py b/projects/lieur/dominion/Dominion.py
new file mode 100644
index 0000000..6a0a534
--- /dev/null
+++ b/projects/lieur/dominion/Dominion.py
@@ -0,0 +1,762 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Tue Oct 13 15:26:55 2015
+
+@author: tfleck
+"""
+import random
+from collections import Counter, OrderedDict
+from operator import itemgetter
+import re
+import pandas
+
+class Card():
+ def __init__(self,name,category,cost,buypower,vpoints):
+ self.name = name
+ self.category = category
+ self.cost = cost
+ self.buypower = buypower
+ self.vpoints = vpoints
+ def react(self,player):
+ return False
+
+class Coin_card(Card):
+ def __init__(self,name,cost,buypower):
+ Card.__init__(self,name,"coin",cost,buypower,0)
+
+class Copper(Coin_card):
+ def __init__(self):
+ Coin_card.__init__(self,"Copper",0,1)
+
+class Silver(Coin_card):
+ def __init__(self):
+ Coin_card.__init__(self,"Silver",3,2)
+
+class Gold(Coin_card):
+ def __init__(self):
+ Coin_card.__init__(self,"Gold",6,3)
+
+class Victory_card(Card):
+ def __init__(self,name,cost,vpoints):
+ Card.__init__(self,name,"victory",cost,0,vpoints)
+
+class Estate(Victory_card):
+ def __init__(self):
+ Victory_card.__init__(self,"Estate",2,1)
+
+class Duchy(Victory_card):
+ def __init__(self):
+ Victory_card.__init__(self,"Duchy",5,3)
+
+class Province(Victory_card):
+ def __init__(self):
+ Victory_card.__init__(self,"Province",8,6)
+
+class Gardens(Victory_card):
+ def __init__(self):
+ Victory_card.__init__(self,"Gardens",4,0)
+
+class Curse(Card):
+ def __init__(self):
+ Card.__init__(self,"Curse","curse",0,0,-1)
+
+class Action_card(Card):
+ def __init__(self,name,cost,actions,cards,buys,coins):
+ Card.__init__(self,name,"action",cost,0,0)
+ self.actions = actions
+ self.cards = cards
+ self.buys = buys
+ self.coins = coins
+ def use(self,player,trash):
+ player.played.append(self)
+ player.hand.remove(self)
+ def augment(self,player):
+ player.actions+=self.actions
+ player.buys+=self.buys
+ player.purse+=self.coins
+ for i in range(self.cards):
+ player.draw()
+ def play(self,player,players,supply,trash):
+ pass
+
+class Woodcutter(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Woodcutter",3,0,0,1,2)
+
+class Smithy(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Smithy",4,0,3,0,0)
+
+class Laboratory(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Laboratory",5,1,2,0,0)
+
+class Village(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Village",3,2,1,0,0)
+
+class Festival(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Festival",5,2,0,1,2)
+
+class Market(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Market",5,1,1,1,1)
+
+class Chancellor(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Chancellor",3,0,0,0,2)
+ def play(self,player,players,supply,trash):
+ if player.yesnoinput('Would you like to discard your entire deck?'):
+ player.discard = player.discard + player.deck
+ player.deck = []
+
+class Workshop(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Workshop",3,0,0,0,0)
+ def play(self,player,players,supply,trash):
+ player.gaincard(supply,4)
+
+class Moneylender(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Moneylender",4,0,0,0,0)
+ def play(self,player,players,supply,trash):
+ c = getcard("Copper",supply,player.hand,"your hand")
+ if c:
+ trash.append(c)
+ player.hand.remove(c)
+ player.purse += 3
+
+class Chapel(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Chapel",2,0,0,0,0)
+ def play(self,player,players,supply,trash):
+ trashed=0
+ while trashed<4 and len(player.hand)>0:
+ trashcard = input("Choose a card from your hand to trash: ")
+ if not trashcard:
+ break
+ c = getcard(trashcard,supply,player.hand,"your hand")
+ if c:
+ trash.append(c)
+ player.hand.remove(c)
+ trashed+=1
+
+class Cellar(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Cellar",2,1,0,0,0)
+ def play(self,player,players,supply,trash):
+ discarded=0
+ while len(player.hand)>0:
+ dis_card=input("Choose a card from your hand to discard: ")
+ if not dis_card:
+ break
+ c = getcard(dis_card,supply,player.hand,"your hand")
+ if c:
+ player.discard.append(c)
+ player.hand.remove(c)
+ discarded+=1
+ for j in range(discarded):
+ player.draw()
+
+class Remodel(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Remodel",4,0,0,0,0)
+ def play(self,player,players,supply,trash):
+ while len(player.hand)>0:
+ this_card = input("Choose a card from your hand to remodel: ")
+ c = getcard(this_card,supply,player.hand,"your hand")
+ if c:
+ trash.append(c)
+ player.hand.remove(c)
+ player.gaincard(supply,c.cost+2)
+ break
+
+class Adventurer(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Adventurer",6,0,0,0,0)
+ def play(self,player,players,supply,trash):
+ coins_added = 0
+ while (player.deck or player.discard) and coins_added <2:
+ player.draw()
+ if player.hand[-1].category == "coin":
+ coins_added +=1
+ else:
+ player.aside.append(player.hand.pop())
+
+class Feast(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Feast",4,0,0,0,0)
+ def use(self,player,trash):
+ trash.append(self)
+ player.hand.remove(self)
+ def play(self,player,players,supply,trash):
+ player.gaincard(supply,5)
+
+class Mine(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Mine",5,0,0,0,0)
+ def play(self,player,players,supply,trash):
+ while "coin" in catinlist(player.hand):
+ this_card = input("Choose a coin from your hand to upgrade: ")
+ c = getcard(this_card,supply,player.hand,"your hand",["coin"])
+ if c:
+ trash.append(c)
+ player.hand.remove(c)
+ while c.cost>2 or len(supply["Copper"])>0 or len(supply["Silver"])>0:
+ pick = input("Choose a coin to gain. Any coin up to " + str(c.cost+3)+": ")
+ g = getcard(pick,supply,categories=["coin"],upto=c.cost+3)
+ if g:
+ player.hand.append(g)
+ supply[pick].remove(g)
+ break
+ break
+
+class Library(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Library",5,0,0,0,0)
+ def play(self,player,players,supply,trash):
+ while (player.deck or player.discard) and len(player.hand) <7:
+ player.draw(player.hold)
+ if (player.hold[-1].category == "action" and not player.yesnoinput("You drew " + player.hold[-1].name + ". Would you like to keep it?",", add to my hand", ", set it aside")):
+ player.aside.append(player.hold.pop())
+ else:
+ player.hand.append(player.hold.pop())
+
+class Moat(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Moat",2,0,2,0,0)
+ def react(self,player):
+ player.show()
+ return player.yesnoinput(player.name + ", you have a " + self.name +
+ " in your hand. Do you want to block the attack?")
+
+class Council_Room(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Council Room",5,0,3,1,0)
+ def play(self,this_player,players,supply,trash):
+ for player in players:
+ player.draw()
+
+class Witch(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Witch",5,0,2,0,0)
+ def play(self,this_player,players,supply,trash):
+ if len(supply["Curse"])>0:
+ for player in players:
+ if player==this_player:
+ pass
+ else:
+ for c in player.hand:
+ if c.react(player):
+ break
+ else:
+ if len(supply["Curse"])>0:
+ player.discard.append(supply["Curse"].pop())
+
+class Bureaucrat(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Bureaucrat",4,0,0,0,0)
+ def play(self,this_player,players,supply,trash):
+ if len(supply["Silver"])>0:
+ this_player.deck.insert(0,supply["Silver"].pop())
+ for player in players:
+ if (not player==this_player) and ("victory" in catinlist(player.hand)):
+ for c in player.hand:
+ if c.react(player):
+ break
+ else:
+ player.show()
+ while True:
+ putback = player.choose_discard(player.name + ", which victory card" +
+ " do you want to put on top of your deck?\n--> ")
+ c = getcard(putback,supply,player.hand,"your hand",["victory"])
+ if c:
+ player.hand.remove(c)
+ player.deck.insert(0,c)
+ break
+
+class Militia(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Militia",4,0,0,0,2)
+ def play(self,this_player,players,supply,trash):
+ for player in players:
+ if (not player==this_player) and len(player.hand)>3:
+ for c in player.hand:
+ if c.react(player):
+ break
+ else:
+ player.show()
+ while len(player.hand)>3:
+ dis_card=player.choose_discard(player.name + ", choose a card from your hand to discard: ")
+ if dis_card:
+ c = getcard(dis_card,supply,player.hand,"your hand")
+ if c:
+ player.hand.remove(c)
+ player.discard.append(c)
+
+class Spy(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Spy",4,1,1,0,0)
+ def play(self,this_player,players,supply,trash):
+ for player in players:
+ for c in player.hand:
+ if c.react(player):
+ break
+ else:
+ b = player.draw([])
+ if not b:
+ continue
+ else:
+ print("The first card in the deck of " + player.name + " is " + b.name)
+ if this_player.yesnoinput(this_player.name + ", do you want " + player.name + " to discard this?",
+ ", discard",", keep"):
+ player.discard.append(b)
+ else:
+ player.deck.insert(0,b)
+ #check logic of this structure
+
+class Thief(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Thief",4,0,0,0,0)
+ def play(self,this_player,players,supply,trash):
+ for player in players:
+ if player == this_player:
+ continue
+ for c in player.hand:
+ if c.react(player):
+ break
+ else:
+ for i in range(2):
+ player.draw(player.hold)
+ print( player.name, namesinlist(player.hold))
+ if "coin" in catinlist(player.hold):
+ while True:
+ burn = input("Which card would you like " + player.name + " to trash?\n-->")
+ c = getcard(burn,supply,player.hold," the top 2 cards",["coin"])
+ if c:
+ player.hold.remove(c)
+ break
+ if this_player.yesnoinput("Do you want to steal it?",", it's mine!",", leave it in the trash."):
+ this_player.discard.append(c)
+ else:
+ trash.append(c)
+ player.discard=player.discard+player.hold
+ player.hold = []
+
+class Throne_Room(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Throne Room",4,0,0,0,0)
+ def play(self,player,players,supply,trash):
+ if "action" in catinlist(player.hand):
+ while True:
+ double = input("What card would you like to double?\n--> ")
+ c = getcard(double,supply,player.hand," your hand",["action"])
+ if c:
+ c.use(player,trash)
+ c.augment(player)
+ c.play(player,players,supply,trash)
+ player.show()
+ c.augment(player)
+ c.play(player,players,supply,trash)
+ break
+
+
+class Player():
+ def __init__(self,name):
+ self.name = name
+ self.hand = []
+ self.deck = [Copper()]*7 + [Estate()]*3
+ random.shuffle(self.deck)
+ self.played = []
+ self.discard = []
+ self.aside = []
+ self.hold = []
+ for i in range(5):
+ self.draw()
+
+ def other(self):
+ return self.played+self.discard+self.hold+self.aside
+ def stack(self):
+ return (self.deck + self.hand + self.played + self.discard + self.aside + self.hold)
+ def draw(self,dest=None):
+ #defualt destination is player's hand
+ if dest==None:
+ dest = self.hand
+ #Replenish deck if necessary.
+ if len(self.deck)==0:
+ self.deck = self.discard
+ self.discard = []
+ random.shuffle(self.deck)
+ #If deck has cards, add card to destination list
+ if len(self.deck)>0:
+ c = self.deck.pop(0)
+ dest.append(c)
+ return c
+ def turn(self,players,supply,trash):
+ self.show()
+ self.actions = 1
+ self.buys = 1
+ self.purse = 0
+ #action phase
+ while self.actions>0 and 'action' in catinlist(self.hand):
+ playthis = input("Which card would you like to play? You have " +
+ str(self.actions) + " action(s). \n-Hit enter for no play. --> ")
+ if playthis:
+ c = getcard(playthis,supply,self.hand,"your hand",['action'])
+ if c:
+ self.actions = self.actions - 1
+ c.use(self,trash)
+ c.augment(self)
+ c.play(self,players,supply,trash)
+ self.show()
+ else:
+ self.actions=0
+ #buy phase
+ for c in self.hand:
+ self.purse += c.buypower
+ while self.buys>0:
+ buy_string = "Buying power is " + str(self.purse) + ". You have " + str(self.buys) + " buy"
+ if self.buys>1:
+ buy_string += "s"
+ buy_string += "."
+ print( buy_string)
+ purchase = input("What would you like to purchase? -Hit enter for no purchase.-\n--> ")
+ if not purchase:
+ break
+ else:
+ c = getcard(purchase,supply,upto=self.purse)
+ if c:
+ self.discard.append(supply[purchase].pop())
+ self.buys = self.buys -1
+ self.purse = self.purse - c.cost
+
+ #cleanup phase
+ self.discard = self.discard + self.played + self.hand + self.aside
+ self.played = []
+ self.hand = []
+ self.aside = []
+ for i in range(5):
+ self.draw()
+
+ def gaincard(self,supply,upto):
+ while True:
+ gain = input("What would you like to get? Any card up to " + str(upto) + "\n--> ")
+ c = getcard(gain,supply,upto=upto)
+ if c:
+ self.discard.append(c)
+ supply[gain].remove(c)
+ break
+ def yesnoinput(self,prompt,yesstring='',nostring=''):
+ print(prompt + "\n1 - Yes" + yesstring + "\n0 - No" + nostring)
+ while True:
+ r = input("--> ")
+ if r == "0":
+ return False
+ if r == "1":
+ return True
+
+ def choose_discard(self,prompt):
+ return input(prompt)
+
+ def show(self):
+ print (self.name)
+ print ("hand:", ", ".join(sorted(namesinlist(self.hand))))
+ if len(self.deck)>0:
+ print ("deck (alphabetical order):", ", ".join(sorted(namesinlist(self.deck))))
+ if len(self.discard)>0:
+ print ("discard:", ", ".join(sorted(namesinlist(self.discard))))
+ if len(self.played)>0:
+ print ("played:", ", ".join(sorted(namesinlist(self.played))))
+ if len(self.aside)>0:
+ print ("aside:", ", ".join(sorted(namesinlist(self.aside))))
+ print ("\r")
+
+ def action_balance(self):
+ balance = 0
+ for c in self.stack():
+ if c.category == "action":
+ balance = balance - 1 + c.actions
+ return 70*balance / len(self.stack())
+
+ def cardsummary(self):
+ summary = {}
+ for c in self.stack():
+ if c.name in summary:
+ summary[c.name] += 1
+ else:
+ summary[c.name] = 1
+ summary['VICTORY POINTS']=self.calcpoints()
+ return summary
+
+ def calcpoints(self):
+ tally = 0
+ gardens = 0
+ n = 0
+ for c in self.stack():
+ tally += c.vpoints
+ n += 1
+ if c.name == "Gardens":
+ gardens+=1
+ return tally + n//10 * gardens
+
+class ComputerPlayer(Player):
+ def __init__(self,name):
+ Player.__init__(self,name)
+ self.index = 0
+ self.buygaintable = []
+ #beginning and middle of game
+ self.buygaintable1 = ["Province","Gold","Laboratory","Festival","Witch",
+ "Council Room","Market","Militia","Adventurer","Smithy","Bureaucrat","Silver","Moat",""]
+ #end of game
+ self.buygaintable2 = ["Province","Gardens","Duchy","Estate","Gold","Silver",""]
+ #beginning and middle of the game, too many action cards
+ self.buygaintable3 = ["Province","Gold","Festival","Laboratory","Market","Village",
+ "Silver",""]
+ self.playtable1 = ["Village","Festival","Market","Laboratory","Witch",
+ "Council Room","Militia","Adventurer","Smithy","Bureaucrat","Moat",""]
+ self.discardtable1 = ["Gardens","Duchy","Province","Estate","Curse","Copper",
+ "Village","Bureaucrat","Silver","Militia","Smithy","Council Room","Witch",
+ "Festival","Market","Adventurer","Laboratory","Gold","Moat"]
+
+ def turn(self,players,supply,trash):
+ self.show()
+ self.actions = 1
+ self.buys = 1
+ self.purse = 0
+ #action phase
+ self.index = 0
+ while self.actions>0 and 'action' in catinlist(self.hand):
+ playthis = self.playtable1[self.index]
+ if playthis:
+ c = self.getcard(playthis,supply,self.hand,"your hand",['action'])
+ if c:
+ print (self.name + " plays " + c.name)
+ self.actions = self.actions - 1
+ c.use(self,trash)
+ self.index=0
+ c.augment(self)
+ c.play(self,players,supply,trash)
+ self.show()
+ else:
+ self.index += 1
+ else:
+ self.actions=0
+ #buy phase
+ if len(supply["Province"])>len(players)+totalbuypower(self.deck)/8:
+ if self.action_balance()<-10:
+ self.buygaintable = self.buygaintable3
+ else:
+ self.buygaintable = self.buygaintable1
+ else:
+ self.buygaintable = self.buygaintable2
+ self.index = 0
+ for c in self.hand:
+ self.purse += c.buypower
+ while self.buys>0:
+ purchase = self.buygaintable[self.index]
+ if not purchase:
+ break
+ else:
+ c = self.getcard(purchase,supply,upto=self.purse)
+ if c:
+ self.discard.append(supply[purchase].pop())
+ self.index = 0
+ self.buys = self.buys -1
+ self.purse = self.purse - c.cost
+ print (self.name + " bought " + c.name)
+ else:
+ self.index += 1
+
+ #cleanup phase
+ self.discard = self.discard + self.played + self.hand + self.aside
+ self.played = []
+ self.hand = []
+ self.aside = []
+ for i in range(5):
+ self.draw()
+
+ def getcard(self,name,supply,target_list=None,target_name= "the supply anymore",categories=['action','coin','curse','victory'],upto=100):
+ if not name in supply:
+ #print name + " is not in this game."
+ return None
+ if not target_list:
+ target_list = supply[name]
+ nameslist = namesinlist(target_list)
+ if not name in nameslist:
+ #print "There is no " + name + " in " + target_name
+ return None
+ i = nameslist.index(name)
+ c = target_list[i]
+ if c.category not in categories:
+ catstring = categories[0]
+ for i in categories[1:]:
+ catstring = catstring + " or " + categories[i]
+ #print name + " is not a " + catstring + " card."
+ return None
+ if c.cost > upto:
+ #print name + " costs " + str(c.cost)
+ return None
+ return c
+
+ def choose_discard(self,prompt):
+ index = 0
+ while True:
+ dis_card = self.discardtable1[index]
+ c = self.getcard(dis_card,[dis_card],self.hand)
+ if c:
+ return c.name
+ else:
+ index+=1
+
+ def yesnoinput(self,prompt,yesstring='',nostring=''):
+ return True
+
+ def show(self):
+ pass
+
+class TablePlayer(ComputerPlayer):
+ def __init__(self,name):
+ ComputerPlayer.__init__(self,name)
+ self.index=0
+ self.buygaintable=[]
+ q=re.match(r'([a-zA-Z]+)(\d+)',name)
+ if q:
+ self.number = q.group(2)
+ else:
+ print(name)
+ self.playtable1 = ["Village","Festival","Market","Laboratory","Witch",
+ "Council Room","Militia","Adventurer","Smithy","Bureaucrat","Moat",""]
+ self.discardtable1 = ["Gardens","Duchy","Province","Estate","Curse","Copper",
+ "Village","Bureaucrat","Silver","Militia","Smithy","Council Room","Witch",
+ "Festival","Market","Adventurer","Laboratory","Gold","Moat"]
+
+ def turn(self,players,supply,trash):
+ self.show()
+ self.actions = 1
+ self.buys = 1
+ self.purse = 0
+ #action phase
+ self.index = 0
+ while self.actions>0 and 'action' in catinlist(self.hand):
+ playthis = self.playtable1[self.index]
+ if playthis:
+ c = self.getcard(playthis,supply,self.hand,"your hand",['action'])
+ if c:
+ #print (self.name + " plays " + c.name)
+ self.actions = self.actions - 1
+ c.use(self,trash)
+ self.index=0
+ c.augment(self)
+ c.play(self,players,supply,trash)
+ self.show()
+ else:
+ self.index += 1
+ else:
+ self.actions=0
+ #buy phase
+ v= self.number
+ csvstring = r"Dominionbuy" + str(v) + ".csv"
+ buydf=pandas.read_csv(csvstring,na_filter=False)
+ sortedbuydf=buydf.sort_values("Buyvalues",ascending=False)
+ ranktable = sortedbuydf.Cardname
+ self.index = 0
+ for c in self.hand:
+ self.purse += c.buypower
+ while self.buys>0:
+ purchase = ranktable.iloc[self.index]
+ if not purchase:
+ break
+ else:
+ c = self.getcard(purchase,supply,upto=self.purse)
+ if c:
+ self.discard.append(supply[purchase].pop())
+ self.index = 0
+ self.buys = self.buys -1
+ self.purse = self.purse - c.cost
+ else:
+ self.index += 1
+
+ #cleanup phase
+ self.discard = self.discard + self.played + self.hand + self.aside
+ self.played = []
+ self.hand = []
+ self.aside = []
+ for i in range(5):
+ self.draw()
+
+
+def gameover(supply):
+ if len(supply["Province"])==0:
+ return True
+ out = 0
+ for stack in supply:
+ if len(supply[stack])==0:
+ out+=1
+ if out>=3:
+ return True
+ return False
+
+def namesinlist(cardlist):
+ namelist = []
+ for c in cardlist:
+ namelist.append(c.name)
+ return namelist
+
+def catinlist(cardlist):
+ catlist = []
+ for c in cardlist:
+ catlist.append(c.category)
+ return catlist
+
+def getcard(name,supply,target_list=None,target_name= "the supply anymore",categories=['action','coin','curse','victory'],upto=100):
+ if not name in supply:
+ print( name + " is not in this game.")
+ return None
+ if not target_list:
+ target_list = supply[name]
+ nameslist = namesinlist(target_list)
+ if not name in nameslist:
+ print ("There is no " + name + " in " + target_name)
+ return None
+ i = nameslist.index(name)
+ c = target_list[i]
+ if c.category not in categories:
+ catstring = categories[0]
+ for i in categories[1:]:
+ catstring = catstring + " or " + categories[i]
+ print (name + " is not a " + catstring + " card.")
+ return None
+ if c.cost > upto:
+ print (name + " costs " + str(c.cost))
+ return None
+ return c
+
+def totalbuypower(cardlist):
+ TBP = 0
+ for c in cardlist:
+ TBP += c.buypower
+ if c.category == "action":
+ TBP += c.coins
+ return TBP
+
+def cardsummaries(players):
+ cardsums={}
+ for player in players:
+ cardsums[player.name]=player.cardsummary()
+ cardsdf = pandas.DataFrame(cardsums).fillna(0).sort_index()
+ vp=cardsdf.loc[['VICTORY POINTS']]
+ cardsdf.drop(['VICTORY POINTS'],inplace=True)
+ return pandas.concat([cardsdf,vp],axis=0).fillna(0).astype(int)
+
+def countsupply(supply,form):
+ return [len(supply[a]) for a in form]
+
+def countcards(cards,form):
+ dcount = Counter(namesinlist(cards))
+ return [dcount[a] for a in form]
+
+def rankcards(form,vector):
+ od = OrderedDict(zip(form,vector))
+ sd = OrderedDict(sorted(od.items(),key = itemgetter(1),reverse=True))
+ return list(sd.keys())
\ No newline at end of file
diff --git a/projects/lieur/dominion/README.md b/projects/lieur/dominion/README.md
new file mode 100644
index 0000000..fe8676d
--- /dev/null
+++ b/projects/lieur/dominion/README.md
@@ -0,0 +1 @@
+#Raymond Lieu, lieur
\ No newline at end of file
diff --git a/projects/lieur/dominion/REPLdominion.py b/projects/lieur/dominion/REPLdominion.py
new file mode 100644
index 0000000..5499972
--- /dev/null
+++ b/projects/lieur/dominion/REPLdominion.py
@@ -0,0 +1,853 @@
+import random
+from collections import Counter, OrderedDict
+from operator import itemgetter
+import re
+import pandas
+
+class Card():
+ def __init__(self,name,category,cost,buypower,vpoints):
+ self.name = name
+ self.category = category
+ self.cost = cost
+ self.buypower = buypower
+ self.vpoints = vpoints
+ def react(self,player):
+ return False
+
+class Coin_card(Card):
+ def __init__(self,name,cost,buypower):
+ Card.__init__(self,name,"coin",cost,buypower,0)
+
+class Copper(Coin_card):
+ def __init__(self):
+ Coin_card.__init__(self,"Copper",0,1)
+
+class Silver(Coin_card):
+ def __init__(self):
+ Coin_card.__init__(self,"Silver",3,2)
+
+class Gold(Coin_card):
+ def __init__(self):
+ Coin_card.__init__(self,"Gold",6,3)
+
+class Victory_card(Card):
+ def __init__(self,name,cost,vpoints):
+ Card.__init__(self,name,"victory",cost,0,vpoints)
+
+class Estate(Victory_card):
+ def __init__(self):
+ Victory_card.__init__(self,"Estate",2,1)
+
+class Duchy(Victory_card):
+ def __init__(self):
+ Victory_card.__init__(self,"Duchy",5,3)
+
+class Province(Victory_card):
+ def __init__(self):
+ Victory_card.__init__(self,"Province",8,6)
+
+class Garden(Victory_card):
+ def __init__(self):
+ Victory_card.__init__(self,"Garden",4,0)
+
+class Curse(Card):
+ def __init__(self):
+ Card.__init__(self,"Curse","curse",0,0,-1)
+
+class Action_card(Card):
+ def __init__(self,name,cost,actions,cards,buys,coins):
+ Card.__init__(self,name,"action",cost,0,0)
+ self.actions = actions
+ self.cards = cards
+ self.buys = buys
+ self.coins = coins
+ def use(self,player,trash):
+ player.played.append(self)
+ player.hand.remove(self)
+ def augment(self,player):
+ player.actions+=self.actions
+ player.buys+=self.buys
+ player.purse+=self.coins
+ for i in range(self.cards):
+ player.draw()
+ def play(self,player,players,supply,trash):
+ pass
+
+class Woodcutter(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Woodcutter",3,0,0,1,2)
+
+class Smithy(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Smithy",4,0,3,0,0)
+
+class Laboratory(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Laboratory",5,1,2,0,0)
+
+class Village(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Village",3,2,1,0,0)
+
+class Festival(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Festival",5,2,0,1,2)
+
+class Market(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Market",5,1,1,1,1)
+
+class Chancellor(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Chancellor",3,0,0,0,2)
+ def play(self,player,players,supply,trash):
+ if player.yesnoinput('Would you like to discard your entire deck?'):
+ player.discard = player.discard + player.deck
+ player.deck = []
+
+class Workshop(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Workshop",3,0,0,0,0)
+ def play(self,player,players,supply,trash):
+ player.gaincard(supply,4)
+
+class Moneylender(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Moneylender",4,0,0,0,0)
+ def play(self,player,players,supply,trash):
+ c = getcard("Copper",supply,player.hand,"your hand")
+ if c:
+ trash.append(c)
+ player.hand.remove(c)
+ player.purse += 3
+
+class Chapel(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Chapel",2,0,0,0,0)
+ def play(self,player,players,supply,trash):
+ trashed=0
+ while trashed<4 and len(player.hand)>0:
+ trashcard = input("Choose a card from your hand to trash: ")
+ if not trashcard:
+ break
+ c = getcard(trashcard,supply,player.hand,"your hand")
+ if c:
+ trash.append(c)
+ player.hand.remove(c)
+ trashed+=1
+
+class Cellar(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Cellar",2,1,0,0,0)
+ def play(self,player,players,supply,trash):
+ discarded=0
+ while len(player.hand)>0:
+ dis_card=input("Choose a card from your hand to discard: ")
+ if not dis_card:
+ break
+ c = getcard(dis_card,supply,player.hand,"your hand")
+ if c:
+ player.discard.append(c)
+ player.hand.remove(c)
+ discarded+=1
+ for j in range(discarded):
+ player.draw()
+
+class Remodel(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Remodel",4,0,0,0,0)
+ def play(self,player,players,supply,trash):
+ while len(player.hand)>0:
+ this_card = input("Choose a card from your hand to remodel: ")
+ c = getcard(this_card,supply,player.hand,"your hand")
+ if c:
+ trash.append(c)
+ player.hand.remove(c)
+ player.gaincard(supply,c.cost+2)
+ break
+
+class Adventurer(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Adventurer",6,0,0,0,0)
+ def play(self,player,players,supply,trash):
+ coins_added = 0
+ while (player.deck or player.discard) and coins_added <2:
+ player.draw()
+ if player.hand[-1].category == "coin":
+ coins_added +=1
+ else:
+ player.aside.append(player.hand.pop())
+
+class Feast(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Feast",4,0,0,0,0)
+ def use(self,player,trash):
+ trash.append(self)
+ player.hand.remove(self)
+ def play(self,player,players,supply,trash):
+ player.gaincard(supply,5)
+
+class Mine(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Mine",5,0,0,0,0)
+ def play(self,player,players,supply,trash):
+ while "coin" in catinlist(player.hand):
+ this_card = input("Choose a coin from your hand to upgrade: ")
+ c = getcard(this_card,supply,player.hand,"your hand",["coin"])
+ if c:
+ trash.append(c)
+ player.hand.remove(c)
+ while c.cost>2 or len(supply["Copper"])>0 or len(supply["Silver"])>0:
+ pick = input("Choose a coin to gain. Any coin up to " + str(c.cost+3)+": ")
+ g = getcard(pick,supply,categories=["coin"],upto=c.cost+3)
+ if g:
+ player.hand.append(g)
+ supply[pick].remove(g)
+ break
+ break
+
+class Library(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Library",5,0,0,0,0)
+ def play(self,player,players,supply,trash):
+ while (player.deck or player.discard) and len(player.hand) <7:
+ player.draw(player.hold)
+ if (player.hold[-1].category == "action" and not player.yesnoinput("You drew " + player.hold[-1].name + ". Would you like to keep it?",", add to my hand", ", set it aside")):
+ player.aside.append(player.hold.pop())
+ else:
+ player.hand.append(player.hold.pop())
+
+class Moat(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Moat",2,0,2,0,0)
+ def react(self,player):
+ player.show()
+ return player.yesnoinput(player.name + ", you have a " + self.name +
+ " in your hand. Do you want to block the attack?")
+
+class Council_Room(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Council Room",5,0,3,1,0)
+ def play(self,this_player,players,supply,trash):
+ for player in players:
+ player.draw()
+
+class Witch(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Witch",5,0,2,0,0)
+ def play(self,this_player,players,supply,trash):
+ if len(supply["Curse"])>0:
+ for player in players:
+ if player==this_player:
+ pass
+ else:
+ for c in player.hand:
+ if c.react(player):
+ break
+ else:
+ if len(supply["Curse"])>0:
+ player.discard.append(supply["Curse"].pop())
+
+class Bureaucrat(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Bureaucrat",4,0,0,0,0)
+ def play(self,this_player,players,supply,trash):
+ if len(supply["Silver"])>0:
+ this_player.deck.insert(0,supply["Silver"].pop())
+ for player in players:
+ if (not player==this_player) and ("victory" in catinlist(player.hand)):
+ for c in player.hand:
+ if c.react(player):
+ break
+ else:
+ player.show()
+ while True:
+ putback = player.choose_discard(player.name + ", which victory card" +
+ " do you want to put on top of your deck?\n--> ")
+ c = getcard(putback,supply,player.hand,"your hand",["victory"])
+ if c:
+ player.hand.remove(c)
+ player.deck.insert(0,c)
+ break
+
+class Militia(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Militia",4,0,0,0,2)
+ def play(self,this_player,players,supply,trash):
+ for player in players:
+ if (not player==this_player) and len(player.hand)>3:
+ for c in player.hand:
+ if c.react(player):
+ break
+ else:
+ player.show()
+ while len(player.hand)>3:
+ dis_card=player.choose_discard(player.name + ", choose a card from your hand to discard: ")
+ if dis_card:
+ c = getcard(dis_card,supply,player.hand,"your hand")
+ if c:
+ player.hand.remove(c)
+ player.discard.append(c)
+
+class Spy(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Spy",4,1,1,0,0)
+ def play(self,this_player,players,supply,trash):
+ for player in players:
+ for c in player.hand:
+ if c.react(player):
+ break
+ else:
+ b = player.draw([])
+ if not b:
+ continue
+ else:
+ print("The first card in the deck of " + player.name + " is " + b.name)
+ if this_player.yesnoinput(this_player.name + ", do you want " + player.name + " to discard this?",
+ ", discard",", keep"):
+ player.discard.append(b)
+ else:
+ player.deck.insert(0,b)
+ #check logic of this structure
+
+class Thief(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Thief",4,0,0,0,0)
+ def play(self,this_player,players,supply,trash):
+ for player in players:
+ if player == this_player:
+ continue
+ for c in player.hand:
+ if c.react(player):
+ break
+ else:
+ for i in range(2):
+ player.draw(player.hold)
+ print( player.name, namesinlist(player.hold))
+ if "coin" in catinlist(player.hold):
+ while True:
+ burn = input("Which card would you like " + player.name + " to trash?\n-->")
+ c = getcard(burn,supply,player.hold," the top 2 cards",["coin"])
+ if c:
+ player.hold.remove(c)
+ break
+ if this_player.yesnoinput("Do you want to steal it?",", it's mine!",", leave it in the trash."):
+ this_player.discard.append(c)
+ else:
+ trash.append(c)
+ player.discard=player.discard+player.hold
+ player.hold = []
+
+class Throne_Room(Action_card):
+ def __init__(self):
+ Action_card.__init__(self,"Throne Room",4,0,0,0,0)
+ def play(self,player,players,supply,trash):
+ if "action" in catinlist(player.hand):
+ while True:
+ double = input("What card would you like to double?\n--> ")
+ c = getcard(double,supply,player.hand," your hand",["action"])
+ if c:
+ c.use(player,trash)
+ c.augment(player)
+ c.play(player,players,supply,trash)
+ player.show()
+ c.augment(player)
+ c.play(player,players,supply,trash)
+ break
+
+
+class Player():
+ def __init__(self,name):
+ self.name = name
+ deal = [Copper()]*7 + [Estate()]*3
+ random.shuffle(deal)
+ self.hand = deal[:5]
+ self.deck = deal[5:]
+ self.played = []
+ self.discard = []
+ self.aside = []
+ self.hold = []
+ random.shuffle(self.deck)
+ for i in range(5):
+ self.draw
+ def other(self):
+ return self.played+self.discard+self.hold+self.aside
+ def stack(self):
+ return (self.deck + self.hand + self.played + self.discard + self.aside + self.hold)
+ def draw(self,dest=None):
+ #defualt destination is player's hand
+ if dest==None:
+ dest = self.hand
+ #Replenish deck if necessary.
+ if len(self.deck)==0:
+ self.deck = self.discard
+ self.discard = []
+ random.shuffle(self.deck)
+ #If deck has cards, add card to destination list
+ if len(self.deck)>0:
+ c = self.deck.pop(0)
+ dest.append(c)
+ return c
+ def turn(self,players,supply,trash):
+ self.show()
+ self.actions = 1
+ self.buys = 1
+ self.purse = 0
+ #action phase
+ while self.actions>0 and 'action' in catinlist(self.hand):
+ playthis = input("Which card would you like to play? You have " +
+ str(self.actions) + " action(s). \n-Hit enter for no play. --> ")
+ if playthis:
+ c = getcard(playthis,supply,self.hand,"your hand",['action'])
+ if c:
+ self.actions = self.actions - 1
+ c.use(self,trash)
+ c.augment(self)
+ c.play(self,players,supply,trash)
+ self.show()
+ else:
+ self.actions=0
+ #buy phase
+ for c in self.hand:
+ self.purse += c.buypower
+ while self.buys>0:
+ buy_string = "Buying power is " + str(self.purse) + ". You have " + str(self.buys) + " buy"
+ if self.buys>1:
+ buy_string += "s"
+ buy_string += "."
+ print( buy_string)
+ purchase = input("What would you like to purchase? -Hit enter for no purchase.-\n--> ")
+ if not purchase:
+ break
+ else:
+ c = getcard(purchase,supply,upto=self.purse)
+ if c:
+ self.discard.append(supply[purchase].pop())
+ self.buys = self.buys -1
+ self.purse = self.purse - c.cost
+
+ #cleanup phase
+ self.discard = self.discard + self.played + self.hand + self.aside
+ self.played = []
+ self.hand = []
+ self.aside = []
+ for i in range(5):
+ self.draw()
+
+ def gaincard(self,supply,upto):
+ while True:
+ gain = input("What would you like to get? Any card up to " + str(upto) + "\n--> ")
+ c = getcard(gain,supply,upto=upto)
+ if c:
+ self.discard.append(c)
+ supply[gain].remove(c)
+ break
+ def yesnoinput(self,prompt,yesstring='',nostring=''):
+ print(prompt + "\n1 - Yes" + yesstring + "\n0 - No" + nostring)
+ while True:
+ r = input("--> ")
+ if r == "0":
+ return False
+ if r == "1":
+ return True
+
+ def choose_discard(self,prompt):
+ return input(prompt)
+
+ def show(self):
+ print (self.name)
+ print ("hand: ", namesinlist(self.hand))
+ shuffled_deck = namesinlist(self.deck)
+ random.shuffle(shuffled_deck)
+ print ("deck (not in order): ", shuffled_deck)
+ print ("discard: ", namesinlist(self.discard))
+ if len(self.played)>0:
+ print ("played: ", namesinlist(self.played))
+ if len(self.aside)>0:
+ print ("aside: ",namesinlist(self.aside))
+ print ("\r")
+
+ def action_balance(self):
+ balance = 0
+ for c in self.stack():
+ if c.category == "action":
+ balance = balance - 1 + c.actions
+ return 70*balance / len(self.stack())
+
+ def cardsummary(self):
+ summary = {}
+ for c in self.stack():
+ if c.name in summary:
+ summary[c.name] += 1
+ else:
+ summary[c.name] = 1
+ return summary
+
+ def calcpoints(self):
+ tally = 0
+ gardens = 0
+ n = 0
+ for c in self.stack():
+ tally += c.vpoints
+ n += 1
+ if c.name == "Garden":
+ gardens+=1
+ return tally + n//10 * gardens
+
+class ComputerPlayer(Player):
+ def __init__(self,name):
+ Player.__init__(self,name)
+ self.index = 0
+ self.buygaintable = []
+ #beginning and middle of game
+ self.buygaintable1 = ["Province","Gold","Laboratory","Festival","Witch",
+ "Council Room","Market","Militia","Adventurer","Smithy","Bureaucrat","Silver","Moat",""]
+ #end of game
+ self.buygaintable2 = ["Province","Garden","Duchy","Estate","Gold","Silver",""]
+ #beginning and middle of the game, too many action cards
+ self.buygaintable3 = ["Province","Gold","Festival","Laboratory","Market","Village",
+ "Silver",""]
+ self.playtable1 = ["Village","Festival","Market","Laboratory","Witch",
+ "Council Room","Militia","Adventurer","Smithy","Bureaucrat","Moat",""]
+ self.discardtable1 = ["Garden","Duchy","Province","Estate","Curse","Copper",
+ "Village","Bureaucrat","Silver","Militia","Smithy","Council Room","Witch",
+ "Festival","Market","Adventurer","Laboratory","Gold","Moat"]
+
+ def turn(self,players,supply,trash):
+ self.show()
+ self.actions = 1
+ self.buys = 1
+ self.purse = 0
+ #action phase
+ self.index = 0
+ while self.actions>0 and 'action' in catinlist(self.hand):
+ playthis = self.playtable1[self.index]
+ if playthis:
+ c = self.getcard(playthis,supply,self.hand,"your hand",['action'])
+ if c:
+ #print (self.name + " plays " + c.name)
+ self.actions = self.actions - 1
+ c.use(self,trash)
+ self.index=0
+ c.augment(self)
+ c.play(self,players,supply,trash)
+ self.show()
+ else:
+ self.index += 1
+ else:
+ self.actions=0
+ #buy phase
+ if len(supply["Province"])>len(players)+totalbuypower(self.deck)/8:
+ if self.action_balance()<-10:
+ self.buygaintable = self.buygaintable3
+ else:
+ self.buygaintable = self.buygaintable1
+ else:
+ self.buygaintable = self.buygaintable2
+ self.index = 0
+ for c in self.hand:
+ self.purse += c.buypower
+ while self.buys>0:
+ purchase = self.buygaintable[self.index]
+ if not purchase:
+ break
+ else:
+ c = self.getcard(purchase,supply,upto=self.purse)
+ if c:
+ self.discard.append(supply[purchase].pop())
+ self.index = 0
+ self.buys = self.buys -1
+ self.purse = self.purse - c.cost
+ #print (self.name + " bought " + c.name)
+ else:
+ self.index += 1
+
+ #cleanup phase
+ self.discard = self.discard + self.played + self.hand + self.aside
+ self.played = []
+ self.hand = []
+ self.aside = []
+ for i in range(5):
+ self.draw()
+
+ def getcard(self,name,supply,target_list=None,target_name= "the supply anymore",categories=['action','coin','curse','victory'],upto=100):
+ if not name in supply:
+ #print name + " is not in this game."
+ return None
+ if not target_list:
+ target_list = supply[name]
+ nameslist = namesinlist(target_list)
+ if not name in nameslist:
+ #print "There is no " + name + " in " + target_name
+ return None
+ i = nameslist.index(name)
+ c = target_list[i]
+ if c.category not in categories:
+ catstring = categories[0]
+ for i in categories[1:]:
+ catstring = catstring + " or " + categories[i]
+ #print name + " is not a " + catstring + " card."
+ return None
+ if c.cost > upto:
+ #print name + " costs " + str(c.cost)
+ return None
+ return c
+
+ def choose_discard(self,prompt):
+ index = 0
+ while True:
+ dis_card = self.discardtable1[index]
+ c = self.getcard(dis_card,[dis_card],self.hand)
+ if c:
+ return c.name
+ else:
+ index+=1
+
+ def yesnoinput(self,prompt,yesstring='',nostring=''):
+ return True
+
+ def show(self):
+ pass
+
+class TablePlayer(ComputerPlayer):
+ def __init__(self,name):
+ ComputerPlayer.__init__(self,name)
+ self.index=0
+ self.buygaintable=[]
+ q=re.match(r'([a-zA-Z]+)(\d+)',name)
+ if q:
+ self.number = q.group(2)
+ else:
+ print(name)
+ self.playtable1 = ["Village","Festival","Market","Laboratory","Witch",
+ "Council Room","Militia","Adventurer","Smithy","Bureaucrat","Moat",""]
+ self.discardtable1 = ["Garden","Duchy","Province","Estate","Curse","Copper",
+ "Village","Bureaucrat","Silver","Militia","Smithy","Council Room","Witch",
+ "Festival","Market","Adventurer","Laboratory","Gold","Moat"]
+
+ def turn(self,players,supply,trash):
+ self.show()
+ self.actions = 1
+ self.buys = 1
+ self.purse = 0
+ #action phase
+ self.index = 0
+ while self.actions>0 and 'action' in catinlist(self.hand):
+ playthis = self.playtable1[self.index]
+ if playthis:
+ c = self.getcard(playthis,supply,self.hand,"your hand",['action'])
+ if c:
+ #print (self.name + " plays " + c.name)
+ self.actions = self.actions - 1
+ c.use(self,trash)
+ self.index=0
+ c.augment(self)
+ c.play(self,players,supply,trash)
+ self.show()
+ else:
+ self.index += 1
+ else:
+ self.actions=0
+ #buy phase
+ v= self.number
+ csvstring = r"Dominionbuy" + str(v) + ".csv"
+ buydf=pandas.read_csv(csvstring,na_filter=False)
+ sortedbuydf=buydf.sort_values("Buyvalues",ascending=False)
+ ranktable = sortedbuydf.Cardname
+ self.index = 0
+ for c in self.hand:
+ self.purse += c.buypower
+ while self.buys>0:
+ purchase = ranktable.iloc[self.index]
+ if not purchase:
+ break
+ else:
+ c = self.getcard(purchase,supply,upto=self.purse)
+ if c:
+ self.discard.append(supply[purchase].pop())
+ self.index = 0
+ self.buys = self.buys -1
+ self.purse = self.purse - c.cost
+ else:
+ self.index += 1
+
+ #cleanup phase
+ self.discard = self.discard + self.played + self.hand + self.aside
+ self.played = []
+ self.hand = []
+ self.aside = []
+ for i in range(5):
+ self.draw()
+
+
+def gameover(supply):
+ if len(supply["Province"])==0:
+ return True
+ out = 0
+ for stack in supply:
+ if len(supply[stack])==0:
+ out+=1
+ if out>=3:
+ return True
+ return False
+
+def namesinlist(cardlist):
+ namelist = []
+ for c in cardlist:
+ namelist.append(c.name)
+ return namelist
+
+def catinlist(cardlist):
+ catlist = []
+ for c in cardlist:
+ catlist.append(c.category)
+ return catlist
+
+def getcard(name,supply,target_list=None,target_name= "the supply anymore",categories=['action','coin','curse','victory'],upto=100):
+ if not name in supply:
+ print( name + " is not in this game.")
+ return None
+ if not target_list:
+ target_list = supply[name]
+ nameslist = namesinlist(target_list)
+ if not name in nameslist:
+ print ("There is no " + name + " in " + target_name)
+ return None
+ i = nameslist.index(name)
+ c = target_list[i]
+ if c.category not in categories:
+ catstring = categories[0]
+ for i in categories[1:]:
+ catstring = catstring + " or " + categories[i]
+ print (name + " is not a " + catstring + " card.")
+ return None
+ if c.cost > upto:
+ print (name + " costs " + str(c.cost))
+ return None
+ return c
+
+def totalbuypower(cardlist):
+ TBP = 0
+ for c in cardlist:
+ TBP += c.buypower
+ if c.category == "action":
+ TBP += c.coins
+ return TBP
+
+def countsupply(supply,form):
+ return [len(supply[a]) for a in form]
+
+def countcards(cards,form):
+ dcount = Counter(namesinlist(cards))
+ return [dcount[a] for a in form]
+
+def rankcards(form,vector):
+ od = OrderedDict(zip(form,vector))
+ sd = OrderedDict(sorted(od.items(),key = itemgetter(1),reverse=True))
+ return list(sd.keys())
+
+#import Dominion
+#import random
+from collections import defaultdict
+
+#Get player names
+player_names = ["Timothy","*Grover","*Elmo"]
+
+#number of curses and victory cards
+if len(player_names)>2:
+ nV=12
+else:
+ nV=8
+nC = -10 + 10 * len(player_names)
+
+#Define box
+box = {}
+box["Woodcutter"]=[Woodcutter()]*10
+box["Smithy"]=[Smithy()]*10
+box["Laboratory"]=[Laboratory()]*10
+box["Village"]=[Village()]*10
+box["Festival"]=[Festival()]*10
+box["Market"]=[Market()]*10
+box["Chancellor"]=[Chancellor()]*10
+box["Workshop"]=[Workshop()]*10
+box["Moneylender"]=[Moneylender()]*10
+box["Chapel"]=[Chapel()]*10
+box["Cellar"]=[Cellar()]*10
+box["Remodel"]=[Remodel()]*10
+box["Adventurer"]=[Adventurer()]*10
+box["Feast"]=[Feast()]*10
+box["Mine"]=[Mine()]*10
+box["Library"]=[Library()]*10
+box["Garden"]=[Garden()]*nV
+box["Moat"]=[Moat()]*10
+box["Council Room"]=[Council_Room()]*10
+box["Witch"]=[Witch()]*10
+box["Bureaucrat"]=[Bureaucrat()]*10
+box["Militia"]=[Militia()]*10
+box["Spy"]=[Spy()]*10
+box["Thief"]=[Thief()]*10
+box["Throne Room"]=[Throne_Room()]*10
+
+supply_order = {0:['Curse','Copper'],2:['Estate','Cellar','Chapel','Moat'],
+ 3:['Silver','Chancellor','Village','Woodcutter','Workshop'],
+ 4:['Garden','Bureaucrat','Feast','Militia','Moneylender','Remodel','Smithy','Spy','Thief','Throne Room'],
+ 5:['Duchy','Market','Council Room','Festival','Laboratory','Library','Mine','Witch'],
+ 6:['Gold','Adventurer'],8:['Province']}
+
+#Pick 10 cards from box to be in the supply.
+boxlist = [k for k in box]
+random.shuffle(boxlist)
+random10 = boxlist[:10]
+supply = defaultdict(list,[(k,box[k]) for k in random10])
+
+
+#The supply always has these cards
+supply["Copper"]=[Copper()]*(60-len(player_names)*7)
+supply["Silver"]=[Silver()]*40
+supply["Gold"]=[Gold()]*30
+supply["Estate"]=[Estate()]*nV
+supply["Duchy"]=[Duchy()]*nV
+supply["Province"]=[Province()]*nV
+supply["Curse"]=[Curse()]*nC
+
+#initialize the trash
+trash = []
+
+#Costruct the Player objects
+players = []
+for name in player_names:
+ if name[0]=="*":
+ players.append(ComputerPlayer(name[1:]))
+ elif name[0]=="^":
+ players.append(TablePlayer(name[1:]))
+ else:
+ players.append(Player(name))
+
+#Play the game
+turn = 0
+while not gameover(supply):
+ turn += 1
+ print("\r")
+ for value in supply_order:
+ print (value)
+ for stack in supply_order[value]:
+ if stack in supply:
+ print (stack, len(supply[stack]))
+ print("\r")
+ for player in players:
+ print (player.name,player.calcpoints())
+ print ("\rStart of turn " + str(turn))
+ for player in players:
+ if not gameover(supply):
+ print("\r")
+ player.turn(players,supply,trash)
+
+
+#Final score
+print ("\r")
+for player in players:
+ print (player.name,player.calcpoints())
+
+print ("\n")
+for player in players:
+ print (player.name,player.cardsummary())
\ No newline at end of file
diff --git a/projects/lieur/dominion/playDominion.py b/projects/lieur/dominion/playDominion.py
new file mode 100644
index 0000000..b4d6021
--- /dev/null
+++ b/projects/lieur/dominion/playDominion.py
@@ -0,0 +1,119 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Tue Oct 13 15:42:42 2015
+
+@author: tfleck
+"""
+
+import Dominion
+import random
+from collections import defaultdict
+
+#Get player names
+player_names = ["Annie","*Ben","*Carla"]
+
+#number of curses and victory cards
+if len(player_names)>2:
+ nV=12
+else:
+ nV=8
+nC = -10 + 10 * len(player_names)
+
+#Define box
+box = {}
+box["Woodcutter"]=[Dominion.Woodcutter()]*10
+box["Smithy"]=[Dominion.Smithy()]*10
+box["Laboratory"]=[Dominion.Laboratory()]*10
+box["Village"]=[Dominion.Village()]*10
+box["Festival"]=[Dominion.Festival()]*10
+box["Market"]=[Dominion.Market()]*10
+box["Chancellor"]=[Dominion.Chancellor()]*10
+box["Workshop"]=[Dominion.Workshop()]*10
+box["Moneylender"]=[Dominion.Moneylender()]*10
+box["Chapel"]=[Dominion.Chapel()]*10
+box["Cellar"]=[Dominion.Cellar()]*10
+box["Remodel"]=[Dominion.Remodel()]*10
+box["Adventurer"]=[Dominion.Adventurer()]*10
+box["Feast"]=[Dominion.Feast()]*10
+box["Mine"]=[Dominion.Mine()]*10
+box["Library"]=[Dominion.Library()]*10
+box["Gardens"]=[Dominion.Gardens()]*nV
+box["Moat"]=[Dominion.Moat()]*10
+box["Council Room"]=[Dominion.Council_Room()]*10
+box["Witch"]=[Dominion.Witch()]*10
+box["Bureaucrat"]=[Dominion.Bureaucrat()]*10
+box["Militia"]=[Dominion.Militia()]*10
+box["Spy"]=[Dominion.Spy()]*10
+box["Thief"]=[Dominion.Thief()]*10
+box["Throne Room"]=[Dominion.Throne_Room()]*10
+
+supply_order = {0:['Curse','Copper'],2:['Estate','Cellar','Chapel','Moat'],
+ 3:['Silver','Chancellor','Village','Woodcutter','Workshop'],
+ 4:['Gardens','Bureaucrat','Feast','Militia','Moneylender','Remodel','Smithy','Spy','Thief','Throne Room'],
+ 5:['Duchy','Market','Council Room','Festival','Laboratory','Library','Mine','Witch'],
+ 6:['Gold','Adventurer'],8:['Province']}
+
+#Pick 10 cards from box to be in the supply.
+boxlist = [k for k in box]
+random.shuffle(boxlist)
+random10 = boxlist[:10]
+supply = defaultdict(list,[(k,box[k]) for k in random10])
+
+
+#The supply always has these cards
+supply["Copper"]=[Dominion.Copper()]*(60-len(player_names)*7)
+supply["Silver"]=[Dominion.Silver()]*40
+supply["Gold"]=[Dominion.Gold()]*30
+supply["Estate"]=[Dominion.Estate()]*nV
+supply["Duchy"]=[Dominion.Duchy()]*nV
+supply["Province"]=[Dominion.Province()]*nV
+supply["Curse"]=[Dominion.Curse()]*nC
+
+#initialize the trash
+trash = []
+
+#Costruct the Player objects
+players = []
+for name in player_names:
+ if name[0]=="*":
+ players.append(Dominion.ComputerPlayer(name[1:]))
+ elif name[0]=="^":
+ players.append(Dominion.TablePlayer(name[1:]))
+ else:
+ players.append(Dominion.Player(name))
+
+#Play the game
+turn = 0
+while not Dominion.gameover(supply):
+ turn += 1
+ print("\r")
+ for value in supply_order:
+ print (value)
+ for stack in supply_order[value]:
+ if stack in supply:
+ print (stack, len(supply[stack]))
+ print("\r")
+ for player in players:
+ print (player.name,player.calcpoints())
+ print ("\rStart of turn " + str(turn))
+ for player in players:
+ if not Dominion.gameover(supply):
+ print("\r")
+ player.turn(players,supply,trash)
+
+
+#Final score
+dcs=Dominion.cardsummaries(players)
+vp=dcs.loc['VICTORY POINTS']
+vpmax=vp.max()
+winners=[]
+for i in vp.index:
+ if vp.loc[i]==vpmax:
+ winners.append(i)
+if len(winners)>1:
+ winstring= ' and '.join(winners) + ' win!'
+else:
+ winstring = ' '.join([winners[0],'wins!'])
+
+print("\nGAME OVER!!!\n"+winstring+"\n")
+print(dcs)
\ No newline at end of file
diff --git a/projects/lieur/dominion/testDominion1.py b/projects/lieur/dominion/testDominion1.py
new file mode 100644
index 0000000..f533ba8
--- /dev/null
+++ b/projects/lieur/dominion/testDominion1.py
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+""""
+Created on Saturday, January 18, 2020
+
+@author: lieur
+
+This test case sets the random supply box to null, meaning only victory cards
+and money exist. This allows us to test the coin buying and victory conditions of
+when the provinces are all sold out.
+"""""
+
+import Dominion
+import testUtility
+import random
+from collections import defaultdict
+
+# Get player names
+player_names = ["Annie", "*Ben", "*Carla"]
+
+# Set number of curses and victory cards
+nV, nC = testUtility.set_vc_number(player_names)
+
+# Define box and supply_order
+box, supply_order = testUtility.define_box(nV)
+
+#Test no box
+box = {}
+
+# Choose and set supply cards
+supply = testUtility.set_supply(box, player_names, nV, nC)
+
+# Initialize the trash
+trash = []
+
+# Construct the Player objects
+players = testUtility.set_players(player_names)
+
+# Play the game
+testUtility.play_game(supply, supply_order, players, trash)
+
+
+# Final score
+testUtility.display_game_results(players)
\ No newline at end of file
diff --git a/projects/lieur/dominion/testDominion2.py b/projects/lieur/dominion/testDominion2.py
new file mode 100644
index 0000000..b7423e4
--- /dev/null
+++ b/projects/lieur/dominion/testDominion2.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+""""
+Created on Saturday, January 18, 2020
+
+@author: lieur
+
+This test case sets silver and gold to 0, which in most cases prevent the computer from
+buying provinces. This tests to see if the game ends when one more supply car hits 0 (since
+silver and gold are already at 0 and the game ends when 3 supply deck hits 0)
+"""""
+
+import Dominion
+import testUtility
+import random
+from collections import defaultdict
+
+# Get player names
+player_names = ["Annie", "*Ben", "*Carla"]
+
+# Set number of curses and victory cards
+nV, nC = testUtility.set_vc_number(player_names)
+
+# Define box and supply_order
+box, supply_order = testUtility.define_box(nV)
+
+
+# Choose and set supply cards
+supply = testUtility.set_supply(box, player_names, nV, nC)
+
+# Initialize the trash
+trash = []
+# Test silver and gold = 0
+supply["Copper"]=[Dominion.Copper()]*(60-len(player_names)*7)
+supply["Silver"]=[Dominion.Silver()]*0
+supply["Gold"]=[Dominion.Gold()]*0
+
+# Construct the Player objects
+players = testUtility.set_players(player_names)
+
+# Play the game
+testUtility.play_game(supply, supply_order, players, trash)
+
+# Final score
+testUtility.display_game_results(players)
\ No newline at end of file
diff --git a/projects/lieur/dominion/testUtility.py b/projects/lieur/dominion/testUtility.py
new file mode 100644
index 0000000..34c2e6f
--- /dev/null
+++ b/projects/lieur/dominion/testUtility.py
@@ -0,0 +1,123 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Saturday, January 18, 2020
+
+@author: lieur
+"""
+
+import Dominion
+import random
+from collections import defaultdict
+
+def set_vc_number(player_names):
+ if len(player_names)>2:
+ nV=12
+ else:
+ nV=8
+ nC = -10 + 10 * len(player_names)
+ return nV, nC
+
+#Define definebox
+def define_box(nV):
+ box = {}
+ box["Woodcutter"]=[Dominion.Woodcutter()]*10
+ box["Smithy"]=[Dominion.Smithy()]*10
+ box["Laboratory"]=[Dominion.Laboratory()]*10
+ box["Village"]=[Dominion.Village()]*10
+ box["Festival"]=[Dominion.Festival()]*10
+ box["Market"]=[Dominion.Market()]*10
+ box["Chancellor"]=[Dominion.Chancellor()]*10
+ box["Workshop"]=[Dominion.Workshop()]*10
+ box["Moneylender"]=[Dominion.Moneylender()]*10
+ box["Chapel"]=[Dominion.Chapel()]*10
+ box["Cellar"]=[Dominion.Cellar()]*10
+ box["Remodel"]=[Dominion.Remodel()]*10
+ box["Adventurer"]=[Dominion.Adventurer()]*10
+ box["Feast"]=[Dominion.Feast()]*10
+ box["Mine"]=[Dominion.Mine()]*10
+ box["Library"]=[Dominion.Library()]*10
+ box["Gardens"]=[Dominion.Gardens()]*nV
+ box["Moat"]=[Dominion.Moat()]*10
+ box["Council Room"]=[Dominion.Council_Room()]*10
+ box["Witch"]=[Dominion.Witch()]*10
+ box["Bureaucrat"]=[Dominion.Bureaucrat()]*10
+ box["Militia"]=[Dominion.Militia()]*10
+ box["Spy"]=[Dominion.Spy()]*10
+ box["Thief"]=[Dominion.Thief()]*10
+ box["Throne Room"]=[Dominion.Throne_Room()]*10
+
+ supply_order = {0: ['Curse', 'Copper'], 2: ['Estate', 'Cellar', 'Chapel', 'Moat'],
+ 3: ['Silver', 'Chancellor', 'Village', 'Woodcutter', 'Workshop'],
+ 4: ['Gardens', 'Bureaucrat', 'Feast', 'Militia', 'Moneylender', 'Remodel', 'Smithy', 'Spy', 'Thief',
+ 'Throne Room'],
+ 5: ['Duchy', 'Market', 'Council Room', 'Festival', 'Laboratory', 'Library', 'Mine', 'Witch'],
+ 6: ['Gold', 'Adventurer'], 8: ['Province']}
+ return box, supply_order
+
+#
+def set_supply(box, player_names, nV, nC):
+ #Pick 10 cards from box to be in the supply.
+ boxlist = [k for k in box]
+ random.shuffle(boxlist)
+ random10 = boxlist[:10]
+ supply = defaultdict(list,[(k,box[k]) for k in random10])
+ #The supply always has these cards
+ supply["Copper"]=[Dominion.Copper()]*(60-len(player_names)*7)
+ supply["Silver"]=[Dominion.Silver()]*40
+ supply["Gold"]=[Dominion.Gold()]*30
+ supply["Estate"]=[Dominion.Estate()]*nV
+ supply["Duchy"]=[Dominion.Duchy()]*nV
+ supply["Province"]=[Dominion.Province()]*nV
+ supply["Curse"]=[Dominion.Curse()]*nC
+ return supply
+
+#Define set_players
+def set_players(player_names):
+ players = []
+ for name in player_names:
+ if name[0] == "*":
+ players.append(Dominion.ComputerPlayer(name[1:]))
+ elif name[0] == "^":
+ players.append(Dominion.TablePlayer(name[1:]))
+ else
+ players.append(Dominion.Player(name))
+ return players
+
+#define play game
+def play_game(supply, supply_order, players, trash):
+ turn = 0
+ while not Dominion.gameover(supply):
+ turn += 1
+ print("\r")
+ for value in supply_order:
+ print(value)
+ for stack in supply_order[value]:
+ if stack in supply:
+
+ print(stack, len(supply[stack]))
+ print("\r")
+ for player in players:
+ print(player.name, player.calcpoints())
+ print("\rStart of turn " + str(turn))
+ for player in players:
+ if not Dominion.gameover(supply):
+ print("\r")
+ player.turn(players, supply, trash)
+
+#Define display_game_results
+def display_game_results(players):
+ 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)
+