Untitled

 avatar
unknown
plain_text
10 months ago
8.6 kB
19
Indexable
import pyautogui, time
BOARD_SIZE = 6
pyautogui.FAILSAFE = True

class Screen:
    def __init__(self):
        #   TODO: ???
        self.__x0 = 518
        self.__y0 = 302
        self.__pixel_moon = (76, 140, 230)
        self.__pixel_sun = (255, 179, 30)
    def fillCell(self, i, j, isSun):
        # DIFFERENCE BETWEEN SQUARES IS 66 PX
        if(isSun):
            pyautogui.click(self.__x0 + i * 66, self.__y0 + j * 66)
        else:
            pyautogui.click(self.__x0 + i * 66, self.__y0 + j * 66, clicks=2)

    def changeToGame(self):
        pyautogui.keyDown('alt')
        pyautogui.press('tab')    # press tab while alt down
        pyautogui.keyUp('alt')
    def readGame(self):
        board_string = ""
        for i in range(BOARD_SIZE):
            for j in range(BOARD_SIZE):
                my_pixel = pyautogui.pixel(self.__x0 + j * 66, self.__y0 + i * 66)
                if (my_pixel == self.__pixel_moon): board_string += "0"
                elif (my_pixel == self.__pixel_sun): board_string += "1"
                else: board_string += "."
        return board_string

    def playGame(self):
        self.changeToGame()
        tango_string = self.readGame()
        tango_board = Board(tango_string)
        tango_board.display()
        tango_board.solve()
        tango_original = Board(tango_string)
        for i in range(BOARD_SIZE):
            for j in range(BOARD_SIZE):
                isSun = True if tango_board.get(j, i) == 1 else False
                if(tango_string[6 * j + i] == "."):
                    self.fillCell(i, j, isSun)



        


class Board:
    def __init__(self, board_string = None, size = 6):
        self.__board = [['.' for _ in range(size)] for _ in range(size)]
        self.__size = size
        # represents the sum of numbers in a given row
        # so rowsum[2] represents the sum of all numbers in the 3rd row
        # . . .
        # . . .
        # a b c Here, the variable changing is in the columns VV
        #       rowsum[2] = a + b + c = sum over i (matrix[2][i])
        self.__rowsum = [0 for _ in range(size)] 
        self.__colsum = [0 for _ in range(size)]
        self.__amountInCol = [0 for _ in range(size)]
        self.__amountInRow = [0 for _ in range(size)]
        if board_string is not None:
            for i in range(size):
                for j in range(size):
                    if board_string[size*i + j] == "1":
                        self.__board[i][j] = 1
                        self.__rowsum[i] += 1
                        self.__colsum[j] += 1
                        self.__amountInRow[i] += 1
                        self.__amountInCol[j] += 1

                    elif board_string[size*i + j] == "0":
                        self.__board[i][j] = 0
                        self.__rowsum[i] -= 1
                        self.__colsum[j] -= 1
                        self.__amountInRow[i] += 1
                        self.__amountInCol[j] += 1

                    else:
                        self.__board[i][j] = '.'

    def update_stats(self, i, j, value):
        self.__amountInRow[i] += 1
        self.__amountInCol[j] += 1
        if (value == 1):
            self.__rowsum[i] += 1
            self.__colsum[j] += 1
        else:
            self.__rowsum[i] -= 1
            self.__colsum[j] -= 1

    def set(self, i, j, value):
        if (value != 0 and value != 1):
            raise Exception("Board can only accept values of 0 or 1.")
        if (self.__board[i][j] != '.'): return
        
        self.__board[i][j] = value
        self.update_stats(i, j, value)

    def get(self, i, j):
        return self.__board[i][j]
    
    def display(self):
        for i in range(self.__size): #print("hello", end="")   
            for j in range(self.__size):
                print(self.__board[i][j], end = " ")
            print()
        print()
    
    def print_rowsum(self):
        print(self.__rowsum)

    def print_colsum(self):
        print(self.__colsum)

    def fillRemaining(self):
        for i in range(self.__size):
            if self.__amountInRow[i] == self.__size - 1:
                for j in range(self.__size):
                    if (self.get(i, j) == '.'):
                        self.set(i, j, 0 if self.__rowsum[i] == 1 else 1)
                        break
        for j in range(BOARD_SIZE):
            if self.__amountInCol[j] == self.__size - 1:
                for i in range(self.__size):
                    if (self.get(i, j) == '.'):
                        self.set(i, j, 0 if self.__colsum[j] == 1 else 1)
                        break
    def blockTriples(self):
        # FOR THE HORIZONTAL TRIPLETS
        for i in range(self.__size):
            for j in range(self.__size):
                squares = [0 for _ in range(3)]
                for k in range(3):
                    squares[k] = self.get(i, (j + k) % self.__size)
                self.findAndBlockTriple(squares, i, j, True)
        # FOR THE VERTICAL TRIPLETS
        for j in range(self.__size):
            for i in range(self.__size):
                squares = [0 for _ in range(3)]
                for k in range(3):
                    squares[k] = self.get((i + k) % self.__size, j)
                self.findAndBlockTriple(squares, i, j, False)

    # findTriple:
    # Takes in a triplet of squares, and checks if they have exactly one
    # missing square. If not, returns -1
    # If yes, then it checks if they are the same. If they are, it returns
    # what should be in the third square
    # If they are not the same, also returns -1

    def setRightPiece(self, squares, i, j, period_coord, filled_coord, horiz):
        if(horiz):
            self.set(i, (j + period_coord) % self.__size, 1 - squares[filled_coord])
        else:
            self.set((i + period_coord) % self.__size, j, 1 - squares[filled_coord])

    def findAndBlockTriple(self, squares, i, j, horiz):
        period_count = 0
        for k in range(3):
            if (squares[k] == '.'): period_count += 1
        if (period_count != 1): return

        filled_sum = 0
        filled_coord = 0
        period_coord = 0
        for k in range(3):
            if (squares[k] != '.'): 
                filled_sum += squares[k]
                filled_coord = k
            else: period_coord = k
        if (filled_sum % 2 == 0):
            self.setRightPiece(squares, i, j, period_coord, filled_coord, horiz)

    def notSolved(self):
        for i in range(0, self.__size):
            if (self.__amountInCol[i] != 6): return True
        return False
    def solve(self):
        while(self.notSolved()):
            self.blockTriples()
            self.display()
            self.fillRemaining()
            self.display()





                    # TODO: READ THIS!! (really cool idea)
    #   README: DON'T HAVE TO DO THIS, THE TRIPLE AND THE 5TH COMPLETE
    # STRATEGIES ALREADY COMBINED MAKE THIS WHENEVER WE WANT

    # TODO: MAKE A SIMPLE STRATEGY TO COUNT THE NUMBER OF
    # MOONS/SUNS IN A ROW OR COLUMN AND FILL OUT THE REST IN CASE
    # IT'S ALREADY 3 (OR BOARD_SIZE/2)


                    # TODO: READ THIS!! (really cool idea)
    # (harder): MAKE THE ADVANCED STRATEGY OF WHEN YOU HAVE TWO
    # OF THE SAME THING ON ONE SIDE OF THE BOARD IT DEDUCTS SOMETHING
    # ON THE OTHER SIDE (my good strategy for tango)
    # CAN BE ANY TWO OF THE FOLLOWING THREE:
    # X X . . . X
    # THAT IS, IF ANY TWO OF THESE THREE ARE EQUAL, THEN THE THIRD
    # HAS TO BE DIFFERENT
    # README
    # MAYBE IMPLEMENT THIS AS A "COUNTERPART" TO blockTriples 
    # (because this is essentially saying you cant have 3 in the same)
    # configuration but the opposite
    # README
    # this could be implemented normally with blockTriples
    # if we deal with wraparound (i.e. mod 6)
    # so maybe not harder after all






# for i in range(5):
    # tango_board.display()
    # tango_board.blockTriples()
    # tango_board.display()
    # tango_board.fillRemaining()

my_screen = Screen()
my_screen.playGame()

"""
RULES FOR TANGO:
    * CANNOT HAVE 3 OF THE SAME CONSECUTIVELY

    * MUST HAVE SAME NUMBER OF THINGS IN EACH LINE AND COLUMN

    * DEAL WITH = AND X (LATER)



"""

# Cool 50/50 board:
#
# 1 0 1 . 0 . 
# 0 1 0 . 1 . 
# 1 1 0 1 0 0 
# 1 0 1 0 0 1 
# 0 0 1 0 1 1 
# 0 1 0 1 1 0 
Editor is loading...
Leave a Comment