view chainup.py @ 0:a9991245138f default tip

Chain up is a card game.
author kent <kent@cr.ie.u-ryukyu.ac.jp>
date Tue, 09 Dec 2008 15:55:11 +0900
parents
children
line wrap: on
line source

#!/usr/bin/python
# -*- coding: UTF-8 -*- 

import random,readline
from Tkinter import *

class GameManager:
	def __init__(self, size=5):
		self.trumped = []
		self.hands = None
		self.talon = None
		self.handsSize = size
		self.marker = [ [ True for m in range(13) ]for n in range(4) ]
	def createTalon(self):
		self.talon = []
		#self.talon.append( Card(0, 0) )
		#self.talon.append( Card(0, 0) )
		#for r in range(1, 14):
			#for s in range(1, 5):
				#self.talon.append( Card(s, r) ) # it's same with following sentence.
		self.talon.extend( [ Card(s, r) for r in range(1,14) for s in range(1,5) ] )
		assert len(self.talon)
	def start(self):
		assert self.hands==None
		self.createTalon()
		random.shuffle(self.talon)
		self.hands = []
		while len(self.hands)<self.handsSize:
			self.hands.append( self.talon.pop() )
		self.trumped.append( Card(0,0))
	def getHand(self, n=None):
		if n==None:
			return self.hands
		else:
			return self.hands[n]
	def trump(self, n):
		#assert 0<=n<=self.handsSize and self.hands!=None
		if not 0<=n<=self.handsSize or self.hands==None: return False
		if not self.checkTrumpable(n): return False
		card = self.hands[n]
		self.trumped.append(card)
		self.marker[card.suit-1][card.rank-1] = False
		if len(self.talon) >= 1:
			self.hands[n] = self.talon.pop()
		else:
			self.hands[n] = None
		return True
		#self.hands[n] = (len(self.talon)>1)? self.talon.pop(): None
	def checkTrumpable(self, n):
		card=self.hands[n]
		if card==None: return False
		if len(self.trumped)==0:
			return True
		top = self.trumped[-1]
		if top.suit==card.suit or top.rank==card.rank:
			return True
		if top.suit==0 or card.suit==0:
			return True
		return False
	def getTopOfTrumped(self):
		if len(self.trumped)==0: return None
		return self.trumped[-1]
	def reset(self, n=5):
		del self.trumped
		del self.hands
		del self.talon
		del self.handsSize
		del self.marker
		self.__init__(n)
		self.start()




class Card:
	def __init__(self, suit, rank):
		self.suit = suit
		self.rank = rank
	def toString(self):
		if 1 == self.rank: s = "A"
		elif 11 == self.rank: s = "J"
		elif 12 == self.rank: s = "Q"
		elif 13 == self.rank: s = "K"
		elif 2 <= self.rank <= 10:
			s = str(self.rank)
		elif 2 == self.rank:  s = "o"
		else: s = "?"

		if self.suit == 0: f = "J" # Joker
		elif self.suit == 1: f = "S"
		elif self.suit == 2: f = "H"
		elif self.suit == 3: f = "C"
		elif self.suit == 4: f = "D"
		else: f = "?"

		return f + s
	def toFilename(self):
		if 1 == self.rank: s = "a"
		elif 0 == self.rank: s = ""
		elif 10 == self.rank: s = "t"
		elif 11 == self.rank: s = "j"
		elif 12 == self.rank: s = "q"
		elif 13 == self.rank: s = "k"
		elif 2 <= self.rank <= 9:
			s = str(self.rank)
		else: s = "?"

		if self.suit == 0: f = "j" # Joker
		elif self.suit == 1: f = "s"
		elif self.suit == 2: f = "h"
		elif self.suit == 3: f = "c"
		elif self.suit == 4: f = "d"
		else: f = "?"

		return "images/"+s+f+".gif"
	@classmethod
	def rank2str(cls, rank=None):
		if rank==None: rank=cls.rank
		if 1 == rank: s = "A"
		elif 0 == rank: s = " "
		elif 10 == rank: s = "T"
		elif 11 == rank: s = "J"
		elif 12 == rank: s = "Q"
		elif 13 == rank: s = "K"
		elif 2 <= rank <= 9:
			s = str(rank)
		else: s = "?"
		return s
	@classmethod
	def suit2str(cls, suit=None):
		if suit == 0: s = "J" # Joker
		elif suit == 1: s = "S"
		elif suit == 2: s = "H"
		elif suit == 3: s = "C"
		elif suit == 4: s = "D"
		else: s = "?"
		return s


def suitToString(suit):
	if suit == 0: return "Joker"
	elif suit == 1: return "Spades"
	elif suit == 2: return "Hearts"
	elif suit == 3: return "Clubs"
	elif suit == 4: return "Diremonds"
	else: return -1

# for CUI
def chk(gm,x):
	""" Internal function for game.  """
	if gm.checkTrumpable(x):
		return "*"
	else:
		return ""
def print_status(gm, c):
	""" Internal function for game.  """
	print " top:",gm.getTopOfTrumped().toString(), c
	#print "     ",chk(gm,0).rjust(4),chk(gm,1).rjust(4),chk(gm,2).rjust(4),chk(gm,3).rjust(4),chk(gm,4).rjust(4)
	print "     ", "".join(map(lambda x:chk(gm,x).rjust(4), range(len(gm.getHand()))))
	#print "Hand: ".join(map(lambda x:x.toString(), gm.getHand()))
	print "Hand:", "".join(map(lambda x:x.toString().rjust(4), gm.getHand()))
def game_cui(n):
	gm = GameManager(n)
	gm.start()
	count=0
	print len(gm.getHand())

	while True:
		print_status(gm,count)
		str = raw_input('(1..5): ')
		if str=="reset":
			gm.reset(n)
			continue
		n = int(str)-1
		f = gm.trump(n)
		if f: count+=1





# GUI
class Field(Frame, GameManager):
	def __init__(self, size=5, master=None):
		Frame.__init__(self, master)
		GameManager.__init__(self, size)
		self.pack()
	def start(self):
		GameManager.start(self) # superclass method

		# widgets for hands.
		fr = Frame(self)
		fr.pack(side='bottom')
		self.createHands(fr)
		# widgets for trumped card.
		img = PhotoImage(file="images/j.gif")
		self.lastTrumped = Label(self, relief=FLAT, image=img)
		self.lastTrumped.img = img
		self.lastTrumped.pack(side='left')
		# widgets for status of remaining cards.
		fr = Frame(self)
		fr.pack(side='left')
		self.createStatusBar(fr)
		# widgets for reset and quit buttons.
		fr = Frame(self)
		fr.pack(side='left')
		self.createCtrlButtons(fr)
	def createCtrlButtons(self, fr):
		resetB = Button(fr, text="Reset", command=self.resetButton)
		quitB = Button(fr, text="Quit")
		resetB.pack(side='top')
		quitB.pack(side='top')
	def createHands(self, fr):
		self.b = []
		for n in range(self.handsSize):
			# hands
			img = PhotoImage()
			self.b.append( Button(fr, image=img, borderwidth=1))
			self.b[n].img = img
			self.b[n].img.config(file=self.hands[n].toFilename())
			def tmp(a):
				return lambda: self.trump(a)
			self.b[n].config(command=tmp(n))
			self.b[n].pack(side='left')
		self.checkHands()
	def createStatusBar(self, fr):
		fr4 = [ Frame(fr) for n in range(4) ]
		map( lambda x: x.pack(side='top') , fr4)
		self.status = [ [ Label(fr4[n], text=Card.rank2str(m+1)) for m in range(13) ]for n in range(4) ]
		for i in range(4):
			lb = Label(fr4[i], text=Card.suit2str(i+1))
			lb.pack(side='left')
			map( lambda x: x.pack(side='left') , self.status[i] )
	def trump(self, n):
		if not GameManager.trump(self, n): return False
		#print "No",n,"was trumped"
		lt = self.trumped[-1]
		if self.hands[n]!=None:
			self.b[n].img.config(file=self.hands[n].toFilename())
		else:
			self.b[n].img.config(file="images/b.gif")
		self.lastTrumped.img.config(file=lt.toFilename())
		self.status[lt.suit-1][lt.rank-1].config(fg="grey")
		self.checkHands()
		print "trumped", len(self.trumped)
		print "talon", len(self.talon)
		return True
	def checkHands(self):
		# hands
		for n in range(self.handsSize):
			if self.checkTrumpable(n):
				self.b[n].config(state=NORMAL)
				self.b[n].bind("<Enter>", self.mouseOver, "+")
				self.b[n].bind("<Leave>", self.mouseOut, "+")
			else:
				self.b[n].config(state=DISABLED)
				self.b[n].unbind("<Enter>")
				self.b[n].unbind("<Leave>")
		#print self.marker
	def resetButton(self):
		self.reset(self.handsSize)
	def reset(self, n):
		del self.b
		del self.status
		del self.lastTrumped
		GameManager.reset(self, n)
		
	# Event handlers
	def clicked(self, no):
		""" Callback function for Button.  """
		#print "clicked", no
		#self.trump(no)
	def mouseOver(self, event):
		""" Callback function for Button.  """
		#print "over"
		event.widget.config(fg="#ff0000")
	def mouseOut(self, event):
		""" Callback function for Button.  """
		#print "out"
		event.widget.config(fg="#000000")

def game_gui(n):
	field = Field(n)
	field.createTalon()
	field.start()
	field.mainloop()


game_gui(12)
#game_cui(10)