in python solve for fucntions playround and __str__ under class SolitaireGame fr
ID: 3751307 • Letter: I
Question
in python solve for fucntions playround and __str__ under class SolitaireGame from Deck import * from random import shuffle class SolitaireGame(object): """ a simple Solitaire Game: N cards are dealt face up on the table. If two cards have a matching rank, new cards are dealt face up on top of them. Dealing continues until the deck is empty, or no two stacks have matching ranks. The player wins if all the cards are dealt.""" def __init__(self, N): """Constructor pre: N is an integer, denotes the number of piles, s.t. 1 < N < 50 post: self.size is the number of piles""" if N < 1 or N>50: raise ValueError self.size = N def newGame(self): """ Creates a new game post: creates an instance of Solitaire game with N empty places""" self.deck = Deck() # creating a deck of cards self.deck.shuffle() # shuffling them in place self.places = [self.deck.deal() for i in range(self.size)] # creating self.size(N) piles, with one card in each def playRound(self): """ a round of a game pre: all piles are not empty post: piles with same rank get new cards on top of them, returns True if successful, and False if no cards were placed into piles""" #find two piles (in self.places) with the cards with the same rank, # say at position i and j #deal new cards from the deck into piles i and j #return True #if piles with cards of the same rank were found, then return False def playGame(self): """ plays a Solitaire game post: returns True, if player wins, and False otherwise""" roundResult = True # initially, to enter the while loop's body while roundResult: roundResult = playRound() if roundResult == True: # all cards were dealt from the deck, success! return True else: # not all cards were dealt from the deck, the player lost return False def __str__(self): """ prints out the layout of top cards at the moment, in self.size(N) piles""" #Tests # just one presented s = SolitaireGame(10) result = s.playGame() if result == True: print("The player won!") else: print("The player lost.")
Explanation / Answer
import math
import random
from Tkinter import *
from Canvas import Rectangle, CanvasText, Group, Window
class Group(Group):
def bind(selfs, seq=None, cmd=None):
return selfs.canvas.tag_bind(selfs.id, seq, cmd)
width = 100
height = 150
MARGIN = 10
x_spacing = width + 2*MARGIN
y_spacing = height + 4*MARGIN
OFFSET = 5
BACKGROUND = '#070'
HEART = 'Heart'
DIAMOND = 'Diamond'
CLUBS = 'Club'
SPADE = 'Spade'
RED = 'red'
BLACK = 'black'
colors = {}
for s in (HEART, DIAMOND):
colors[s] = RED
for s in (CLUB, SPADE):
colors[s] = BLACK
all_Suits = colors.keys()
NSUITS = len(all_Suits)
ACE = 1
JACK = 11
QUEEN = 12
KING = 13
ALLVALUES = range(1, 14) # (one more than the highest value)
NVALUES = len(ALLVALUES)
VALNAMES = ["", "A"] + map(str, range(2, 11)) + ["J", "Q", "K"]
NROWS = 7
class Card:
def __init__(selfs, suits, val, canvs):
selfs.suits = suits
selfs.val = val
selfs.colors = colors[suits]
selfs.face_shown = 0
selfs.x = selfs.y = 0
selfs.group = Group(canvs)
text = "%s %s" % (VALNAMES[val], suits)
selfs.__text = CanvasText(canvs, width//2, 0,
anchor=N, fill=selfs.colors, text=text)
selfs.group.addtag_withtag(selfs.__text)
selfs.__rect = Rectangle(canvs, 0, 0, width, height,
outline='black', fill='white')
selfs.group.addtag_withtag(selfs.__rect)
selfs.__back = Rectangle(canvs, MARGIN, MARGIN,
width-MARGIN, height-MARGIN,
outline='black', fill='blue')
selfs.group.addtag_withtag(selfs.__back)
def __repr__(selfs):
return "Card(%r, %r)" % (selfs.suits, selfs.val)
def moveto(selfs, x, y):
selfs.moveby(x - selfs.x, y - selfs.y)
def moveby(selfs, dx, dy):
selfs.x = selfs.x + dx
selfs.y = selfs.y + dy
selfs.group.move(dx, dy)
def tkraise(selfs):
selfs.group.tkraise()
def showface(selfs):
selfs.tkraise()
selfs.__rect.tkraise()
selfs.__text.tkraise()
selfs.face_shown = 1
def showback(selfs):
selfs.tkraise()
selfs.__rect.tkraise()
selfs.__back.tkraise()
selfs.face_shown = 0
class Stack:
def __init__(selfs, x, y, games=None):
selfs.x = x
selfs.y = y
selfs.games = games
selfs.cardss = []
selfs.group = Group(selfs.games.canvs)
selfs.group.bind('<1>', selfs.clickhandler)
selfs.group.bind('<Double-1>', selfs.doubleclickhandler)
selfs.group.bind('<B1-Motion>', selfs.motionhandler)
selfs.group.bind('<ButtonRelease-1>', selfs.releasehandler)
selfs.makebottom()
def makebottom(selfs):
pass
def __repr__(selfs):
return "%s(%d, %d)" % (selfs.__class__.__name__, selfs.x, selfs.y)
def add(selfs, card):
selfs.cardss.append(card)
card.tkraise()
selfs.position(card)
selfs.group.addtag_withtag(card.group)
def delete(selfs, card):
selfs.cardss.remove(card)
card.group.dtag(selfs.group)
def showtop(selfs):
if selfs.cardss:
selfs.cardss[-1].showface()
def deal(selfs):
if not selfs.cardss:
return None
card = selfs.cardss[-1]
selfs.delete(card)
return card
def position(selfs, card):
card.moveto(selfs.x, selfs.y)
def userclickhandler(selfs):
selfs.showtop()
def userdoubleclickhandler(selfs):
selfs.userclickhandler()
def usermovehandler(selfs, cardss):
for card in cardss:
selfs.position(card)
def clickhandler(selfs, events):
selfs.finishmoving() # In case we lost an events
selfs.userclickhandler()
selfs.startmoving(events)
def motionhandler(selfs, events):
selfs.keepmoving(events)
def releasehandler(selfs, events):
selfs.keepmoving(events)
selfs.finishmoving()
def doubleclickhandler(selfs, events):
selfs.finishmoving() # In case we lost an events
selfs.userdoubleclickhandler()
selfs.startmoving(events)
moving = None
def startmoving(selfs, events):
selfs.moving = None
tags = selfs.games.canvs.gettags('current')
for i in range(len(selfs.cardss)):
card = selfs.cardss[i]
if card.group.tag in tags:
break
else:
return
if not card.face_shown:
return
selfs.moving = selfs.cardss[i:]
selfs.lastx = events.x
selfs.lasty = events.y
for card in selfs.moving:
card.tkraise()
def keepmoving(selfs, events):
if not selfs.moving:
return
dx = events.x - selfs.lastx
dy = events.y - selfs.lasty
selfs.lastx = events.x
selfs.lasty = events.y
if dx or dy:
for card in selfs.moving:
card.moveby(dx, dy)
def finishmoving(selfs):
cardss = selfs.moving
selfs.moving = None
if cardss:
selfs.usermovehandler(cardss)
class Deck(Stack):
def makebottom(selfs):
bottom = Rectangle(selfs.games.canvs,
selfs.x, selfs.y,
selfs.x+width, selfs.y+height,
outline='black', fill=BACKGROUND)
selfs.group.addtag_withtag(bottom)
def fill(selfs):
for suits in all_Suits:
for val in ALLVALUES:
selfs.add(Card(suits, val, selfs.games.canvs))
def shuffle(selfs):
n = len(selfs.cardss)
newcards = []
for i in randperm(n):
newcards.append(selfs.cardss[i])
selfs.cardss = newcards
def userclickhandler(selfs):
opendeck = selfs.games.opendeck
card = selfs.deal()
if not card:
while 1:
card = opendeck.deal()
if not card:
break
selfs.add(card)
card.showback()
else:
selfs.games.opendeck.add(card)
card.showface()
def randperm(n):
r = range(n)
x = []
while r:
i = random.choice(r)
x.append(i)
r.remove(i)
return x
class OpenStack(Stack):
def acceptable(selfs, cardss):
return 0
def usermovehandler(selfs, cardss):
card = cardss[0]
stack = selfs.games.closeststack(card)
if not stack or stack is selfs or not stack.acceptable(cardss):
Stack.usermovehandler(selfs, cardss)
else:
for card in cardss:
selfs.delete(card)
stack.add(card)
selfs.games.wincheck()
def userdoubleclickhandler(selfs):
if not selfs.cardss:
return
card = selfs.cardss[-1]
if not card.face_shown:
selfs.userclickhandler()
return
for s in selfs.games.suits:
if s.acceptable([card]):
selfs.delete(card)
s.add(card)
selfs.games.wincheck()
break
class SuitStack(OpenStack):
def makebottom(selfs):
bottom = Rectangle(selfs.games.canvs,
selfs.x, selfs.y,
selfs.x+width, selfs.y+height,
outline='black', fill='')
def userclickhandler(selfs):
pass
def userdoubleclickhandler(selfs):
pass
def acceptable(selfs, cardss):
if len(cardss) != 1:
return 0
card = cardss[0]
if not selfs.cardss:
return card.val == ACE
topcard = selfs.cardss[-1]
return card.suits == topcard.suits and card.val == topcard.val + 1
class RowStack(OpenStack):
def acceptable(selfs, cardss):
card = cardss[0]
if not selfs.cardss:
return card.val == KING
topcard = selfs.cardss[-1]
if not topcard.face_shown:
return 0
return card.colors != topcard.colors and card.val == topcard.val - 1
def position(selfs, card):
y = selfs.y
for c in selfs.cardss:
if c == card:
break
if c.face_shown:
y = y + 2*MARGIN
else:
y = y + OFFSET
card.moveto(selfs.x, y)
class Solitaire:
def __init__(selfs, master):
selfs.master = master
selfs.canvs = canvs(selfs.master,
background=BACKGROUND,
highlightthickness=0,
width=NROWS*x_spacing,
height=3*y_spacing + 20 + MARGIN)
selfs.canvs.pack(fill=BOTH, expand=TRUE)
selfs.dealbutton = Button(selfs.canvs,
text="Deal",
highlightthickness=0,
background=BACKGROUND,
activebackground="green",
cmd=selfs.deal)
Window(selfs.canvs, MARGIN, 3*y_spacing + 20,
window=selfs.dealbutton, anchor=SW)
x = MARGIN
y = MARGIN
selfs.deck = Deck(x, y, selfs)
x = x + x_spacing
selfs.opendeck = OpenStack(x, y, selfs)
x = x + x_spacing
selfs.suits = []
for i in range(NSUITS):
x = x + x_spacing
selfs.suits.append(SuitStack(x, y, selfs))
x = MARGIN
y = y + y_spacing
selfs.rows = []
for i in range(NROWS):
selfs.rows.append(RowStack(x, y, selfs))
x = x + x_spacing
selfs.openstacks = [selfs.opendeck] + selfs.suits + selfs.rows
selfs.deck.fill()
selfs.deal()
def wincheck(selfs):
for s in selfs.suits:
if len(s.cardss) != NVALUES:
return
selfs.win()
selfs.deal()
def win(selfs):
"""Stupid animation when you win."""
cardss = []
for s in selfs.openstacks:
cardss = cardss + s.cardss
while cardss:
card = random.choice(cardss)
cardss.remove(card)
selfs.animatedmoveto(card, selfs.deck)
def animatedmoveto(selfs, card, dest):
for i in range(10, 0, -1):
dx, dy = (dest.x-card.x)//i, (dest.y-card.y)//i
card.moveby(dx, dy)
selfs.master.update_idletasks()
def closeststack(selfs, card):
closest = None
cdist = 999999999
for stack in selfs.openstacks:
dist = (stack.x - card.x)**2 + (stack.y - card.y)**2
if dist < cdist:
closest = stack
cdist = dist
return closest
def deal(selfs):
selfs.reset()
selfs.deck.shuffle()
for i in range(NROWS):
for r in selfs.rows[i:]:
card = selfs.deck.deal()
r.add(card)
for r in selfs.rows:
r.showtop()
def reset(selfs):
for stack in selfs.openstacks:
while 1:
card = stack.deal()
if not card:
break
selfs.deck.add(card)
card.showback()
# Main function, run when invoked as a stand-alone Python program.
def main():
root = Tk()
games = Solitaire(root)
root.protocol('WM_DELETE_WINDOW', root.quit)
root.mainloop()
if __name__ == '__main__':
main()
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.