diff --git a/game.py b/game.py
index 4eac1f092e4f696819f2421d836418bca435e4fc..b613031b936c39a6fa3639de5ed041bb7f68ce9e 100644
--- a/game.py
+++ b/game.py
@@ -2,21 +2,11 @@ import matplotlib.pyplot as plt
 from matplotlib import cm
 from mpl_toolkits.mplot3d import Axes3D
 import numpy as np
-import copy
 import utilis, agent, graph
 
 
-N = 100
-# K = 2
-# P = 0.8
-I = 1000
-R = 1
-
-Actions = [0, 0.2, 0.4, 0.6, 0.8]    # sort in ascending order
-
-
 class game:
-    def __init__(self, K = 2, P = 0.8 ):
+    def __init__(self, N=100, R=1, K=99, P=0, Actions=[0, 0.2, 0.4, 0.6, 0.8], I=1000, RF=0, alpha=1):
         # datamap = utilis.read()
         # self.N = datamap['N']  # N-Player Game
         # self.M = datamap['M']  # Randomly choose M players to play the game (normally 2)
@@ -27,8 +17,8 @@ class game:
 
         self.N = N
         self.M = 2
-        self.RF = 0
-        self.alpha = 1
+        self.RF = RF
+        self.alpha = alpha
         self.R = R
         self.threshold = 0.5      # Threshold
         # self.actions = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
@@ -56,77 +46,45 @@ class game:
         IW = 100     # Initial Wealth - can be input, can be variable to distinguish population
         self.totalWealth = self.M * IW    # subject to change
         for i in range(self.N):
-            self.players.append(agent.Agent(self.R,IW,self.actions))
-
-
-        "Check if N is divisible by M"
-        if self.N % self.M != 0:
-            print("ERROR, N is not divisible by M, abort")
-            exit(1)
+            self.players.append(agent.Agent(self.R, IW, self.actions))
 
 
-    def lossfrac(self):
-        """
-            the percentage of wealth that players are going to lose if collective-risk happens
-        """
-
-        return self.alpha
 
-
-    def riskfunc(self,RF,contribution,totalwealth):
+    def riskfunc(self,contribution,totalwealth):
         """
             the probability of collective-risk happening, given contribution
         """
 
         proportion = contribution/totalwealth
 
-        if RF == 0:
+        if self.RF == 0:
             # probably parse more parameters here
             return 1 - proportion
 
 
-        elif RF == 1:
-            if proportion >= self.threshold:
+        elif self.RF == 1:
+            if proportion >= 0.5:
                 return 0
             else:
                 return 1
 
 
-        elif RF == 2:
-            if proportion < self.threshold:
-                return 1 - proportion / self.threshold
+        elif self.RF == 2:
+            threshold = 0.5
+            if proportion < threshold:
+                return 1 - proportion / threshold
             else:
                 return 0
 
-
         return "error"
 
 
-
-    def computeRisk(self, contrib_sum, haveRisk = True):  ############
-
-        if haveRisk:
-            return self.riskfunc(self.RF, contrib_sum, self.totalWealth)
-        else:
-            return 0
-
-
-
-
-    def selectPlayers(self):
-        """
-            Randomly select M players from population of size N for each game.
-            :return: An array of permutation of players as arrays of M players
-        """
-        return np.random.permutation(self.N).reshape((self.N//self.M, self.M))  # A 2-dimensional array, stating index of agents
-
-
-    def play2(self):
+    def play(self):
 
         # lastStrategyTable = np.zeros((self.N, self.R))
         # sameStrategyRounds = 0
 
-        results = np.zeros((self.iterations,self.R, len(self.actions)))
+        results = np.zeros((self.iterations, self.R, len(self.actions)))
         """ITERATION"""
         for iter in range(self.iterations):
 
@@ -148,11 +106,11 @@ class game:
                     pool = 0
                     pool += self.players[i].getWealth() * actionTable[i][r] +\
                             self.players[j].getWealth() * actionTable[j][r]
-                    risk = self.computeRisk(pool, self.totalWealth)
+                    risk = self.riskfunc(pool, self.totalWealth)
 
                     for p in [i, j]:
                         if np.random.uniform(0, 1) < risk:
-                            lossTable[p, r] += self.lossfrac()/self.graph.getNodesNumber()[p]
+                            lossTable[p, r] += self.alpha/self.graph.getNodesNumber()[p]
                 for i in range(self.N):
                     self.players[i].updateReward(r, actionTable[i][r], lossTable[i][r])
 
@@ -178,147 +136,12 @@ class game:
 
 
 
-
-    def playM(self):
-        """
-            Play an iteration of N/M games between M players, of R rounds
-        """
-        iteration = 1
-        results = []
-        last_counter = []
-        same_results = 0
-
-        # if self.graph_based:
-        #     playersNo = self.graphSelect()
-
-
-        while (iteration <= self.iterations) & (same_results < 50 or True):   # iteration starts
-
-            """ITERATION"""
-
-            iteration_counter = []
-
-            for player in self.players:     # reset initial wealth
-                player.resetWealth()
-
-
-            playersNo = self.selectPlayers()
-            print(playersNo)
-
-
-
-            """GAME"""
-
-            for m_players in playersNo:    # for each set of m players  -- a game
-
-                game_counter = []  # STATS: list of the round counters
-
-                print("A new game starts, among players:", m_players, "\nContribution initialised")
-                contributions = {}   # accumulated contributions of each round
-
-                """ROUND"""
-
-
-                for r in range(self.R):    # for each round
-
-                    round_counter = {}  # STATS: counting the number of each actions
-                    for action in self.actions:
-                        round_counter[action] = 0
-
-                    ratio = {}
-                    print("RRRRRRRRRRRRRRRRound", r)
-
-                    """PLAYER'S TURN"""
-                    for m in m_players:    # for each player
-                        print("Player", m, "is playing:")
-                        ratio[m] = self.players[m].chooseAction(r)         # Choose Action (a ratio)
-                        round_counter[ratio[m]] += 1
-                        currentWealth = self.players[m].getWealth()
-                        if m not in contributions:
-                            contributions[m] = 0
-                        print("Ratio:", ratio[m], "current wealth before:", currentWealth)
-                        contributions[m] += ratio[m] * currentWealth
-                        print("Contribute: ", ratio[m] * currentWealth)
-                    """PLAYER'S TURN END"""
-
-                    print("All players contributed, sum:", sum(contributions.values()), "total wealth:", self.totalWealth)
-                    risk = self.computeRisk(sum(contributions.values()), self.totalWealth)
-                    print("risk:", risk)
-                    for m in m_players:
-                        if np.random.uniform(0,1) < risk:   # "<" since np.random.uniform is [0, 1)
-                            print("XXXXXXXX Tragedy happened to Player ", m, " losing " ,self.lossfrac(), "of wealth")
-                            loss = self.lossfrac()
-                        else:
-                            print("NOTHING HAPPEND TO PLAYER",m)
-                            loss = 0
-                        self.players[m].updateReward(r, ratio[m], loss)
-
-                    print("R----------Round finished, round counter: ", round_counter)
-                    game_counter.append(round_counter)
-                """ROUND END"""
-
-                print("G======Game finished. game counter:", game_counter)
-
-                if not iteration_counter:
-                    iteration_counter = copy.deepcopy(game_counter)
-                else:
-                    for r in range(self.R):
-                        iteration_counter[r] = utilis.combine_dict(iteration_counter[r], game_counter[r])
-
-            """GAME END"""
-
-            print("I~~~~~Iteration ", iteration, " finished. Iteration Counter:")
-            print(iteration_counter)
-            results.append(iteration_counter)
-            iteration += 1
-
-            if last_counter:
-                if last_counter == iteration_counter:
-                    same_results += 1
-                else:
-                    same_results = 0
-
-            last_counter = copy.deepcopy(iteration_counter)
-
-
-        """ITERATION END"""
-
-        print("GAME FINISHED. RESULTS:")
-        for i in range(len(results)):
-            print("iteration", i+1, results[i])
-
-
-def stackBar(data, r):    # Plotting the data for round r
-
-    A = len(Actions)
-    p = []
-    mean = np.zeros((A, I))     # of each action in each iter
-    ind = np.arange(I)
-    width = 0.3
-    for iter in range(I):
-        for a in range(A):
-            mean[a, iter] = data[iter, r, a]
-    base = 0
-    for a in range(A):
-        p.append(plt.bar(ind, mean[a], width, bottom=base))
-        base += mean[a]
-
-    plt.ylabel('Number of Actions')
-    plt.xlabel('Time(iterations)')
-    plt.title('Average Number of Actions in Round ' + str(r+1))
-    # plt.xticks(ind, ('G1', 'G2', 'G3', 'G4', 'G5'))
-    # plt.yticks(np.arange(0, 81, 10))
-    plt.legend(tuple([p[x][0] for x in range(A)][::-1]), tuple(Actions[::-1]))
-
-    plt.show()
-
-
-def stackPlot(data, r, k, p):
+def stackPlot(data, r, Actions, Iterations, titleComment = ""):
 
     A = len(Actions)
-    x = range(I)
-    y = np.zeros((I, A))
-    for i in range(I):
+    x = range(Iterations)
+    y = np.zeros((Iterations, A))
+    for i in range(Iterations):
         y[i] = data[i][r]
     y = np.vstack(y.T)
 
@@ -328,50 +151,50 @@ def stackPlot(data, r, k, p):
     ax.legend(loc='lower right')
     plt.ylabel('Number of Actions')
     plt.xlabel('Time(iterations)')
-    plt.title('Average Number of Actions in Round ' + str(r+1) +
-              '\n(k=' + str(k) + ', p=' + str(p) + ')')
+
+    title = 'Average Number of Actions in Round ' + str(r+1) + ')'
+    if not titleComment:
+        title += "\n" + titleComment
+
+    plt.title(title)
     plt.show()
 
 
-def rep(rept, K, P, r=0, graph = None):
+def rep(repeat, N=100, R=1, K=99, P=0, Actions=[0, 0.2, 0.4, 0.6, 0.8], I=1000, RF=0, alpha=1):
     data = np.zeros((I, R, len(Actions)))
-    for re in range(rept):
+    Actions.sort()
+    for re in range(repeat):
         print("REP", re)
-        g = game(K=K, P=P)
-        result = g.play2()
+        g = game(N, R, K, P, Actions, I, RF, alpha)
+        result = g.play()
         data += result
-    data /= rept
-    print(data)
+    data /= repeat
+    return data
 
 
-    if graph == "stackBar":
-        stackBar(data, 0)
 
-    elif graph == "stackPlot":
-        if r == -1:
-            for i in range(R):
-                stackPlot(data, i, K, P)
-        else:
-            stackPlot(data, r, K, P)
+def averageOfLast(data, Actions, r=0, lastIterations=100 ):
+    sum = 0
+    action_counter = {}
 
+    for i in range(-1, -lastIterations-1, -1):
+        sum += np.sum(data[i, r] * Actions)
+        for a in Actions:
+            action_counter[a] += data[i, r, a]/lastIterations
+    return (sum/100, action_counter)
 
-    # Taking the mean of the last 100 iterations  --- need to justify
 
-    sum = 0
-    for i in range(-1, -101, -1):
-        sum += np.sum(result[i, r] * Actions)
-    return sum/100
 
-def graph_kp3d(Klist=[2, 4, 8, 10], Plist=[0.2, 0.4, 0.6, 0.8], repet=30):
+def graph_kp3d(Actions, Klist=[2], Plist=[0.2, 0.5, 0.8], repeat=1):
     K = Klist
     P = Plist
 
-
     meanA = np.zeros((len(K), len(P)))
 
     for k in range(len(K)):
         for p in range(len(P)):
-            meanA[k][p] = rep(repet, K[k], P[p])
+            data = rep(repeat, K=K[k], P=P[p])    # Specify other params by adding here or change default of rep
+            meanA[k][p] = averageOfLast(data, Actions, lastIterations=100)  # Doing the first round only -- for now
 
     P, K = np.meshgrid(P, K)
 
@@ -386,9 +209,34 @@ def graph_kp3d(Klist=[2, 4, 8, 10], Plist=[0.2, 0.4, 0.6, 0.8], repet=30):
 
 
 def main():
-    graph_kp3d()
-    # rep(50, 99, 0, graph="stackPlot")
 
+    # Read-in or Define Parameters
+
+    N = 100
+    R = 2
+    K = 99
+    P = 0
+    I = 1000
+    RF = 0
+    alpha =1
+    Actions = [0, 0.2, 0.4, 0.6, 0.8]
+
+
+    """
+    Graph1: Number of Actions of Round r (start by 0) by Iteration
+    """
+    # Repeat game and get the averaged data
+    RepeatTimes = 30
+    data = rep(RepeatTimes, N, R, K, P, Actions, I, RF, alpha)
+
+    for r in range(R):
+        stackPlot(data, r, Actions, I, "Fully-Mixed Graph")
+
+    """
+    Graph2: Average contribution by K, P
+    """
+
+    graph_kp3d(Actions)