def getThirds(self):
     thirds = []
     for n in self.P1.notS:
             P2 = NumericalSemigroup( self.P1.gens + [n] )
             if P2.isIrreducible()==False and n > 3:
                     thirds.append( n )
     return thirds
class GameState():

    def __init__( self, play1, play2 ):
        assert 1==isGCD( [play1, play2] ), "Initial 2 plays are not relatively prime"
        self.gameBoard = NumericalSemigroup( [play1, play2] )
        self.plays = [play1, play2]

    def makePlay( self, play ):
        assert play not in self.gameBoard.getInS(), "Invalid move; play already eliminated"
        self.plays.append( play )
        self.gameBoard = self.gameBoard.whatIfAddGens( self.plays )

    def getPlays( self ):
        return self.plays

    def getNextPlays( self ):
        return self.gameBoard.getNotInS()

    def getValidNextPlays( self ):
        thirds = []
        for n in self.gameBoard.getNotS():
                P2 = self.gameBoard.whatIfAddGens( [n] )
                if P2.isIrreducible()==False and n > 3:
                        thirds.append( n )
        return thirds

    def copy( self ):
        copy = GameState( self.plays[0], self.plays[1] )
        for n in self.plays[2:]:
            copy.makePlay( n )
        return copy
def checkit(situation):
    # print("working...")
    sety = NumericalSemigroup(situation).minGens
    # print( sety )
    nvect = ExhaustiveGame(NumericalSemigroup(situation)).thirds
    counter = 0

    if sety in good:
        return 1

    for n in nvect:

        P1 = NumericalSemigroup(sety + [n])
        gens = P1.minGens

        if gens in good:
            bad.append(sety)
            return 0
        elif gens in bad:
            counter += 1
        elif P1.isIrreducible() == True:
            bad.append(gens)
            counter += 1
        else:
            x = checkit(sety + [n])
            if x == 0:
                counter += 1
            elif x == 1:
                bad.append(sety)
                return 0

    if counter == len(nvect):
        if sety not in good:
            good.append(sety)
            return 1
 def generateOneGame(self, num):
     if num > 3:
         P2 = NumericalSemigroup( self.P1.gens + [num] )
         if P2.isIrreducible() == False:
             
             check = checker( P2 )
             self.soulDict[num] = check
             self.whichGamesGenerated()
             print("Generated {0} with {1} games".format( num, len(check)) )
             return check               
    def __init__(self, generators):
        NS = NumericalSemigroup( generators )

        self.nodes = NS.getNotS()[3:]
        self.hashFullGraph = {}
        for node in self.nodes:
            self.hashFullGraph[node] = []
            tempNS = NS.whatIfAddGens( [node] )
            
            extendedVals = tempNS.getInS()
            # Gets arcs even when they are larger than the new FS
            for val in range(max(tempNS.getInS()), max(NS.getNotS()), 1) : extendedVals.append( val )
            extendedVals = set( extendedVals )
            for dest in extendedVals:    
                if dest in NS.getNotS():
                    self.hashFullGraph[ node ] = self.hashFullGraph[node] + [dest]
            
        self.pairs = []
        for nodeOrigin in self.hashFullGraph:
            for nodeDest in self.hashFullGraph[ nodeOrigin ]:
                if not self.checkLongerPathExists( nodeOrigin, nodeDest ):
                    self.pairs.append( (nodeOrigin, nodeDest ) )
 def __init__( self, play1, play2 ):
     assert 1==isGCD( [play1, play2] ), "Initial 2 plays are not relatively prime"
     self.gameBoard = NumericalSemigroup( [play1, play2] )
     self.plays = [play1, play2]