aboutsummaryrefslogtreecommitdiffstats
path: root/python/alphaBeta.py
blob: 0a24ebcfff052714e9520bdacb028031c49b3913 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import math
from copy import deepcopy
from time import perf_counter
from random import choice

from GameState import GameState
class GameController(object):
    def get_next_move(self, state):
        # when you get a new move, it is assumed that the game is not ended yet
        assert state.get_moves()

class ABNode(object): # A class for Node related operations
    def __init__(self, state):
        self.Current = state
        if state.player == 1:
            self.CurrentScore = self.Current.score[2]-self.Current.score[1]
        elif state.player ==2:
            self.CurrentScore = self.Current.score[1]-self.Current.score[2]
        self.children = {}


    def update_score(self):
        if self.Current.player == 2:
            self.CurrentScore = self.Current.score[1]-self.Current.score[2]
        elif self.Current.player == 1:
            self.CurrentScore = self.Current.score[2]-self.Current.score[1]
            
    def Make(self, r,c,o): # Function for generating a child node
        lit=deepcopy(self.Current)
        self.children[(r,c,o)] = ABNode(lit)
        move=(r,c,o)
        self.children[(r,c,o)].Current.play_move(move)
        self.children[(r,c,o)].update_score()

    def Populate(self, r,c,o, Child): # Function for adding a node
        self.children[(r,c,o)] = Child

    def Draw(self): # function for drawing the board
        self.Current.Draw_mat()

# A class for defining algorithms used (minimax and alpha-beta pruning)
class AlphaBeta(object):

    def miniMax(self, State, Ply_num):  # Function for the minimax algorithm
        State = deepcopy(State)
        start = ABNode(State)
        possiblemoves=State.get_moves()
        if len(possiblemoves) < 3:
            for x in possiblemoves:
                return x
        for x in possiblemoves:
            if len(possiblemoves) < 3:
                return x
            if (x[0],x[1],x[2]) not in start.children:
                start.Make(x[0],x[1],x[2]) 
        # if Ply_num < 2:
        #     return (i, j)

        Minimum_Score = 1000
        r = 0
        c = 0
        o = ""
        for k, z in start.children.items():
            Result = self.Maximum(z, Ply_num - 1, Minimum_Score)
            if Minimum_Score > Result:
                Minimum_Score = Result
                r = k[0]
                c = k[1]
                o = k[2]

        return (r,c,o)

    # Alpha-beta pruning function for taking care of Alpha values
    def Maximum(self, State, Ply_num, Alpha):
        if Ply_num == 0:
            return State.CurrentScore

        possiblemoves=State.Current.get_moves()
        for x in possiblemoves:
            if (x[0],x[1],x[2]) not in State.children:
                State.Make(x[0],x[1],x[2]) 

        Maximum_Score = -1000
        r = 0
        c = 0
        o=""
        for k, z in State.children.items():
            Result = self.Minimum(z, Ply_num - 1, Maximum_Score)
            if Maximum_Score < Result:
                Maximum_Score = Result
            if Result > Alpha:
                return Result

        return Maximum_Score

    def Minimum(self, State, Ply_num, Beta):  # Alpha-beta pruning function for taking care of Beta values
        if Ply_num == 0:
            return State.CurrentScore

        possiblemoves = State.Current.get_moves()
        for x in possiblemoves:
            if (x[0],x[1],x[2]) not in State.children:
                State.Make(x[0],x[1],x[2])

        Minimum_Score = 1000
        i = 0
        j = 0
        for k, z in State.children.items():
            Result = self.Maximum(z, Ply_num - 1, Minimum_Score)
            if Minimum_Score > Result:
                Minimum_Score = Result
            if Result < Beta:
                return Result

        return Minimum_Score
    
    def __repr__(self):
        s="ABNode"
        return s