Beispiel #1
0
    def __init__(self, master, p1, p2):
        self.HOLEW = 100 #width of hole
        self.HEIGHT = 250 #height of hole
        self.BOARDW = 500 #width of board
        self.PAD = 2 #padding between each hole
        self.game = MancalaBoard() #call Mancala Board class

        self.p1 = p1 #player 1
        self.p2 = p2 #player 2

        self.BINW = self.BOARDW / self.game.NHOLES #get the width of the board to fill the hole NHOLES=6

        self.turn = p1 #current player is player 1
        self.wait = p2 #player 2 has to wait
        self.root = master #root = Tk() open window

        frame = Frame(master,bg='light goldenrod yellow') #open frame
        frame.pack() #pack frame

        # Create the board
        self.makeBoard( frame ) #makeBoard function takes frame as argument

        displayStr = "Let's play Mancala!" #string

        # w = Label(master, option, ...)
        # master-parent window
        # option-list of commonly used option--text
        # self.frame is parent window
        self.status = Label(frame, text=displayStr,bg='light goldenrod yellow',fg='rosybrown4')  #display one or more lines of text that cannot be modified by the user
        self.status.config(font=('Jokerman', 18,'bold'))
        self.status.pack(side=BOTTOM) #show text in status
Beispiel #2
0
    def __init__(self, master, p1, p2, enableGUI):
        self.CUPW = 75
        self.HEIGHT = 200
        self.BOARDW = 400
        self.PAD = 0
        self.game = MancalaBoard()
        self.p1 = p1
        self.p2 = p2
        self.BINW = self.BOARDW / self.game.NCUPS

        self.turn = p1
        self.wait = p2
        self.root = master
        self.GUI = enableGUI
        frame = Frame(master)
        frame.pack()

        # Create the board
        self.makeBoard(frame)

        displayStr = "Welcome to Mancala"

        self.status = Label(frame, text=displayStr)
        self.status.pack(side=BOTTOM)
        self.won = Player(-1, 0, 0)
Beispiel #3
0
    def __init__(self, p1, p2):
        self.game = MancalaBoard()
        self.p1 = p1
        self.p2 = p2

        self.turn = p1
        self.wait = p2
Beispiel #4
0
 def __init__(self, playerNum, playerType, ply=0):
     """Initialize a Player with a playerNum (1 or 2), playerType (one of
     the constants such as HUMAN), and a ply (default is 0)."""
     from MancalaBoard import *
     self.prev_board = MancalaBoard()
     self.num = playerNum
     self.opp = 2 - playerNum + 1
     self.type = playerType
     self.ply = ply
Beispiel #5
0
    def __init__(self, master, p1, p2):
        self.CUPW = 75
        self.HEIGHT = 200
        self.BOARDW = 400
        self.PAD = 0
        self.game = MancalaBoard()
        self.p1 = p1
        self.p2 = p2
        self.BINW = self.BOARDW / self.game.NCUPS

        self.turn = p1
        self.wait = p2
        self.root = master
        
        frame = Frame(master)
        frame.pack()

        # Create the board
        self.makeBoard( frame )
        
        displayStr = "Welcome to Mancala"
            
        self.status = Label(frame, text=displayStr)
        self.status.pack(side=BOTTOM)
Beispiel #6
0
class MancalaTest:
    def __init__(self, p1, p2):
        self.game = MancalaBoard()
        self.p1 = p1
        self.p2 = p2

        self.turn = p1
        self.wait = p2
    def newgame(self):
        """ Start a new game between the players """
        self.game.reset()
        self.turn = self.p1
        self.wait = self.p2
        s = "Player " + str(self.turn) + "'s turn"
        if self.turn.type != Player.HUMAN:
            s += " Please wait..."
        self.continueGame()
    def continueGame( self ):
        """ Find out what to do next.  If the game is over, report who
            won.  If it's a human player's turn, enable the board for
            a click.  If it's a computer player's turn, choose the next move."""
        if self.game.gameOver():
            if self.game.hasWon(self.p1.num):
                print "Player " + str(self.p1) + " wins"
            elif self.game.hasWon(self.p2.num):
                print "Player " + str(self.p2) + " wins"
            else:
                print "Tie game"
            return
        else:
            move = self.turn.chooseMove( self.game )
            playAgain = self.game.makeMove( self.turn, move )
            if not playAgain:
                self.swapTurns()
            self.continueGame()

    def swapTurns( self ):
        """ Change whose turn it is"""
        temp = self.turn
        self.turn = self.wait
        self.wait = temp
Beispiel #7
0
class MancalaWindow:
    """# A very simple GUI for playing the game of Mancala."""

    def __init__(self, master, p1, p2):
        self.CUPW = 75
        self.HEIGHT = 200
        self.BOARDW = 400
        self.PAD = 0
        self.game = MancalaBoard()
        self.p1 = p1
        self.p2 = p2
        self.BINW = self.BOARDW / self.game.NCUPS

        self.turn = p1
        self.wait = p2
        self.root = master
        
        frame = Frame(master)
        frame.pack()

        # Create the board
        self.makeBoard( frame )
        
        displayStr = "Welcome to Mancala"
            
        self.status = Label(frame, text=displayStr)
        self.status.pack(side=BOTTOM)
        
    def enableBoard(self):
        """ Allow a human player to make moves by clicking"""
        for i in [0, 1]:
            for j in range(self.game.NCUPS):
                self.cups[i][j].bind("<Button-1>", self.callback)

    def disableBoard(self):
        """ Prevent the human player from clicking while the computer thinks"""
        for i in [0, 1]:
            for j in range(self.game.NCUPS):
                self.cups[i][j].unbind("<Button-1>")

    def makeBoard( self, frame ):
        """ Create the board """
        boardFrame = Frame(frame)
        boardFrame.pack(side=TOP)

        self.button = Button(frame, text="Start New Game", command=self.newgame)
        self.button.pack(side=BOTTOM)

        gamef = Frame(boardFrame)
        topRow = Frame(gamef)
        bottomRow = Frame(gamef)
        topRow.pack(side=TOP)
        bottomRow.pack(side=TOP)
        tmpCups = []
        tmpCups2 = []

        binW = self.BOARDW/self.game.NCUPS
        binH = self.HEIGHT/2

        for i in range(self.game.NCUPS):
            c = Canvas(bottomRow, width=binW, height=binH)
            c.pack(side=LEFT)
            tmpCups += [c]
            c = Canvas(topRow, width=binW, height=binH)
            c.pack(side=LEFT)
            tmpCups2 += [c]

        self.cups = [tmpCups, tmpCups2]
        self.p1cup = Canvas(boardFrame, width=self.CUPW, height=self.HEIGHT)
        self.p2cup = Canvas(boardFrame, width=self.CUPW, height=self.HEIGHT)

        self.p2cup.pack(side=LEFT)
        gamef.pack(side=LEFT)
        self.p1cup.pack(side=LEFT)

        self.drawBoard()


    def drawBoard( self ):
        """ Draw the board on the canvas """
        self.p2cup.create_oval(self.PAD, self.PAD, self.CUPW, 0.9*self.HEIGHT, width=2 )
        binW = self.BOARDW/self.game.NCUPS
        binH = self.HEIGHT/2
        for j in [0, 1]:
            for i in range(self.game.NCUPS):
                
                self.cups[j][i].create_rectangle(self.PAD, self.PAD, binW, binH)
        self.p1cup.create_oval(self.PAD, self.PAD+0.1*self.HEIGHT, self.CUPW, self.HEIGHT, width=2 )
        

    def newgame(self):
        """ Start a new game between the players """
        self.game.reset()
        self.turn = self.p1
        self.wait = self.p2
        s = "Player " + str(self.turn) + "'s turn"
        if self.turn.type != Player.HUMAN:
            s += " Please wait..."
        self.status['text'] = s
        self.resetStones()
        self.continueGame()

    # Board must be disabled to call continueGame
    def continueGame( self ):
        """ Find out what to do next.  If the game is over, report who
            won.  If it's a human player's turn, enable the board for
            a click.  If it's a computer player's turn, choose the next move."""
        self.root.update()
        if self.game.gameOver():
            if self.game.hasWon(self.p1.num):
                self.status['text'] = "Player " + str(self.p1) + " wins"
            elif self.game.hasWon(self.p2.num):
                self.status['text'] = "Player " + str(self.p2) + " wins"
            else:
                self.status['text'] = "Tie game"
            return
        if self.turn.type == Player.HUMAN:
            self.enableBoard()
        else:
            move = self.turn.chooseMove( self.game )
            playAgain = self.game.makeMove( self.turn, move )
            if not playAgain:
                self.swapTurns()
            self.resetStones()
            self.continueGame()

    def swapTurns( self ):
        """ Change whose turn it is"""
        temp = self.turn
        self.turn = self.wait
        self.wait = temp
        statusstr = "Player " + str(self.turn) + "\'s turn "
        if self.turn.type != Player.HUMAN:
            statusstr += "Please wait..."
        self.status['text'] = statusstr
        
        
    def resetStones(self):
        """ Clear the stones and redraw them """
        # Put the stones in the cups
        for i in range(len(self.game.P2Cups)):
            index = (len(self.game.P2Cups)-i)-1
            self.clearCup(self.cups[1][index])
            # put the number of stones at the top of the canvas
            self.cups[1][index].create_text(self.BINW/2, 0.05*self.HEIGHT, text=str(self.game.P2Cups[i]), tag="num")
        for i in range(len(self.game.P1Cups)):
            # put the number of stones at the bottom of the canvas
            self.clearCup(self.cups[0][i])
            self.cups[0][i].create_text(self.BINW/2, 0.05*self.HEIGHT, text=str(self.game.P1Cups[i]), tag="num")
        self.clearCup(self.p1cup)
        self.clearCup(self.p2cup)
        self.p2cup.create_text(self.CUPW/2, 10, text=str(self.game.scoreCups[1]), tag="num")
        self.p1cup.create_text(self.CUPW/2, 10+0.1*self.HEIGHT, text=str(self.game.scoreCups[0]), tag="num")
        
    
    def clearCup( self, cup ):
        """ Clear the stones in the given cup"""
        titems = cup.find_withtag("num")
        stones = cup.find_withtag("stone")
        cup.delete(titems)
        cup.delete(stones)
            

    def callback(self, event):
        """ Handle the human player's move"""
        # calculate which box the click was in
        moveAgain = True
        self.disableBoard()
        if self.turn.num == 1:
            for i in range(len(self.cups[0])):
                if self.cups[0][i] == event.widget:
                    if self.game.legalMove( self.turn, i+1 ):
                        moveAgain = self.game.makeMove( self.turn, i+1 )
                        if not moveAgain:
                            self.swapTurns()
                        self.resetStones()
        else:
            for i in range(len(self.cups[1])):
                if self.cups[1][i] == event.widget:
                    index = self.game.NCUPS - i
                    if self.game.legalMove( self.turn, index ):
                        moveAgain = self.game.makeMove( self.turn, index )
                        if not moveAgain:
                            self.swapTurns()
                        self.resetStones()
        if moveAgain:
            self.enableBoard()
        else:
            self.continueGame()
Beispiel #8
0
Datei: Test.py Projekt: jb08/AI
# from MancalaGUI import *
# player1 = MancalaPlayer(1,Player.MINIMAX, ply=5)
# player2 = MancalaPlayer(2,Player.MINIMAX,ply=5)
# startGame(player1,player2)

from dmw956 import *
from TicTacToe import *
from MancalaBoard import *

game = MancalaBoard()
p1 = dmw956(1, dmw956.CUSTOM)
p2 = Player(2, Player.ABPRUNE, ply=10)

# game.makeMove(p1, 3)
# game.makeMove(p1, 4)
# game.makeMove(p1, 6)
# game.makeMove(p2, 0)
# game.makeMove(p2, 2)
# game.makeMove(p2, 5)
#game.hostGame(p1,p2)

ABPRUNE_won = 0
Other_won = 0
tie = 0

for i in range(3):
	#print i

	game.reset()
	game.hostGame(p1,p2)
Beispiel #9
0
class MancalaWindow:
    """ GUI for playing Mancala"""

    def __init__(self, master, p1, p2):
        self.HOLEW = 100 #width of hole
        self.HEIGHT = 250 #height of hole
        self.BOARDW = 500 #width of board
        self.PAD = 2 #padding between each hole
        self.game = MancalaBoard() #call Mancala Board class

        self.p1 = p1 #player 1
        self.p2 = p2 #player 2

        self.BINW = self.BOARDW / self.game.NHOLES #get the width of the board to fill the hole NHOLES=6

        self.turn = p1 #current player is player 1
        self.wait = p2 #player 2 has to wait
        self.root = master #root = Tk() open window

        frame = Frame(master,bg='light goldenrod yellow') #open frame
        frame.pack() #pack frame

        # Create the board
        self.makeBoard( frame ) #makeBoard function takes frame as argument

        displayStr = "Let's play Mancala!" #string

        # w = Label(master, option, ...)
        # master-parent window
        # option-list of commonly used option--text
        # self.frame is parent window
        self.status = Label(frame, text=displayStr,bg='light goldenrod yellow',fg='rosybrown4')  #display one or more lines of text that cannot be modified by the user
        self.status.config(font=('Jokerman', 18,'bold'))
        self.status.pack(side=BOTTOM) #show text in status

    def enableBoard(self):
        """ Allow a human player to make moves by clicking"""
        for i in [0, 1]:#only allow 1 click
            for j in range(self.game.NHOLES):
                self.holes[i][j].bind("<Button-1>", self.callback)
                #bind for each hole-can click on each hole
                #use the bind method of the frame widget to bind a callback function to an event called <Button-1>
                #click in the window that appears

    def disableBoard(self):
        """ Prevent the human player from clicking while the computer thinks"""
        for i in [0, 1]:
            for j in range(self.game.NHOLES):
                self.holes[i][j].unbind("<Button-1>")#unbind/disable key once it's clicked

    def makeBoard( self, frame ):
        """ Create the board """
        boardFrame = Frame(frame)#frame = Frame(master,bg='lemon chiffon') #open frame
        boardFrame.pack(side=BOTTOM)

        self.button = Button(frame, text="Start The Game!", command=self.newgame,bg='lightsalmon2',fg='lemon chiffon') #self.newgame is function to start the game-AI first
        self.button.config(font=('Jokerman', 16))
        self.button.pack(side=TOP)

        gamef = Frame(boardFrame) #boardFrame = Frame(frame)
        topRow = Frame(gamef)
        bottomRow = Frame(gamef)
        topRow.pack(side=TOP)
        bottomRow.pack(side=TOP)

        #temporary list
        tmpHoles = []
        tmpHoles2 = []

        binW = self.BOARDW/self.game.NHOLES #width of each bin for the hole
        binH = self.HEIGHT/2 #height of each bin for the hole

        for i in range(self.game.NHOLES): #create canvas for each hole
            c = Canvas(bottomRow, width=binW, height=binH,bg='lightsalmon2')
            c.pack(side=LEFT)
            tmpHoles += [c] #store each hole canvas created for bottom row

            c = Canvas(topRow, width=binW, height=binH,bg='lightsalmon2')
            c.pack(side=LEFT)
            tmpHoles2 += [c]#store each hole canvas created for top row

        self.holes = [tmpHoles, tmpHoles2]#holes two row
        self.p1hole = Canvas(boardFrame, width=self.HOLEW, height=self.HEIGHT,bg='lightsalmon2')
        self.p2hole = Canvas(boardFrame, width=self.HOLEW, height=self.HEIGHT,bg='lightsalmon2')

        self.p2hole.pack(side=LEFT)
        gamef.pack(side=LEFT)
        self.p1hole.pack(side=LEFT)

        self.drawBoard()#function


    def drawBoard( self ):
        """ Draw the board on the canvas """
        #create oval for each hole

        self.p2hole.create_oval(self.PAD, 10*self.PAD, self.HOLEW, 0.9*self.HEIGHT, width=2,fill='lemon chiffon',outline='brown')#player 2 house

        binW = self.BOARDW/self.game.NHOLES
        binH = self.HEIGHT/2#height for hole

        for j in range(self.game.NHOLES):  # column # create oval for holes
            self.holes[0][j].create_oval(self.PAD, self.PAD, binW, binH, fill='lemon chiffon',outline='brown',activefill='peach puff') #bottom row
            self.holes[1][j].create_oval(self.PAD, self.PAD, binW, binH, fill='lemon chiffon', outline='brown') #top row

        self.p1hole.create_oval(self.PAD, 10*self.PAD, self.HOLEW, 0.9*self.HEIGHT, width=2,fill='lemon chiffon',outline='brown' )#player 1 house


    def newgame(self):
        """ Start a new game between the players """
        self.game.reset() #MancalaBoard.py def reset(self):
        self.turn = self.p1
        self.wait = self.p2

        s = "Player " + str(self.turn) + "'s turn"

        if self.turn.type != Player.HUMAN:
            s += " Please wait..."

        self.status['text'] = s #status-string of text-s store to status

        #replace Let's play Mancala
        self.resetStones()#function
        self.continueGame()#function

    # Board must be disabled to call continueGame
    def continueGame( self ):
        """ Continue the game to next step. Announce the winner or continue to next move: human to click or AI to choose move"""
        self.root.update() #root = Tk()

        #updates the dictionary with the elements from the another dictionary object or from an iterable of key/value pairs.
        #updates the key with the new value

        if self.game.gameOver():#function in MancalaBoard.py def gameOver(self):
            if self.game.hasWon(self.p1.num):#def hasWon(self, playerNum): #check P1 has won
                self.status['text'] = "Player " + str(self.p1) + " wins"
            elif self.game.hasWon(self.p2.num): #check P2 has won
                self.status['text'] = "Player " + str(self.p2) + " wins"
            else:
                self.status['text'] = "Tie game"
            return

        if self.turn.type == Player.HUMAN: #Player class in AI.py
            self.enableBoard() #human turn,enable click
        else: #AI turn
            move = self.turn.chooseMove( self.game )#class in AI.py self.game = MancalaBoard()
            playAgain = self.game.makeMove( self.turn, move ) #def makeMove(self, player, hole) in MancalaBoard.py
            if not playAgain:
                self.swapTurns()
            self.resetStones()#function
            self.continueGame()#function to continue to next step-game over or continue

    def swapTurns( self ):
        """ Change turn/wait"""
        temp = self.turn

        self.turn = self.wait
        self.wait = temp

        statusstr = "Player " + str(self.turn) + "\'s turn "

        if self.turn.type != Player.HUMAN: #not human turn display wait
            statusstr += "Please wait..."

        self.status['text'] = statusstr


    def resetStones(self):
        """ Clear the stones and redraw them """
        # Put the stones in the holes

        for i in range(len(self.game.P2Holes)):#self.P2Holes = [4] * self.NHOLES total 24 stone for 1 player
            index = (len(self.game.P2Holes)-i)-1#traverse the hole and minus each stone
            self.clearHole(self.holes[1][index])#clear hole function
            # display number of stones in each hole at top row
            self.holes[1][index].create_text(self.BINW/2, 0.25*self.HEIGHT, text=str(self.game.P2Holes[i]), tag="num",font='Jokerman')

        for i in range(len(self.game.P1Holes)):
            # display number of stones in each hole at bottom row
            self.clearHole(self.holes[0][i])
            self.holes[0][i].create_text(self.BINW/2, 0.25*self.HEIGHT, text=str(self.game.P1Holes[i]), tag="num",font='Jokerman')

        self.clearHole(self.p1hole)#clear hole for house of p1
        self.clearHole(self.p2hole)#clear hole for house of p1

        #clear hole then redisplay new number of stone

        self.p2hole.create_text(self.HOLEW/2, 0.5*self.HEIGHT, text=str(self.game.scoreHoles[1]), tag="num",font='Jokerman')
        self.p1hole.create_text(self.HOLEW/2, 0.5*self.HEIGHT, text=str(self.game.scoreHoles[0]), tag="num",font='Jokerman')


    def clearHole( self, hole ):
        """ Clear the stones in the given hole"""
        titems = hole.find_withtag("num") #"all canvas items presently having that tag"
        #find tag num in hole
        stones = hole.find_withtag("stone")
        hole.delete(titems)
        hole.delete(stones)


    def callback(self, event):
        """ Handle the human player's move"""
        # calculate which box the click was in
        moveAgain = True
        self.disableBoard()#disable click
        if self.turn.num == 1:
            for i in range(len(self.holes[0])):#length of bottom row of holes
                if self.holes[0][i] == event.widget: #widget generated by this event
                    if self.game.legalMove( self.turn, i+1 ):#allow to move to next hole
                        moveAgain = self.game.makeMove( self.turn, i+1 )#continue moving to i+1

                        if not moveAgain:#cannot move
                            self.swapTurns()#opponent turn
                        self.resetStones()#display latest number of stone
        else:#AI side

            for i in range(len(self.holes[1])):#length of top row of holes
                if self.holes[1][i] == event.widget:
                    index = self.game.NHOLES - i #eg 6=6-1 1 is the first box from left to right and is index 6 for AI

                    if self.game.legalMove( self.turn, index ):#allow to move to next hole
                        moveAgain = self.game.makeMove( self.turn, index )#continue moving

                        if not moveAgain:#cannot move
                            self.swapTurns()#opponent turn

                        self.resetStones()#display latest number of stone

        if moveAgain: #if can move again
            self.enableBoard()#enable click for huamn player

        else:
            self.continueGame()
Beispiel #10
0
# -*- coding: utf-8 -*-
"""
Created on Sun Apr 19 21:08:18 2015

@author: Peter
"""
from MancalaBoard import *

p1 = pbh423(1,Player.CUSTOM)
p2 = Player(2, Player.HUMAN)
mb = MancalaBoard()
mb.hostGame(p1, p2)
Beispiel #11
0
 def setUp(self):
     self.board = MancalaBoard.MancalaBoard()
     self.player1 = slv398.slv398(1, slv398.Player.MINIMAX, 3)
     self.player2 = slv398.slv398(2, slv398.Player.ABPRUNE, 3)
Beispiel #12
0
# only compare two players
me1 = MancalaPlayer(1, Player.ABPRUNE,3)
me2 = MancalaPlayer(1, Player.MINIMAX,3)
player1 = MancalaPlayer(2, Player.MINIMAX)
player2 = Player(2, Player.RANDOM)
player3 = Player(2, Player.MINIMAX)

#opponents = [player2, player3, player4]
mes = [me1, me2]
if logs:
    assert len(mes) == 2
    
opponents = [player1]


myBoard = MancalaBoard()

iterations = 100

filesDict = {}

for meNum, me in enumerate(mes):
        
    if report: print "***********************************************"
        
    if logs: sys.stdout = filesDict[meNum] = StringIO.StringIO()
        
    for oppNum, currentOpponent in enumerate(opponents):

        #reset the scores
        p1 = 0
def runGame(player_1, p1, player_2, p2, gamesWon):
    game = MancalaBoard.MancalaBoard()
    winner = game.hostGame(player_1, player_2)
    gamesWon[p1] += winner[0]
    gamesWon[p2] += winner[1]
    print time.strftime('%H:%M:%S') + ': Finished', p1, 'v', p2
Beispiel #14
0
                  slv398(2, createPlayerType(sys.argv[2])))
    else:
        print "usage: MancalaGUI.py <player_1_type> <player_2_type>"


def createPlayerType(playerType):
    """
    Converts a string representation of player type to an int representation
    :param playerType: player type string
    :return: player type int
    """
    playerTypeNoCase = playerType.lower()
    if playerTypeNoCase == 'human':
        return Player.HUMAN
    if playerTypeNoCase == 'minimax':
        return Player.MINIMAX
    if playerTypeNoCase == 'random':
        return Player.RANDOM
    if playerTypeNoCase == 'abprune':
        return Player.ABPRUNE
    if playerTypeNoCase == 'custom':
        return Player.CUSTOM


if __name__ == '__main__':
    # main()
    #p1 = slv398(1, Player.HUMAN)
    p1 = slv398(1, Player.CUSTOM, 20)
    p2 = slv398(2, Player.HUMAN)
    board = MancalaBoard()
    startGame(p1, p2)
Beispiel #15
0
import time

execfile("MancalaGUI.py")

# create mancala pllayers
me1 = MancalaPlayer(1, Player.ABPRUNE)
me2 = MancalaPlayer(1, Player.MINIMAX)
player1 = MancalaPlayer(2, Player.MINIMAX)
player2 = Player(2, Player.RANDOM)
player3 = Player(2, Player.MINIMAX)

#opponents = [player2, player3, player4]
mes = [me1, me2]
opponents = [player3]

myBoard = MancalaBoard()

iterations = 2

for meNume, me in enumerate(mes):

    for oppNum, currentOpponent in enumerate(opponents):

        #reset the scores
        p1 = 0
        p2 = 0

        print ""
        print "***********************************************"
        print "me" + str(meNume +
                         1) + " playing against opponent" + str(oppNum + 1)
Beispiel #16
0
class MancalaWindow:
    """# A very simple GUI for playing the game of Mancala."""

    def __init__(self, master, p1, p2):
        self.CUPW = 75
        self.HEIGHT = 200
        self.BOARDW = 400
        self.PAD = 0
        self.game = MancalaBoard()
        self.p1 = p1
        self.p2 = p2
        self.BINW = self.BOARDW / self.game.NCUPS

        self.turn = p1
        self.wait = p2
        self.root = master

        frame = Frame(master)
        frame.pack()

        # Create the board
        self.makeBoard( frame )

        displayStr = "Welcome to Mancala"

        self.status = Label(frame, text=displayStr)
        self.status.pack(side=BOTTOM)

    def enableBoard(self):
        """ Allow a human player to make moves by clicking"""
        for i in [0, 1]:
            for j in range(self.game.NCUPS):
                self.cups[i][j].bind("<Button-1>", self.callback)

    def disableBoard(self):
        """ Prevent the human player from clicking while the computer thinks"""
        for i in [0, 1]:
            for j in range(self.game.NCUPS):
                self.cups[i][j].unbind("<Button-1>")

    def makeBoard( self, frame ):
        """ Create the board """
        boardFrame = Frame(frame)
        boardFrame.pack(side=TOP)

        self.button = Button(frame, text="Start New Game", command=self.newgame)
        self.button.pack(side=BOTTOM)

        gamef = Frame(boardFrame)
        topRow = Frame(gamef)
        bottomRow = Frame(gamef)
        topRow.pack(side=TOP)
        bottomRow.pack(side=TOP)
        tmpCups = []
        tmpCups2 = []

        binW = self.BOARDW/self.game.NCUPS
        binH = self.HEIGHT/2

        for i in range(self.game.NCUPS):
            c = Canvas(bottomRow, width=binW, height=binH)
            c.pack(side=LEFT)
            tmpCups += [c]
            c = Canvas(topRow, width=binW, height=binH)
            c.pack(side=LEFT)
            tmpCups2 += [c]

        self.cups = [tmpCups, tmpCups2]
        self.p1cup = Canvas(boardFrame, width=self.CUPW, height=self.HEIGHT)
        self.p2cup = Canvas(boardFrame, width=self.CUPW, height=self.HEIGHT)

        self.p2cup.pack(side=LEFT)
        gamef.pack(side=LEFT)
        self.p1cup.pack(side=LEFT)

        self.drawBoard()


    def drawBoard( self ):
        """ Draw the board on the canvas """
        self.p2cup.create_oval(self.PAD, self.PAD, self.CUPW, 0.9*self.HEIGHT, width=2 )
        binW = self.BOARDW/self.game.NCUPS
        binH = self.HEIGHT/2
        for j in [0, 1]:
            for i in range(self.game.NCUPS):

                self.cups[j][i].create_rectangle(self.PAD, self.PAD, binW, binH)
        self.p1cup.create_oval(self.PAD, self.PAD+0.1*self.HEIGHT, self.CUPW, self.HEIGHT, width=2 )


    def newgame(self):
        """ Start a new game between the players """
        self.game.reset()
        self.turn = self.p1
        self.wait = self.p2
        s = "Player " + str(self.turn) + "'s turn"
        if self.turn.type != Player.HUMAN:
            s += " Please wait..."
        self.status['text'] = s
        self.resetStones()
        self.continueGame()

    # Board must be disabled to call continueGame
    def continueGame( self ):
        """ Find out what to do next.  If the game is over, report who
            won.  If it's a human player's turn, enable the board for
            a click.  If it's a computer player's turn, choose the next move."""
        self.root.update()
        if self.game.gameOver():
            if self.game.hasWon(self.p1.num):
                self.status['text'] = "Player " + str(self.p1) + " wins"
            elif self.game.hasWon(self.p2.num):
                self.status['text'] = "Player " + str(self.p2) + " wins"
            else:
                self.status['text'] = "Tie game"
            return
        if self.turn.type == Player.HUMAN:
            self.enableBoard()
        else:
            move = self.turn.chooseMove( self.game )
            playAgain = self.game.makeMove( self.turn, move )
            if not playAgain:
                self.swapTurns()
            self.resetStones()
            self.continueGame()

    def swapTurns( self ):
        """ Change whose turn it is"""
        temp = self.turn
        self.turn = self.wait
        self.wait = temp
        statusstr = "Player " + str(self.turn) + "\'s turn "
        if self.turn.type != Player.HUMAN:
            statusstr += "Please wait..."
        self.status['text'] = statusstr


    def resetStones(self):
        """ Clear the stones and redraw them """
        # Put the stones in the cups
        for i in range(len(self.game.P2Cups)):
            index = (len(self.game.P2Cups)-i)-1
            self.clearCup(self.cups[1][index])
            # put the number of stones at the top of the canvas
            self.cups[1][index].create_text(self.BINW/2, 0.05*self.HEIGHT, text=str(self.game.P2Cups[i]), tag="num")
        for i in range(len(self.game.P1Cups)):
            # put the number of stones at the bottom of the canvas
            self.clearCup(self.cups[0][i])
            self.cups[0][i].create_text(self.BINW/2, 0.05*self.HEIGHT, text=str(self.game.P1Cups[i]), tag="num")
        self.clearCup(self.p1cup)
        self.clearCup(self.p2cup)
        self.p2cup.create_text(self.CUPW/2, 10, text=str(self.game.scoreCups[1]), tag="num")
        self.p1cup.create_text(self.CUPW/2, 10+0.1*self.HEIGHT, text=str(self.game.scoreCups[0]), tag="num")


    def clearCup( self, cup ):
        """ Clear the stones in the given cup"""
        titems = cup.find_withtag("num")
        stones = cup.find_withtag("stone")
        cup.delete(titems)
        cup.delete(stones)


    def callback(self, event):
        """ Handle the human player's move"""
        # calculate which box the click was in
        moveAgain = True
        self.disableBoard()
        if self.turn.num == 1:
            for i in range(len(self.cups[0])):
                if self.cups[0][i] == event.widget:
                    if self.game.legalMove( self.turn, i+1 ):
                        moveAgain = self.game.makeMove( self.turn, i+1 )
                        if not moveAgain:
                            self.swapTurns()
                        self.resetStones()
        else:
            for i in range(len(self.cups[1])):
                if self.cups[1][i] == event.widget:
                    index = self.game.NCUPS - i
                    if self.game.legalMove( self.turn, index ):
                        moveAgain = self.game.makeMove( self.turn, index )
                        if not moveAgain:
                            self.swapTurns()
                        self.resetStones()
        if moveAgain:
            self.enableBoard()
        else:
            self.continueGame()
Beispiel #17
0
 def setUp(self):
     self.board = MancalaBoard.MancalaBoard()
     self.player1 = slv398.slv398(1, slv398.Player.CUSTOM)
     self.player2 = slv398.slv398(2, slv398.Player.CUSTOM)