#!/usr/bin/env python
#########
# Cards #
#########

#This software is coypright 2008 by Thomas Dickerson
#and StickFigure Graphic Productions
#under the terms of the GNU General Public License v3
#a copy of which may be obtained here: http://www.gnu.org/licenses/gpl-3.0.txt

import sys, os, random

defaultsuits = {'spades' : 'black', 'clubs' : 'black', 'hearts' : 'red', 'diamonds' : 'red'}
defaultvalues = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']

class Card:
	
	#defines a card
	def __init__(self, suit, value, deck):
		__init__(self, suit, value, suitdict = deck.getsuitdict(), valset = deck.getvalueset())
	
	def __init__(self, suit, value, suitdict = None, valset = None):
		if suitdict == None:
			global defaultsuits
			suitdict = defaultsuits
		if valset == None:
			global defaultvalues
			valset = defaultvalues
		if suit in suitdict:
			self.suit = suit
			self.color = suitdict[suit]
		else:
			raise TypeError, ("suit '%s' is not a member of the key-set %s for suitdict" % (suit, str(suitdict.keys())))
		if valset.count(value) > 0:
			self.value = value
		else:
			raise TypeError, ("value '%s' is not a member of valset %s" % (value, str(valset)))
	
	def getsuit(self):
		return self.suit
		
	def getcolor(self):
		return self.color
			
	def getvalue(self):
		return self.value
		
	def __str__(self):
		return "%s of %s" % (self.value, self.suit)

class Deck:

	#defines a deck
	def __init__(self, suitdict = None, valset = None, mergedecks = None):
		if suitdict == None:
			global defaultsuits
			suitdict = defaultsuits
		if valset == None:
			global defaultvalues
			valset = defaultvalues
		self.suitdict = suitdict
		self.valset = valset
		self.deck = []
		if len(mergedecks):
			for i in mergedecks:
				for x in i:
					self.deck.append(x)
			
				
	def shuffle(self):
		random.shuffle(self.deck)
	
	def getsuitdict(self):
		return self.suitdict
		
	def getvalueset(self):
		return self.valset
		
	def addcard(self, card):
		self.deck.append(card)
		
	def addcards(self, cards):
		self.deck += cards
		
	def removecard(self, card):
		self.deck.remove(card)
		
	def removecards(self, cards):
		for card in cards:
			self.deck.remove(card)
			
	def drawcard(self):
		return self.deck.pop()
		
	def drawcards(self, count):
		cards = []
		for i in range(0, count):
			cards.append(self.deck.pop())
		return cards
		
	def drawrandomcard(self):
		return self.deck.pop(random.randrange(0, len(self.deck)))
		
	def drawrandomcards(self, count):
		cards = []
		for i in range(0, count):
			cards.append(self.deck.pop(random.randrange(0, len(self.deck))))
		return cards
	
	def getdeck(self):
		return self.deck
		
	def countdeck(self):
		return len(self.deck)
		
	def printdeck(self):
		for i in self.deck:
			print i

class Game:

	#defines a game
	def __init__(self, deck = None, playergroup = None, observergroup = None, gametype = None):
		self.deck = deck
		if playergroup == None:
			playergroup = []
		if observergroup == None:
			observergroup = []
		self.playergroup = playergroup
		self.gametype = gametype
		self.observergroup = observergroup
	
	def deal(self, toeach):
		for i in range(0, toeach * self.countplayers()):
			player = self.getplayerat(i % self.countplayers())
			card = self.deck.drawcard()
			player.acceptcard(card)
		
	def observe(self):
		return (self.getgametype(), self.getdeck(), self.getplayers())
		
	def play(self):
		self.deal(toeach = 3)
		gametype, deck, players = self.observe()
		print "Gametype: '%s'" % gametype
		print "%d cards left in deck" % deck.countdeck()
		deck.printdeck()
		print ""
		print "Players: "
		for player in players:
			print "\t%s" % str(player)
			print "\tCards: ",
			for card in player.gethand():
				print str(card) + ", ",
			print ""
			print ""
		
	def getplayers(self):
		return self.playergroup
	
	def setplayers(self, playergroup = None):
		#to blank the player list, just use game.setplayers()
		if playergroup == None:
			playergroup = []
		self.playergroup = playergroup

	def addplayer(self, player):
		self.playergroup.append(player)
		
	def removeplayer(self, player):
		self.playergroup.remove(player)
		
	def addplayers(self, players):
		self.playergroup += players
		
	def removeplayers(self, players):
		for player in players:
			self.playergroup.remove(player)
			
	def countplayers(self):
		return len(self.playergroup)
		
	def getplayerat(self, at):
		return self.playergroup[at]
	
	def removeplayerat(self, at):
		return self.playergroup.pop(at)
	
	def getgametype(self):
		return self.gametype
	
	def setgametype(self, gametype=None):
		self.gametype = gametype
		
	def getdeck(self):
		return self.deck
		
	def setdeck(self, deck = None):
		self.deck = deck
	
	def clearplayers(self):
		self.setplayers()
	
	def cleardeck(self):
		self.setdeck()
		
	def cleargametype(self):
		self.setgametype()

class Player:
	
	#defines a player
	def __init__(self, game=None, hand=None, name="", observer=False):
		self.game = game
		if hand == None:
			self.hand = []
		else:
			self.hand = hand
		self.name = name
		self.observer = observer
	
	def __str__(self):
		return "Name: " + self.name
		
	def isobserver(self):
		return self.observer
		
	def setobserver(self, observer=False):
		self.observer = observer
		
	def play(self):
		self.setobserver()
		
	def observe(self):
		self.setobserver(observer=True)
		
	def getgame(self):
		return self.game
		
	def setgame(self, game):
		self.game = game
		
	def acceptcard(self, card):
		self.addcard(card)
		
	def acceptcards(self, cards):
		self.addcards(cards)
	
	def addcard(self, card):
		self.hand.append(card)
		random.shuffle(self.hand)
		
	def addcards(self, cards):
		self.hand += cards
		random.shuffle(self.hand)
		
	def removecard(self, card):
		self.hand.remove(card)
		
	def removecards(self, cards):
		for card in cards:
			self.hand.remove(card)
			
	def drawcard(self):
		return self.drawrandomcard()
		
	def drawcards(self, count):
		return self.drawrandomcards(count)
		
	def drawrandomcard(self):
		return self.hand.pop(random.randrange(0, len(self.hand)))
		
	def drawrandomcards(self, count):
		cards = []
		for i in range(0, count):
			cards.append(self.hand.pop(random.randrange(0, len(self.hand))))
		return cards
		
	def gethand(self):
		return self.hand
		
	def sethand(self, hand=[]):
		self.hand = hand
		
	def clearhand(self):
		self.sethand()	
	
	def getname(self):
		return self.name
		
	def setname(self, name):
		self.name = name
	
					
def makedeck(suitdict = None, valset = None):
	newdeck = []
	if suitdict == None:
		global defaultsuits
		suitdict = defaultsuits
	if valset == None:
		global defaultvalues
		valset = defaultvalues
	for suit in suitdict.keys():
		for value in valset:
			newdeck.append(Card(suit, value, suitdict = suitdict, valset = valset))
	return Deck(suitdict = suitdict, valset = valset, mergedecks = [newdeck])
		
if __name__ == "__main__":
	mydeck = makedeck()
	mydeck.printdeck()