
'''
Matúš Kočka, 230269
Bakalárska Práca
Elektronické šahcy
'''

from machine import Pin, disable_irq, enable_irq
from utime import sleep_ms
import gc
import time
from AD7147H import AD7147
from mechanics import Mechanics
import sunfishChessEngine

INT1 = Pin(5,Pin.IN)
INT2 = Pin(36,Pin.IN)
INT3 = Pin(39,Pin.IN)
INT4 = Pin(34,Pin.IN)
INT5 = Pin(35,Pin.IN)

CNT = 0
INT_ass = False
#handler function that flips value of int_ass
def INT_asserted(irr):
    state = disable_irq()
    global CNT
    global INT_ass
    CNT = CNT+1
    INT_ass = True
    enable_irq(state)
    
INT1.irq(trigger = Pin.IRQ_FALLING, handler=INT_asserted) # call INT_asserted on falling edge of INT
INT2.irq(trigger = Pin.IRQ_FALLING, handler=INT_asserted)
INT3.irq(trigger = Pin.IRQ_FALLING, handler=INT_asserted)
INT4.irq(trigger = Pin.IRQ_FALLING, handler=INT_asserted)
INT5.irq(trigger = Pin.IRQ_FALLING, handler=INT_asserted)




def main():
    UserMove = [0,0]
    global CNT
    '''ARRAY FOR POSITION OF THE SENSORS'''
    fil = 9
    rank = 9
    ActualPos = [[False] * 9 for _ in range(9)] #Actual sensor board position
    for i in range(9):
        for j in range(3):
            ActualPos[i][j] = True
        for j in range(7, 9):
            ActualPos[i][j] = True
    LastPos = [[False] * 9 for _ in range(9)] #initial sensor board position
    for i in range(9):
        for j in range(3):
            LastPos[i][j] = True
        for j in range(7, 9):
            LastPos[i][j] = True
            
    
        
    
    #create instance of a AD7147 class
    AD = AD7147()
    '''checks if the connection is made and ID checks out'''
    AD.CheckID()
    ''' WRITE TO BANK1 AND BANK2'''
    AD.writeBank1_2()
    
    AD.RegToArray(ActualPos)
    if not (ActualPos == LastPos):
        print ("POLA SA NEROVNAJU")
    
    #instance of the position class in sunfishChessEngine module
    hist = [sunfishChessEngine.Position(sunfishChessEngine.initial, 0, (True, True), (True, True), 0, 0)]
    #instance of the engine searcher class
    searcher = sunfishChessEngine.Searcher()
    
    #instance of the class for controling motors
    mechanism = Mechanics()
    
    #if initial board is not equal to actual wait until it is
    while not (ActualPos == LastPos):
        AD.RegToArray(ActualPos)
        print ("initial not equal to actual")
        sleep_ms(100)
    
    
    while(True):
        CAPTURE = False
        KNIGHTMOVE = False
        KINGMOVE = False
        gc.collect()
        AD.RegToArray(ActualPos) # READ ALL CHESS SQUARES TO THIS 2D ARRAY every cycle
        
        #read move from user and convert to move readable by engine
        for x in range(1,fil):
            for y in range(1,rank):
                if not (ActualPos[x][y] == LastPos[x][y]):
                    CNT += 1
                    if CNT == 1:
                        print("CNT 1")
                        UserMove[0] = AD.parseSensorToEngine(x,y)
                        UserMove[1] = AD.parseSensorToEngine(x,y)
                        LastPos[x][y] = ActualPos[x][y]
                    else:
                        print("CNT 2")
                        if not (ActualPos[x][y]):
                            UserMove[0] = AD.parseSensorToEngine(x,y)
                            LastPos = ActualPos
                        else:
                            UserMove[1] = AD.parseSensorToEngine(x,y)
                            LastPos = ActualPos
        if (CNT == 2):
            CNT = 0
            hist.append(hist[-1].move(UserMove))
            # Limit the history size. (QL)
            hist_remained = hist[-8:]
            hist.clear()
            hist.extend(hist_remained)
            
            #if hist[-1].score <= -MATE_LOWER:
                #print("You won")
                #break
            # Fire up the engine to look for a move.
            start = time.ticks_ms()
            for _depth, CompMove, score in searcher.search(hist[-1], hist):
                if time.ticks_diff(time.ticks_ms(), start) > 1000:
                    break
            CompMoveArr = [0,0]
            CompMoveArr[0] = CompMove[0]
            CompMoveArr[1] = CompMove[1]
            #print(CompMoveArr)
               
            if hist[-1].board[CompMove[0]] == "N":# or hist[-1].board[move[0]] == "n":
                KNIGHTMOVE = True
            if not(hist[-1].board[CompMove[1]] == "."):
                CAPTURE = True
            if hist[-1].board[CompMove[0]] == "K":# or hist[-1].board[move[0]] == "n":
                KINGMOVE = True
            hist.append(hist[-1].move(CompMove))
            
            mechanism.EngineMove(move = CompMoveArr, capture = CAPTURE, KingMove = KINGMOVE, KnightMove = KNIGHTMOVE)
            sleep_ms(200)
            AD.RegToArray(ActualPos)
            LastPos = ActualPos
            
        sleep_ms(300)



if __name__ == "__main__":
    main()    
    
    
    
    
    
    
    
    
    
    
    