[Tutor] GoFish
Russell Bungay
rab121@york.ac.uk
Sat, 11 May 2002 17:06:36 +0100
Hello Again,
As promised here is my code. It is arranged in four modules:
gofish.py: the main program module
cards.py: the module defining a pack of cards class
players.py: the module defining the player classes for humans and AI
players
bmdutils.py: my general purpose module for useful functions (only the
used code is included)
I believe I have used code that will only work under Python 2.2. There
is also a very little windows specific code (os.system('cls')).
#
#gofish.py
#
import bmdutils,cards,ConfigParser,os,os.path,players,sys
gofishdir = os.path.dirname(players.__file__) # Get directory of
module
class GoFish:
def __init__(self):
self.fishers = {}
self.deck =[]
self.out = []
if not os.path.exists(gofishdir + '\\gofishini'):
self.createini()
gofishinifile = open(gofishdir + '\\gofishini', 'rw')
self.ini = ConfigParser.ConfigParser()
self.ini.readfp(gofishinifile)
else:
gofishinifile = open(gofishdir + '\\gofishini', 'rw')
self.ini = ConfigParser.ConfigParser()
self.ini.readfp(gofishinifile)
bmdutils.bmdmenu([['1. Start a New game', self.new,
['1','n','N']],['2. Edit your Preferences', self.pref, ['2','p','P']],
['3. Quit this program', self.quit, ['3','q','Q']]])
def new(self):
default = 'Default Options:\n'
for a in range(self.ini.getint('default','ai')): # Create
string showing default options
default = default + self.ini.get('ai', str(a + 1)) + ' (' +
self.ini.get('ai' , 'levels')[a] + ') '
bmdutils.bmdmenu([['1. Start with Default options',
self.create, ['1','d','D']],['2. Start with New options',
self.createopt, ['2','n','N']],[default,None,[]]]) # Third option
prints default options with no possible selection
def create(self, options=None):
hum = 0
if not options:
options = []
for opt in range(self.ini.getint('default','ai')):
options.append([self.ini.get('ai','levels')[opt],self.ini.get('ai',
str(opt + 1))])
if self.ini.getint('default', 'human') != 0:
options.append([0,self.ini.get('default', 'name')])
for p in range(len(options)):
if options[p][0] == 0:
self.fishers[p] = players.Human(options[p][1])
hum = p
else:
level = 'AI' + str(options[p][0])
self.fishers[p] = eval('players.' + level +
'(options[p][1])')
newcards = cards.bmdcard()
hands =
newcards.deal(hands=[[len(self.fishers),self.ini.getint('default','cards')]],
shuffles=self.ini.getint('prefs','shuffles'))
for k in range(len(self.fishers)):
for c in hands[k]:
self.fishers[self.fishers.keys()[k]].receivecard(c)
hands= hands[-1:]
self.deck = hands[0]
os.system('cls')
self.mainloop(1,hum)
def createopt(self):
print 'opt'
def mainloop(self,start,human):
fish = start
num = len(self.fishers)
while len(self.fishers[human].hand) > 0:
if fish not in self.out:
fish = self.turn(fish,human)
elif len(self.out) == len(self.fishers) - 1:
print 'cheese'
else:
for f in self.fishers:
if f not in self.out:
fish = f
fish = self.turn(fish,human)
for p in self.fishers:
if len(self.fishers[p].hand) == 0 and p not in
self.out:
print 'Well done ' + self.fishers[p].name + '
you finished in place number ' + str(len(self.out) + 1)
self.out.append(p)
raw_input()
self.quit()
def turn(self, fish, human):
interface = 'You have: '
for card in self.fishers[human].hand:
interface += self.numtocard(card) + ' '
interface += '\n'
interface += 'You have declared: '
for rank in self.fishers[human].declared:
interface += str(rank + 1) + ' '
interface += '\n\n'
for player in self.fishers:
if self.fishers[player] != self.fishers[human]:
interface += self.fishers[player].name + ' has ' +
str(len(self.fishers[player].hand)) + ' cards remaining, and has
declared: '
for rank in self.fishers[player].declared:
interface += str(rank + 1) + ' '
interface += '\n'
interface += '\nThere are ' + str(len(self.deck)) + ' cards in
the deck. \n'
if fish != human:
print interface
#for t in self.fishers:
# print self.fishers[t].name, self.fishers[t].hand
play = 0,fish
while play[1] == fish or play[1] in self.out:
play = self.fishers[fish].askcard(len(self.fishers))
print self.fishers[fish].name + ' has asked ' +
self.fishers[play[1]].name + ' for a ' + str(play[0] + 1)
for p in (play[0]*4, play[0]*4 + 1, play[0]*4 + 2, play[0]*4
+ 3):
if p in self.fishers[play[1]].hand:
print self.fishers[play[1]].name + ' has given ' +
self.fishers[fish].name + ' a ' + str(play[0] + 1)
self.fishers[fish].receivecard(p)
self.fishers[play[1]].removecard(p)
for player in self.fishers:
if 'update' in dir(player):
player.update()
raw_input()
os.system('cls')
return fish
if len(self.deck) != 0:
self.fishers[fish].receivecard(self.deck[0])
self.deck = self.deck[1:]
print 'GO FISH'
raw_input()
os.system('cls')
return play[1]
else:
interface += '\nAsk for a card from:'
for player in self.fishers:
interface += '\n'
if self.fishers[player] != self.fishers[human]:
interface += str(player + 1) + '. ' +
self.fishers[player].name + ' '
interface += '\nDeclare a rank.\n'
interface += 'Quit the game.\n'
print interface
choice = ''
choices = ['d','D','q','Q']
for i in range(len(self.fishers) - 1):
choices.append(str(i + 1))
while choice not in choices:
choice = raw_input('Please choose an option: ')
if choice == 'd' or choice == 'D':
print declare
elif choice == 'q' or choice == 'Q':
if raw_input('Are you sure? y/n') == 'y' or
raw_input('Are you sure? y/n') == 'Y': self.quit()
else:
askfor = int(raw_input('Which rank do you wish to ask
for?')) - 1
for a in (askfor*4, askfor*4 + 1, askfor*4 + 2, askfor*4
+ 3):
if a in self.fishers[int(choice) - 1].hand:
print self.fishers[int(choice) - 1].name + ' has
given you a ' + str(askfor + 1)
self.fishers[fish].receivecard(a)
self.fishers[int(choice) - 1].removecard(a)
for player in self.fishers:
if 'update' in dir(player):
player.update()
raw_input()
os.system('cls')
return fish
if len(self.deck) != 0:
self.fishers[fish].receivecard(self.deck[0])
self.deck = self.deck[1:]
print 'GO FISH'
raw_input()
os.system('cls')
return int(choice) - 1
def pref(self):
print 'pref'
def quit(self):
sys.exit()
def createini(self):
gofishinifile = open(gofishdir + '\\gofishini', 'w')
self.ini = ConfigParser.ConfigParser()
self.ini.add_section('prefs')
self.ini.set('prefs', 'sort', 0)
self.ini.set('prefs', 'disp_actions', 1)
self.ini.set('prefs', 'auto_dec', 0)
self.ini.set('prefs', 'shuffles', 10)
self.ini.add_section('default')
self.ini.set('default', 'ai', 3)
self.ini.set('default', 'human', 1)
self.ini.set('default', 'name', 'Player')
self.ini.set('default', 'cards', 7)
self.ini.add_section('ai')
self.ini.set('ai','levels','11111111')
names = {1: 'Amy', 2: 'Theresa', 3:'Russell', 4:'Matthew',
5:'Richard', 6:'Susannah', 7:'Julia', 8:'John'}
for num in names.keys():
self.ini.set('ai',str(num),names[num])
self.ini.write(gofishinifile)
gofishinifile.close()
def numtocard(self,num):
if num % 4 == 0: return str(num/4 + 1) + 'S'
elif (num - 1) % 4 == 0 : return str((num - 1)/4 + 1) + 'H'
elif (num - 2) % 4 == 0 : return str((num - 2)/4 + 1) + 'D'
elif (num - 3) % 4 == 0 : return str((num - 3)/4 + 1) + 'C'
if __name__ == '__main__':
newfish = GoFish()
#
#cards.py
#
class bmdcard:
def __init__(self, size=52, comp=None):
self.cards = []
self.deck = []
for c in range(size):
self.deck.append(c)
self.cards = self.deck
def deal(self, hands=[[4,7]], shuffles=3):
for s in range(shuffles):
self.shuffle()
dealt=[]
for h in hands:
for i in range(hands[hands.index(h)][0]):
dealt.append(self.cards[:hands[hands.index(h)][1]])
self.cards = self.cards[hands[hands.index(h)][1]:]
dealt.append(self.cards)
self.cards=self.deck
return dealt
def shuffle(self):
"""Orignal code by Bruce Sass, as provided on Python Tutor
Mailing list"""
import random
half = len(self.cards)/2
part1 = self.cards[:half]
part2 = self.cards[half:]
shuffled = []
mingrp = 1
maxgrp = 4
while part1 or part2:
if part1:
for i in range(random.randrange(mingrp, 1 + min(maxgrp,
len(part1)))):
shuffled.append(part1.pop())
if part2:
for i in range(random.randrange(mingrp, 1 + min(maxgrp,
len(part2)))):
shuffled.append(part2.pop())
self.cards = shuffled
#
#players.py
#
import random
class Player:
def __init__(self,name):
self.hand = []
self.count = [0]*13
self.name = name
self.declared = []
def removecard(self,card):
self.hand.remove(card)
self.count[card/4] += -1
def receivecard(self,card):
self.hand.append(card)
self.count[card/4] += 1
self.bookcheck()
def declare(self, rank):
self.declared.append(rank)
for c in (rank*4,rank*4 + 1,rank*4 + 2,rank*4 + 3):
self.removecard(c)
self.count[rank] = 0
def bookcheck(self):
if max(self.count) == 4:
self.declare(self.count.index(4))
class Human(Player):
def cheese(self):
print 'cheese'
class AI1(Player):
def askcard(self, players):
return self.count.index(max(self.count)), random.randrange(0,
players)
#
#bmdutils.py - part of
#
def bmdmenu(options, prompt='Please select an option:'):
choice = ''
choices = {}
for o in options:
print o[0]
for p in o[2]:
choices[p] = o[1]
while choice not in choices.keys():
choice = raw_input(prompt)
choices[choice]()
#
#end
#
Thankyou very much,
Russell
--
http://www.bigmaddrongo.com
President of York University Trampoline Club:
http://york.trampolining.net
Chair of The York Glee Singers:
http://www.gleesingers.co.uk