I don't know if it's because I'm tired or what, but I can't seem to
get the "New Game" function in my card game to work. The canvas won't
refresh. All I'm doing is reinitializing all the data and classes,
but it doesn't seem to work until I use wx.ClientDC. I think that
there may be other problems in the reinitialization, but I'm not
concerned about that (however, if you want to look through it for
other bugs, please go ahead). Please excuse the mess: the comments
are all jumbled and there are a lot of direct references to far-
removed methods and such.
···
#------------------------------------------------------------------------------
#!/usr/bin/python
import wx
import sys
from whist import *
class CardPlacement:
def __init__(self, clientSize, deckSize=26, cardsize=(73,97),
humanAmount=13, computerAmount=13):
self.clientSize = clientSize
self.deckSize = deckSize
self.cardsize = cardsize
self.amountCardscomputer = computerAmount
self.amountCardshuman = humanAmount
self.overlapSpace = 20
self.computerbeginPos = (self.clientSize[0]/2 -
(self.overlapSpace*(self.amountCardscomputer-1)-self.cardsize[0]), 15)
self.humanbeginPos = (self.clientSize[0]/2 -
(self.overlapSpace*(self.amountCardshuman-1)-self.cardsize[0]),
self.clientSize[1] - 15 - self.cardsize[1])
class CardGraphics(wx.Window):
def __init__(self, parent):
wx.Window.__init__(self, parent)
self.parent = parent
self.size = (parent.size[0], parent.size[1] - 50)
self.backimage = wx.Image("cards/b.gif").ConvertToBitmap()
self.InitBuffer()
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_LEFT_DOWN, self.Click)
self.Bind(wx.EVT_LEFT_UP, self.offClick)
self.Bind(wx.EVT_MOTION, self.Motion)
self.dealt = False
self.data = CardPlacement(self.size)
self.I = False
def updatePos(self, player):
if player == "human":
for i in range(len(self.parent.human.hand.cards)):
if self.parent.human.hand.cards[i].position[1] ==
self.data.humanbeginPos[1]:
self.parent.human.hand.cards[i].position =
(self.data.humanbeginPos[0] + i*self.data.overlapSpace,
self.data.humanbeginPos[1])
elif player == "computer":
for i in range(len(self.parent.computer.hand.cards)):
if self.parent.computer.hand.cards[i].position[1] ==
self.data.computerbeginPos[1]:
self.parent.computer.hand.cards[i].position =
(self.data.computerbeginPos[0] + i*self.data.overlapSpace,
self.data.computerbeginPos[1])
def Click(self, evt):
x = evt.GetX()
y = evt.GetY()
for i in range(len(self.parent.human.hand.cards)):
if self.parent.human.hand.cards[i].position[0] < x <
self.parent.human.hand.cards[i].position[0]+self.data.overlapSpace and
self.parent.human.hand.cards[i].position[1] < y <
self.parent.human.hand.cards[i].position[1] +
self.parent.human.hand.cards[i].size[1] or
(i==len(self.parent.human.hand.cards)-1 and
self.parent.human.hand.cards[-1].position[0] < x <
self.parent.human.hand.cards[-1].position[0] +
self.parent.human.hand.cards[-1].size[0]):
#select the card, but only if it is human's turn
if self.parent.turn == "human":
if not self.parent.first:
available =
self.parent.human.hand.inSuit(self.parent.lead.suit)
if not available:
available = self.parent.human.hand.cards
if self.parent.human.hand.cards[i] in available:
self.parent.storeHposition =
self.parent.human.hand.cards[i].position
self.parent.human.hand.cards[i].position = ((self.size[0] +
self.parent.human.hand.cards[i].size[0])/2.5 + 40, self.size[1]*.4)
self.parent.Hcard = self.parent.human.hand.cards[i]
if self.parent.Hcard.suit == self.parent.trump.suit:
self.parent.trumpPlayed = True
self.parent.timer.Start(1000)
#return
else:
self.parent.human.hand.cards[i].inverted = True
self.I = True
#return
else:
if self.parent.human.hand.cards[i].suit !=
self.parent.trump.suit or self.parent.trumpPlayed:
self.parent.storeHposition =
self.parent.human.hand.cards[i].position
self.parent.human.hand.cards[i].position = ((self.size[0] +
self.parent.human.hand.cards[i].size[0])/2.5, self.size[1]*.4)
self.parent.lead = self.parent.Hcard =
self.parent.human.hand.cards[i]
self.parent.turn = "computer"
self.parent.timer.Start(1000)
#return
else:
self.parent.human.hand.cards[i].inverted = True
self.I = True
#return
dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
self.DrawEverything(dc)
return
def offClick(self, evt):
x = evt.GetX()
y = evt.GetY()
if self.I == True:
for i in range(len(self.parent.human.hand.cards)):
if self.parent.human.hand.cards[i].inverted:
self.parent.human.hand.cards[i].inverted = False
self.I = False
dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
self.DrawEverything(dc)
def Motion(self, evt):
x = evt.GetX()
y = evt.GetY()
hitTest = False
if self.I == True:
for i in range(len(self.parent.human.hand.cards)):
if self.parent.human.hand.cards[i].inverted and (not
self.data.humanbeginPos[0] < x < self.data.humanbeginPos[0] +
(len(self.parent.human.hand.cards)-1)*self.data.overlapSpace +
self.data.cardsize[0] or not self.data.humanbeginPos[1] < y <
self.data.humanbeginPos[1] + self.data.cardsize[1]):
self.parent.human.hand.cards[i].inverted = False
self.I = False
dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
self.DrawEverything(dc)
def InitBuffer(self):
self.buffer = wx.EmptyBitmap(*self.size)
dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
brush = wx.Brush((0x00, 0xaa, 0x00))
dc.SetBackground(brush)
dc.Clear()
def DrawEverything(self, dc):
brush = wx.Brush((0x00, 0xaa, 0x00))
dc.SetBackground(brush)
dc.Clear()
self.DrawCards(dc, self.parent.human.hand.cards,
self.parent.computer.hand.cards)
self.DrawDeck(dc)
def OnPaint(self, evt):
dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
def DrawCards(self, dc, humanCards, computerCards):
#print computerCards[0].position
#print humanCards[0].position
#draw computer cards
if self.parent.first:
self.DrawHumanCards(dc, humanCards)
self.DrawComputerCards(dc, computerCards)
else:
self.DrawComputerCards(dc, computerCards)
self.DrawHumanCards(dc, humanCards)
#draw human cards
#pass
def DrawHumanCards(self, dc, humanCards):
if humanCards:
for i in range(len(humanCards)):
cardImage = wx.Image("cards/"+Card.RANK[humanCards[i].rank]
[0]+Card.SUIT[humanCards[i].suit][0]+".gif").ConvertToBitmap()
if humanCards[i].inverted:
dc.SetLogicalFunction(wx.SRC_INVERT)
else:
dc.SetLogicalFunction(wx.COPY)
dc.DrawBitmap(cardImage, humanCards[i].position[0],
humanCards[i].position[1])
def DrawComputerCards(self, dc, computerCards):
if computerCards:
for i in range(len(computerCards)):
if not computerCards[i].showFace:
dc.DrawBitmap(self.backimage, computerCards[i].position[0],
computerCards[i].position[1])
else:
cardImage = wx.Image("cards/"+Card.RANK[computerCards[i].rank]
[0]+Card.SUIT[computerCards[i].suit][0]+".gif").ConvertToBitmap()
dc.DrawBitmap(cardImage, computerCards[i].position[0],
computerCards[i].position[1])
def DrawDeck(self, dc, top=None):
#draw deck
#print self.data.deckSize
if self.parent.deck.deck:
if top:
self.top = top
startdeck = (self.size[0]*.24, self.size[1]*.4)
if self.data.deckSize >= 6:
for x in range(5):
dc.DrawBitmap(self.backimage, startdeck[0]+x*2, startdeck[1])
else:
for x in range(self.data.deckSize-1):
dc.DrawBitmap(self.backimage, startdeck[0]+x*2, startdeck[1])
face = wx.Image("cards/"+Card.RANK[self.parent.top.rank]
[0]+Card.SUIT[self.parent.top.suit][0]+".gif").ConvertToBitmap()
dc.DrawBitmap(face, startdeck[0]+5*2, startdeck[1])
class MainWindow(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="German Whist", size=(640,480))
self.size = self.GetClientSizeTuple()
self.SetMaxSize(self.size)
self.SetMinSize(self.size)
self.statusbar = self.CreateStatusBar()
menuBar = wx.MenuBar()
menu = wx.Menu()
new = menu.Append(-1, "&New", "Start a new game")
exit = menu.Append(-1, "E&xit", "Exit the game")
menuBar.Append(menu, "&File")
self.SetMenuBar(menuBar)
self.Bind(wx.EVT_MENU, self.OnExit, exit)
self.Bind(wx.EVT_MENU, self.newGame, new)
self.init_all()
def init_all(self):
self.trumpPlayed = False
self.first = True
self.lead = None
self.Hcard = None
self.Ccard = None
self.Hwin = None
self.Cwin = None
self.storeHposition = None
self.storeCposition = None
self.deck = Deck()
self.human = Player(self.trumpPlayed)
self.computer = ComputerPlayer(self.trumpPlayed)
self.turn = "human"
self.statusbar.SetStatusText("Your turn")
self.Draw = CardGraphics(self)
self.deal()
self.Draw.dealt = True
self.trump = self.top = self.deck.turnTop()
self.computer.hand.organize(self.trump)
self.human.hand.organize(self.trump)
self.Draw.updatePos("human")
self.Draw.updatePos("computer")
self.Draw.data.deckSize = len(self.deck.deck) + 1
dc = wx.BufferedDC(wx.ClientDC(self.Draw), self.Draw.buffer)
self.Draw.DrawEverything(dc)
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
self.timer.Start(1000)
def newGame(self, evt):
#self.deck = None
#self.human = None
#self.computer = None
#self.Draw.buffer = None
#self.Draw = None
self.init_all()
def OnExit(self, evt):
self.Close()
def OnTimer(self, evt):
if self.turn != "human" and not self.Ccard:
self.Ccard = self.computer.selectCard(self.lead, self.trump,
self.top)
for i, x in enumerate(self.computer.memory.usedCards):
if x.name == self.Ccard.name:
del self.computer.memory.pickedUp[i]
for i, c in enumerate(self.computer.hand.cards):
#having problems here?
#that's because the card is being removed from the computer hand
#to fix it, don't remove it from the computer hand until after
if c.name == self.Ccard.name:
#wx.MessageBox("It's a tie.", "Game outcome", wx.OK)
c.showFace = True
if self.first:
self.storeCposition = c.position
self.computer.hand.cards[i].position = ((self.Draw.size[0] +
self.computer.hand.cards[i].size[0])/2.5 + 40, self.Draw.size[1]*.4)
dc = wx.BufferedDC(wx.ClientDC(self.Draw), self.Draw.buffer)
self.Draw.DrawEverything(dc)
else:
self.lead = self.Ccard
self.storeCposition = c.position
self.computer.hand.cards[i].position = ((self.Draw.size[0] +
self.computer.hand.cards[i].size[0])/2.5, self.Draw.size[1]*.4)
self.turn = "human"
self.statusbar.SetStatusText("Your turn")
dc = wx.BufferedDC(wx.ClientDC(self.Draw), self.Draw.buffer)
self.Draw.DrawEverything(dc)
elif self.Ccard and self.Hcard:
self.lead = None
if self.Hcard.suit == self.Ccard.suit: #same suit
if self.Ccard.rank > self.Hcard.rank: #higher card wins
self.Cwin = True
self.Hwin = False
else:
self.Cwin = False
self.Hwin = True
elif self.first:
if self.Hcard.suit != self.trump.suit: #p1 did not trump, p0
wins regardless
self.Cwin = True
self.Hwin = False
else:
self.Cwin = False
self.Hwin = True
elif not self.first:
if self.Ccard.suit != self.trump.suit: #p1 did not trump, p0
wins regardless
self.Cwin = False
self.Hwin = True
else:
self.Cwin = True
self.Hwin = False
if self.Cwin:
#wx.MessageBox(self.Ccard.name+", "+self.Hcard.name+": computer is
best", "Game outcome", wx.OK)
self.first = False
self.turn = "computer"
self.statusbar.SetStatusText("")
if not self.top:
self.computer.wonTrick()
else:
self.computer.receiveCard(self.top)
self.computer.hand.cards[-1].position = self.storeCposition
self.computer.memory.addpickedUp(self.top)
self.human.receiveCard(self.deck.draw())
self.human.hand.cards[-1].position = self.storeHposition
elif self.Hwin:
#wx.MessageBox(self.Ccard.name+", "+self.Hcard.name+": you are
best", "Game outcome", wx.OK)
self.first = True
self.turn = "human"
self.statusbar.SetStatusText("Your turn")
if not self.top:
self.human.wonTrick()
else:
self.human.receiveCard(self.top)
self.human.hand.cards[-1].position = self.storeHposition
self.computer.receiveCard(self.deck.draw())
self.computer.hand.cards[-1].position = self.storeCposition
self.computer.hand.cards[-1].showFace = False
self.computer.hand.remove(self.Ccard.name)
self.human.hand.remove(self.Hcard.name)
self.computer.memory.addDiscarded(self.Ccard)
self.computer.memory.addDiscarded(self.Hcard)
self.Cwin = None
self.Hwin = None
self.Ccard = None
self.Hcard = None
self.human.hand.organize(self.trump)
self.computer.hand.organize(self.trump)
self.Draw.updatePos("human")
self.Draw.updatePos("computer")
if self.deck.deck:
self.top = self.deck.turnTop()
self.Draw.data.deckSize = len(self.deck.deck) + 1
else:
self.statusbar.SetStatusText(self.statusbar.GetStatusText() + ": "
+ "Playing for the trick")
dc = wx.BufferedDC(wx.ClientDC(self.Draw), self.Draw.buffer)
self.Draw.DrawEverything(dc)
if not self.human.hand.cards and not self.computer.hand.cards:
if self.human.tricks > self.computer.tricks:
wx.MessageBox("You win.", "Game outcome", wx.OK)
elif self.computer.tricks > self.human.tricks:
wx.MessageBox("Computer wins.", "Game outcome", wx.OK)
else:
wx.MessageBox("It's a tie.", "Game outcome", wx.OK)
self.statusbar.SetStatusText("Game completed")
self.timer.Stop()
def deal(self):
self.deck.shuffle()
for i in range(13): #each player gets 13 cards
self.human.receiveCard(self.deck.draw())
self.Draw.data.amountCardshuman = len(self.human.hand.cards)
self.human.hand.cards[i].position =
(self.Draw.data.humanbeginPos[0] + i*self.Draw.data.overlapSpace,
self.Draw.data.humanbeginPos[1])
self.computer.receiveCard(self.deck.draw())
self.Draw.data.amountCardscomputer = len(self.computer.hand.cards)
self.computer.hand.cards[i].position =
(self.Draw.data.computerbeginPos[0] + i*self.Draw.data.overlapSpace,
self.Draw.data.computerbeginPos[1])
self.computer.hand.cards[i].showFace = False
if __name__== "__main__":
app = wx.PySimpleApp()
frame = MainWindow()
frame.Show()
app.MainLoop()
#------------------------------------------------------------------------------
Maybe there's another way to handle this, but I can't think of
anything...