示例#1
0
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.hColor = "blue"
        self.vColor = "maroon"

        # stores information about the game
        self.gameState = GameState()
        # used to calculate win expectancy
        # Run Environment: 4.5
        # Home Team Win %: .5
        self.winCalc = WinExpCalculator(4.5, 0.5)

        self.createWidgets()
        self.updateGameDisplay()
        self.updateStateDisplay()
示例#2
0
class App(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.hColor = "blue"
        self.vColor = "maroon"

        # stores information about the game
        self.gameState = GameState()
        # used to calculate win expectancy
        # Run Environment: 4.5
        # Home Team Win %: .5
        self.winCalc = WinExpCalculator(4.5, 0.5)

        self.createWidgets()
        self.updateGameDisplay()
        self.updateStateDisplay()

    # This function creates the widgets used in the GUI's display
    def createWidgets(self):
        # current state of game
        self.gameFrm = Frame(self)
        # home score
        self.homeFrm = Frame(self.gameFrm)
        self.homeScoreLbl = Label(self.homeFrm)
        self.homeScoreTxt = StringVar()
        self.homeScoreLbl["textvariable"] = self.homeScoreTxt
        self.homeScoreLbl.pack(side=TOP)
        self.homeScoreLbl.configure(foreground=self.hColor, font=20)
        self.homePctLbl = Label(self.homeFrm)
        self.homePctTxt = StringVar()
        self.homePctLbl["textvariable"] = self.homePctTxt
        self.homePctLbl.configure(foreground=self.hColor)
        self.homePctLbl.pack(side=TOP)
        self.homeFrm.pack(side=LEFT)
        # visitor score
        self.visFrm = Frame(self.gameFrm)
        self.visScoreLbl = Label(self.visFrm)
        self.visScoreTxt = StringVar()
        self.visScoreLbl["textvariable"] = self.visScoreTxt
        self.visScoreLbl.pack(side=TOP)
        self.visScoreLbl.configure(foreground=self.vColor, font=20)
        self.visPctLbl = Label(self.visFrm)
        self.visPctTxt = StringVar()
        self.visPctLbl["textvariable"] = self.visPctTxt
        self.visPctLbl.configure(foreground=self.vColor)
        self.visPctLbl.pack(side=TOP)
        self.visFrm.pack(side=RIGHT)
        # win probability
        self.winFrm = Frame(self.gameFrm)
        self.wBar = WinBar(self.winFrm, self.hColor, self.vColor)
        self.innLbl = Label(self.winFrm)
        self.innTxt = StringVar()
        self.innLbl["textvariable"] = self.innTxt
        self.baseLbl = Label(self.winFrm)
        self.baseTxt = StringVar()
        self.baseLbl["textvariable"] = self.baseTxt
        self.playLbl = Label(self.winFrm)
        self.playTxt = StringVar()
        self.playLbl["textvariable"] = self.playTxt
        self.wBar.pack(side=TOP)
        self.innLbl.pack(side=TOP)
        self.baseLbl.pack(side=TOP)
        self.playLbl.pack(side=TOP)
        self.winFrm.pack(side=TOP)

        # visual separator
        self.separator = Frame(self, height=5, borderwidth=5, relief=SUNKEN)
        self.gameFrm.pack(side=TOP)
        self.separator.pack(side=TOP, fill=X, padx=5, pady=5)

        # run specific plays
        self.playFrm = LabelFrame(self, text="Choose Play:", borderwidth=2)
        self.plays = sorted(list(self.gameState.playDict.keys()))
        self.playMenVar = StringVar()
        self.playMenVar.set(self.plays[0])
        self.playSelect = OptionMenu(self.playFrm, self.playMenVar, *self.plays)
        self.playBttn = Button(self.playFrm, text="Run Play", command=self.playClick)
        self.playSelect.pack(side=LEFT)
        self.playBttn.pack(side=LEFT)
        self.playFrm.pack(side=TOP)

        # visual separator
        self.separator2 = Frame(self, height=5, borderwidth=5, relief=SUNKEN)
        self.gameFrm.pack(side=TOP)
        self.separator2.pack(side=TOP, padx=5, pady=5)

        # enter a specific game state
        self.stateFrm = LabelFrame(self, text="Go To Specific Game State:", borderwidth=2)
        self.innStFrm = Frame(self.stateFrm)
        self.innStLbl = Label(self.innStFrm, text="Inning: ")
        self.innEnter = Spinbox(self.innStFrm, from_=1, increment=1, to=100)
        self.halfStFrm = Frame(self.stateFrm)
        self.halfLbl = Label(self.halfStFrm, text="Top/Bottom: ")
        self.halfEnter = Spinbox(self.halfStFrm, values=("Bottom", "Top"))
        self.outStFrm = Frame(self.stateFrm)
        self.outLbl = Label(self.outStFrm, text="Outs: ")
        self.outEnter = Spinbox(self.outStFrm, from_=0, to=2, increment=1)
        self.hStFrm = Frame(self.stateFrm)
        self.hStLbl = Label(self.hStFrm, text="Home Score: ")
        self.hEnter = Spinbox(self.hStFrm, from_=self.gameState.hScore, increment=1, to=100)
        self.vStFrm = Frame(self.stateFrm)
        self.vStLbl = Label(self.vStFrm, text="Visitor Score: ")
        self.vEnter = Spinbox(self.vStFrm, from_=self.gameState.vScore, increment=1, to=100)
        self.baseStFrm = Frame(self.stateFrm)
        self.stateBttn = Button(self.stateFrm, text="Go", command=self.stateClick)
        self.hStLbl.pack(side=LEFT)
        self.hEnter.pack(side=LEFT)
        self.vStLbl.pack(side=LEFT)
        self.vEnter.pack(side=LEFT)
        self.hStFrm.pack(side=TOP)
        self.vStFrm.pack(side=TOP)
        self.innStLbl.pack(side=LEFT)
        self.innEnter.pack(side=LEFT)
        self.innStFrm.pack(side=TOP)
        self.halfLbl.pack(side=LEFT)
        self.halfEnter.pack(side=LEFT)
        self.halfStFrm.pack(side=TOP)
        self.outStFrm.pack(side=TOP)
        self.outLbl.pack(side=LEFT)
        self.outEnter.pack(side=LEFT)
        self.baseStFrm.pack(side=TOP)
        self.baseStLbl = Label(self.baseStFrm, text="Baserunners: ")
        self.baseStLbl.pack(side=LEFT)
        self.baseInt = []
        self.baseCh = []
        self.baseNames = ["1st", "2nd", "3rd"]
        for i in range(0, 3):
            self.baseInt.append(IntVar())
            self.baseCh.append(Checkbutton(self.baseStFrm, variable=self.baseInt[i], text=self.baseNames[i]))
            self.baseCh[i].pack(side=LEFT)
        self.stateBttn.pack(side=TOP)
        self.stateFrm.pack(side=BOTTOM)

    # updates the game to a state provided by input from gui
    def stateClick(self):
        try:
            self.gameState.outs = int(self.outEnter.get())
            if self.gameState.outs > 2 or self.gameState.outs < 0:
                raise ValueError("Bad Outs value")
            self.gameState.inning = int(self.innEnter.get())
            if self.gameState.inning < 1:
                raise ValueError("Inning < 1")
            self.gameState.hScore = int(self.hEnter.get())
            if self.gameState.hScore < 0:
                raise ValueError("Score < 1")
            self.gameState.vScore = int(self.vEnter.get())
            if self.gameState.vScore < 0:
                raise ValueError("Score < 1")
        except ValueError as e:
            print("Bad Game State Input: " + str(e))
            return
        halfStr = self.halfEnter.get()
        if halfStr == "Bottom":
            self.gameState.half = 1
        elif halfStr == "Top":
            self.gameState.half = 0
        else:
            print("Bad inning half value: " + halfStr)
        for i in range(0, 3):
            if self.baseInt[i].get() == 1:
                self.gameState.base[i] = True
            elif self.baseInt[i].get() == 0:
                self.gameState.base[i] = False
            else:
                print("Bad base checkbox value: " + str(self.baseInt[i].get()))
        self.updateGameDisplay()

    # runs a particular play from the drop down
    def playClick(self):
        play = self.playMenVar.get()
        self.gameState.runPlay(play)
        self.updateGameDisplay()
        self.updateStateDisplay()

    # updates the win probabilities displayed
    def updateProb(self):
        prob = self.getWinProb()
        self.wBar.update(prob)
        prob = int(round(prob, 0))
        self.homePctTxt.set("Win Pct: " + str(prob) + "%")
        self.visPctTxt.set("Win Pct: " + str(100 - prob) + "%")

    # Simple function to call getWinPct with the correct arguments
    def getWinProb(self):
        p = self.winCalc.getWinPct(
            self.gameState.getBaseState(),
            self.gameState.hScore - self.gameState.vScore,
            self.gameState.inning,
            self.gameState.outs,
            self.gameState.half,
        )
        return p * 100

    # Updates the display of the state of the game (top)
    def updateGameDisplay(self):
        # Inning display
        innStr = ""
        if self.gameState.half == 0:
            innStr += "Top "
        elif self.gameState.half == 1:
            innStr += "Bottom "
        innStr += "of inning "
        innStr += str(self.gameState.inning)
        innStr += ", " + str(self.gameState.outs) + " outs"
        self.innTxt.set(innStr)

        # Baserunner display
        baseStr = ""
        if self.gameState.getBaseState() == 1:
            baseStr = "Bases Empty"
        else:
            comma = 0
            if self.gameState.base[0]:
                comma = 1
                baseStr += " 1st"
            if self.gameState.base[1]:
                if comma == 1:
                    baseStr += ","
                baseStr += " 2nd"
                comma += 1
            if self.gameState.base[2]:
                if comma > 0:
                    baseStr += ","
                comma += 1
                baseStr += " 3rd"
            if comma > 1:
                baseStr = "Runners on:" + baseStr
            else:
                baseStr = "Runner on" + baseStr
        self.baseTxt.set(baseStr)

        # Score display
        hScore = self.gameState.hScore
        vScore = self.gameState.vScore
        if hScore != -1:
            self.homeScoreTxt.set("Home " + str(hScore))
        if vScore != -1:
            self.visScoreTxt.set("Visitor " + str(vScore))

        # Updates win probability and sets win % displays
        self.updateProb()

        # Win % change display
        lc = int(round(self.wBar.lastChange, 0))
        playTxt = "Last W% Change: "
        if lc > 0:
            playTxt += "Home +" + str(lc) + "%"
        elif lc < 0:
            playTxt += "Visitor +" + str(-1 * lc) + "%"
        else:
            playTxt += "Change < 1%"
        self.playTxt.set(playTxt)

    # Updates the "Go to specific game state" section to follow the actual
    # game state
    def updateStateDisplay(self):
        while self.gameState.inning > int(self.innEnter.get()):
            self.innEnter.invoke("buttonup")
        while self.gameState.inning < int(self.innEnter.get()):
            self.innEnter.invoke("buttondown")
        if self.gameState.half == 0:
            self.halfEnter.invoke("buttonup")
        else:
            self.halfEnter.invoke("buttondown")
        while self.gameState.outs > int(self.outEnter.get()):
            self.outEnter.invoke("buttonup")
        while self.gameState.outs < int(self.outEnter.get()):
            self.outEnter.invoke("buttondown")
        while self.gameState.hScore > int(self.hEnter.get()):
            self.hEnter.invoke("buttonup")
        while self.gameState.hScore < int(self.hEnter.get()):
            self.hEnter.invoke("buttondown")
        while self.gameState.vScore > int(self.vEnter.get()):
            self.vEnter.invoke("buttonup")
        while self.gameState.vScore < int(self.vEnter.get()):
            self.vEnter.invoke("buttondown")
        for i in range(0, 3):
            if self.gameState.base[i] == True:
                self.baseCh[i].select()
            else:
                self.baseCh[i].deselect()
        return