Exemple #1
0
class PPP():
    "Simulating Rock, Paper & Probabilities game"

    def __init__(self, configpath):
        self.config = js.load(open(configpath))
        self.vz = Visualization(self.config["language"])
        self.n = None  #Number of simulated rolls
        self.i = None  #Number of iterations
        self.ai = None  #Active iteration
        self.ms = None  #Match size in rolls
        self.discardtieds = None  #Decide if tied rolls are part of a match
        self.starttime = None
        self.sname = None
        self.rollresult = []
        self.simulationdata = []
        self.summarydata = None
        self.dicefaces = ["rock", "paper", "scissors"]
        self.cdice = [-1, -1, -1, -1, -1, -1]
        self.pdice = [-1, -1, -1, -1, -1, -1]
        PPP.setConfig(self, self.config)
        print()
        print(self)
        PPP.run(self)
        PPP.exportRawData(self)
        self.summarydata = PPP.buildSummary(self)
        self.vz.autoCharts(self.sname, self.config["cPath"], self.cdice,
                           self.pdice, self.simulationdata, self.summarydata)
        PPP.exportSummary(self)

    def run(self):
        for d in range(self.i):
            self.starttime = tm.time()
            self.rollresult = [0, "?", "?", 0, 0, 0, 0, 0.0, 0.0, 0.0, 0, 0.0]
            self.simulationdata.append(PPP.buildSimulationDataFrame())
            print("-- Simulation number: " + str(d) + "   ", end="\n")
            PPP.simulation(self)
            print("-- Time needed: " + \
              PPP.getSimulationTime(self.starttime, tm.time()) + "                 ", end="\n")
            print("-- The data was saved!", end="\n")
            print()
            self.ai += 1

    def simulation(self):
        for d in range(self.n):
            print("-- Roll " + str(d) + ":", end=" ")
            r = PPP.play(self)
            PPP.updateRoll(self, d + 1, r)
            print("W: " + str(self.rollresult[7]), end=" ")
            print("T: " + str(self.rollresult[8]), end=" ")
            print("L: " + str(self.rollresult[9]) + "     ", end="\r")
            PPP.saveRoll(self, self.ai)

    def play(self):
        c = rd.choice(self.cdice)
        p = rd.choice(self.pdice)
        r = PPP.decide(c, p)
        return [c, p, r]

    def decide(c, p):
        r = 0
        if c == 0:
            if p == 1:
                r = 1
            elif p == 2:
                r = -1
        if c == 1:
            if p == 2:
                r = 1
            elif p == 0:
                r = -1
        if c == 2:
            if p == 0:
                r = 1
            elif p == 1:
                r = -1
        if c == -1 or p == -1:
            print("-- Dice has strange faces...")
        return r

    def updateRoll(self, n, results):
        self.rollresult[0] = n
        self.rollresult[1] = self.dicefaces[results[0]]
        self.rollresult[2] = self.dicefaces[results[1]]
        self.rollresult[3] = results[2]
        PPP.updateRCounts(self, self.rollresult[3])
        self.rollresult[7] = round(self.rollresult[4] / self.rollresult[0], 2)
        self.rollresult[8] = round(self.rollresult[5] / self.rollresult[0], 2)
        self.rollresult[9] = round(self.rollresult[6] / self.rollresult[0], 2)
        self.rollresult[10] = self.rollresult[4] - self.rollresult[6]
        self.rollresult[11] = round(self.rollresult[10] / self.rollresult[0],
                                    2)

    def updateRCounts(self, result):
        if result == 1:
            self.rollresult[4] += 1
        if result == 0:
            self.rollresult[5] += 1
        if result == -1:
            self.rollresult[6] += 1

    def saveRoll(self, i):
        row = pd.DataFrame([self.rollresult],
                           columns=PPP.buildDataFrameColumns())
        self.simulationdata[self.ai] = pd.concat(
            [self.simulationdata[self.ai], row])

    def exportRawData(self):
        for i in range(self.i):
            self.simulationdata[i].set_index("n", inplace=True)
            self.simulationdata[i].to_csv(self.config["dPath"] + self.sname +
                                          "_" + str(i) + ".csv")

    def buildSummary(self):
        d = PPP.buildSummaryDataFrame(self)
        for i in range(self.i):
            mr = self.getMatchesResults(self.simulationdata[i])
            d.loc[d.index[i], "Won"] = self.simulationdata[i].loc[
                self.simulationdata[i].index[self.n - 1], "Won"]
            d.loc[d.index[i], "Tied"] = self.simulationdata[i].loc[
                self.simulationdata[i].index[self.n - 1], "Tied"]
            d.loc[d.index[i], "Lost"] = self.simulationdata[i].loc[
                self.simulationdata[i].index[self.n - 1], "Lost"]
            d.loc[d.index[i], "Won matches"] = mr[0]
            d.loc[d.index[i], "Lost matches"] = mr[1]
        d.loc[d.index[self.i], "Won"] = round(d["Won"].mean(), 2)
        d.loc[d.index[self.i], "Tied"] = round(d["Tied"].mean(), 2)
        d.loc[d.index[self.i], "Lost"] = round(d["Lost"].mean(), 2)
        d.loc[d.index[self.i], "Won matches"] = round(d["Won matches"].mean(),
                                                      2)
        d.loc[d.index[self.i],
              "Lost matches"] = round(d["Lost matches"].mean(), 2)
        return d

    def getMatchesResults(self, data):
        if self.discardtieds == True:
            rolls = data[data["Result"] != 0]
            rolls.reset_index(inplace=True)
        else:
            rolls = data
        p = self.ms
        mr = [0, 0]
        while p < rolls.shape[0]:
            r = rolls.loc[p - self.ms:p, "Result"].sum()
            if r > 0:
                mr[0] += 1
            elif r < 0:
                mr[1] += 1
            p += self.ms
        return mr

    def exportSummary(self):
        self.summarydata.to_csv(self.config["dPath"] + self.sname + "_S" +
                                ".csv")

    def printRoll(self, results):
        return "-- The dice rolled:\n" + \
          "-- " + self.dicefaces[results[0]] + "vs. " + self.dicefaces[results[1]] + \
          "--> " + str(results[2])

    def setConfig(self, data):
        self.n = data["rollcount"]
        self.i = data["iterations"]
        self.ai = 0
        self.ms = data["matchsize"]
        self.discardtieds = data["discardtieds"]
        self.sname = data["name"]
        PPP.buildDices(self, data["computerdice"], data["playerdice"])

    def buildDices(self, cd, pd):
        c = cd.split(",")
        p = pd.split(",")
        l = len(c)
        if l == 6:
            for f in range(l):
                self.cdice[f] = PPP.setDiceFace(c[f])
                self.pdice[f] = PPP.setDiceFace(p[f])
        else:
            print("-- Configuration data is strange...")

    def setDiceFace(s):
        n = -1
        if s == "rock":
            n = 0
        elif s == "paper":
            n = 1
        elif s == "scissors":
            n = 2
        return n

    def buildSimulationDataFrame():
        columns = PPP.buildDataFrameColumns()
        p = pd.DataFrame(columns=columns)
        p.index.name = "n"
        return p

    def buildDataFrameColumns():
        columns = []
        columns.append("n")
        columns.append("Computer")
        columns.append("Player")
        columns.append("Result")
        columns.append("Won")
        columns.append("Tied")
        columns.append("Lost")
        columns.append("Won%")
        columns.append("Tied%")
        columns.append("Lost%")
        columns.append("delta")
        columns.append("delta%")
        return columns

    def buildSummaryDataFrame(self):
        columns = []
        columns.append("Won")
        columns.append("Tied")
        columns.append("Lost")
        columns.append("Won matches")
        columns.append("Lost matches")
        p = pd.DataFrame(index=range(self.i + 1), columns=columns)
        p.index.name = "n"
        return p

    #Calculating time needed for simulation to finish...
    def getSimulationTime(startTime, endTime):
        time = endTime - startTime
        formatedTime = PPP.formatTime(time)
        return formatedTime

    def formatTime(time):
        ms = ""
        minutes = time // 60
        seconds = time - minutes * 60
        seconds = round(seconds, 2)
        ms = "{:02d}".format(int(minutes))
        ms += ":"
        ms += "{:05.2f}".format(seconds)
        return ms

    def __str__(self):
        return "-- MatEduLab\n" + \
          "-- Rock, Paper & Probabilities\n" + \
          "-- https://gitlab.com/matedulab/rpp-simulation\n" + \
          "-- version: 0.90\n" + \
          "-- Simulating the game...\n"