Tuesday, April 9, 2013

Artificially Intelligent Connect-4 game in Python


#Hailey Hanson
#Connect4 assignment


class Board:


    def __init__(self, width, height):
        self.width = width
        self.height = height
        self.data = [] 
    
        for row in range( self.height ):
            boardRow = []
            for col in range( self.width ):
                boardRow += [' ']
            self.data += [boardRow]
        
        
    def __repr__(self):
        s = ''
        for row in range( self.height ):
            s += '|'
            for col in range( self.width ):
                s += self.data[row][col] + '|'
            s += '\n'
            
        s += '--'*self.width + '-\n'
        
        for col in range( self.width ):
            s += ' ' + str(col % 10)
        s += '\n'
        
        return s
                                    
    def addMove( self,col,ox ):
        if self.allowsMove(col):
            for row in range( self.height ):
                if self.data[row][col] != ' ':
                    self.data[row-1][col] = ox
                    return
            self.data[self.height-1][col] = ox #if empty column, place piece at the bottom
        
    def allowsMove( self,col ):
        if 0 <= col < self.width:
            return self.data[0][col] == ' '
        else:
            print "try a valid number"
        
    def winsFor( self,ox ):
        for row in range( 0,self.height ):
            for col in range( 0,self.width-3 ):
                if self.data[row][col] == ox and \
                self.data[row][col+1] == ox and \
                self.data[row][col+2] == ox and \
                self.data[row][col+3] == ox:
                    return True
               
        for col in range( 0,self.width):
            for row in range( 0,self.height-3 ):
                if self.data[row][col] == ox and \
                self.data[row+1][col] == ox and \
                self.data[row+2][col] == ox and \
                self.data[row+3][col] == ox:
                    return True
                
        for row in range( 0,self.height-3 ):
            for col in range( 3,self.width ):
                if self.data[row][col] == ox and \
                self.data[row+1][col-1] == ox and \
                self.data[row+2][col-2] == ox and \
                self.data[row+3][col-3] == ox:
                    return True
            
        for row in range( 0,self.height-3):
            for col in range( 0,self.width-3 ):
                if self.data[row][col] == ox and \
                self.data[row+1][col+1] == ox and \
                self.data[row+2][col+2] == ox and \
                self.data[row+3][col+3] == ox:
                    return True
        return False
               
    def isFull( self ):
        for col in range( self.width ):
            if self.data[0][col] == ' ':
                return False
        return True     
         
    def clear(self):
        for col in range( self.width ):
            for row in range( self.height ):
                self.data[row][col] = ' '
                
    def delMove( self,col ):
        for row in range( self.height ):
            if self.data[row][col] != ' ':
                self.data[row][col] = ' '
                return 
            
    def hostGame( self ):
        print self
        while True:
            var = self.someInput('x')
            self.addMove(var, 'x')
            print self
            if self.winsFor( 'x' ):
                print "x conquers!"
                break
            var = self.someInput('o')
            self.addMove(var, 'o')
            print self
            if self.winsFor( 'o' ):
                print "o achieves superiority!"
                break
            if self.isFull():
                print "cat's game"
                break
                
    def someInput( self,ox ):
        while True:
            var = raw_input(ox + " play your move: ")
            var = int(var)
            if self.allowsMove( var ):
                return var
   
    def playGameWith(self,aiPlayer):
        print self 
        while True:
            var = self.someInput('x')
            self.addMove(var, 'x')
            print self
            if self.winsFor( 'x' ):
                print "x conquers!"
                break
            var = aiPlayer.aiMove( self ) #computer's move
            self.addMove(var, 'o')
            print self
            if self.winsFor( 'o' ):
                print "o achieves superiority!"
                break
            if self.isFull():
                print "cat's game"
                break   
            
class Player:
    
    def __init__(self,ox,ply):
        self.ox = ox
        self.ply = ply
        
        
    def aiMove( self,board ):
        L = self.scoresFor(board,self.ox,self.ply)
        best = max(L)
        for col in range( len( L ) ):
            if L[col] == best:
                return col
            

    def scoresFor(self,board,ox,ply):
        scoresList = []
        for col in range (board.width):
            if board.allowsMove(col):
                board.addMove(col,ox)
                if board.winsFor( ox ):
                    scoresList += [100]  
                elif ply == 1:
                    scoresList += [50]
                else:
                    if ox == 'x':
                        opponent = 'o'
                    else:
                        opponent = 'x'
                    oppList = self.scoresFor(board,ox,ply-1)
                    bestScore = max(oppList)
                    scoresList += [100-bestScore]
                board.delMove(col)
            else:
                scoresList += [-1]
        return scoresList
    
    
b = Board(7,6)
p = Player('x',3)
b.playGameWith(p)

No comments:

Post a Comment