예제 #1
0
    def test_copy_patch(self):
        tetris_array_top = [1, 0]
        tetris_array_mid = [1, 1]
        tetris_array_bot = [1, 0]

        tetris_array = [tetris_array_top, tetris_array_mid, tetris_array_bot]
        tetris = Patch(1, tetris_array, 2, 3, 0)

        self.assertEqual(tetris.shape, tetris_array)
        self.assertEqual(tetris.orientation, tetris_array)
        self.assertEqual(tetris.cost, 2)
        self.assertEqual(tetris.time_cost, 3)
        self.assertEqual(tetris.button_gen, 0)

        copy = tetris.copy()

        self.assertEqual(copy.shape, tetris_array)
        self.assertEqual(copy.orientation, tetris_array)
        self.assertEqual(copy.cost, 2)
        self.assertEqual(copy.time_cost, 3)
        self.assertEqual(copy.button_gen, 0)

        tetris.rotate_cw()

        tetris_array_cw_top = [1, 1, 1]
        tetris_array_cw_mid = [0, 1, 0]

        tetris_array_rotated = [tetris_array_cw_top, tetris_array_cw_mid]

        self.assertEqual(tetris.shape, tetris_array)
        self.assertEqual(tetris.orientation, tetris_array_rotated)
        self.assertEqual(tetris.cost, 2)
        self.assertEqual(tetris.time_cost, 3)
        self.assertEqual(tetris.button_gen, 0)

        self.assertEqual(copy.shape, tetris_array)
        self.assertEqual(copy.orientation, tetris_array)
        self.assertEqual(copy.cost, 2)
        self.assertEqual(copy.time_cost, 3)
        self.assertEqual(copy.button_gen, 0)

        copy.rotate_cw()

        self.assertEqual(tetris.shape, tetris_array)
        self.assertEqual(tetris.orientation, tetris_array_rotated)
        self.assertEqual(tetris.cost, 2)
        self.assertEqual(tetris.time_cost, 3)
        self.assertEqual(tetris.button_gen, 0)

        self.assertEqual(copy.shape, tetris_array)
        self.assertEqual(copy.orientation, tetris_array_rotated)
        self.assertEqual(copy.cost, 2)
        self.assertEqual(copy.time_cost, 3)
        self.assertEqual(copy.button_gen, 0)
예제 #2
0
    def test_player_jump_simple(self):
        p1 = Player(1)
        p2 = Player(2)

        track = TimeTrack()

        #placing piece to kick off button generation
        tetris_array_top = [1, 0, 0]
        tetris_array_mid = [1, 1, 0]
        tetris_array_bot = [1, 0, 0]
        tetris_array = [tetris_array_top, tetris_array_mid, tetris_array_bot]
        tetris = Patch(1, tetris_array, 2, 3, 3)
        p1.quilt.place_patch(tetris, 0, 0)

        p2.position = 3

        p1.jump(track, p2)

        self.assertEqual(p1.position, 4)
        self.assertEqual(p1.buttons, 9)

        p2.position = 5

        self.assertEqual(p1.jump(track, p2), False)

        self.assertEqual(p1.position, 6)
        self.assertEqual(p1.buttons, 14)

        p2.position = 19

        self.assertEqual(p1.jump(track, p2), True)
예제 #3
0
    def test_patch_rotate(self):
        tetris_array_top = [1, 0]
        tetris_array_mid = [1, 1]
        tetris_array_bot = [1, 0]

        tetris_array = [tetris_array_top, tetris_array_mid, tetris_array_bot]
        tetris = Patch(1, tetris_array, 2, 3, 0)

        tetris_array_cw_top = [1, 1, 1]
        tetris_array_cw_mid = [0, 1, 0]

        tetris_array_rotated = [tetris_array_cw_top, tetris_array_cw_mid]

        self.assertEqual(tetris.shape, tetris_array)
        self.assertEqual(tetris.orientation, tetris_array)

        tetris.rotate_cw()

        self.assertEqual(tetris.shape, tetris_array)
        self.assertEqual(tetris.orientation, tetris_array_rotated)
예제 #4
0
    def test_placement(self):
        board = QuiltBoard()

        board.board_array[0][1] = 1
        board.board_array[1][0] = 1
        board.board_array[1][1] = 1

        row, col, patch_orientation = PatchworkAI().choose_placement(
            Patch(1, [[1]], 0, 0, 0), board)

        self.assertEqual(row, 0)
        self.assertEqual(col, 0)
예제 #5
0
    def test_player_move_simple(self):
        p1 = Player(1)
        p2 = Player(2)

        tetris_array_top = [1, 0, 0]
        tetris_array_mid = [1, 1, 0]
        tetris_array_bot = [1, 0, 0]
        tetris_array = [tetris_array_top, tetris_array_mid, tetris_array_bot]
        tetris = Patch(1, tetris_array, 2, 3, 3)

        p1.quilt.place_patch(tetris, 0, 0)

        track = TimeTrack()

        self.assertEqual(p1.position, 0)

        p1.move(4, track, p2)

        self.assertEqual(p1.position, 4)
        self.assertEqual(p1.buttons, 5)

        p1.move(1, track, p2)

        self.assertEqual(p1.position, 5)
        self.assertEqual(p1.buttons, 8)

        no_tile = p1.move(14, track, p2)

        self.assertEqual(p1.position, 19)
        self.assertEqual(p1.buttons, 14)
        self.assertEqual(no_tile, False)

        tile = p1.move(1, track, p2)

        self.assertEqual(p1.position, 20)
        self.assertEqual(p1.buttons, 14)
        self.assertEqual(tile, True)

        p1.move(32, track, p2)

        self.assertEqual(p1.position, 52)
        self.assertEqual(p1.buttons, 29)

        p1.move(1, track, p2)

        self.assertEqual(p1.position, 53)
        self.assertEqual(p1.buttons, 32)

        p1.move(2, track, p2)

        self.assertEqual(p1.position, 53)
        self.assertEqual(p1.buttons, 32)
예제 #6
0
    def test_patch_flip(self):
        tetris_array_top = [1, 0]
        tetris_array_mid = [1, 1]
        tetris_array_bot = [1, 0]

        tetris_array = [tetris_array_top, tetris_array_mid, tetris_array_bot]
        tetris = Patch(2, tetris_array, 2, 3, 0)

        tetris_array_flip_top = [0, 1]
        tetris_array_flip_mid = [1, 1]
        tetris_array_flip_bot = [0, 1]

        tetris_array_flipped = [
            tetris_array_flip_top, tetris_array_flip_mid, tetris_array_flip_bot
        ]

        self.assertEqual(tetris.shape, tetris_array)
        self.assertEqual(tetris.orientation, tetris_array)

        tetris.flip()

        self.assertEqual(tetris.shape, tetris_array)
        self.assertEqual(tetris.orientation, tetris_array_flipped)

        l_array_top = [1, 0]
        l_array_mid = [1, 0]
        l_array_bot = [1, 1]

        l_array = [l_array_top, l_array_mid, l_array_bot]
        l_patch = Patch(1, l_array, 2, 3, 0)

        l_array_flip_top = [0, 1]
        l_array_flip_mid = [0, 1]
        l_array_flip_bot = [1, 1]

        l_array_flipped = [
            l_array_flip_top, l_array_flip_mid, l_array_flip_bot
        ]

        self.assertEqual(l_patch.shape, l_array)
        self.assertEqual(l_patch.orientation, l_array)

        l_patch.flip()

        self.assertEqual(l_patch.shape, l_array)
        self.assertEqual(l_patch.orientation, l_array_flipped)
예제 #7
0
    def test_player_buy_patch(self):
        p1 = Player(1)
        p2 = Player(2)

        p1.buttons = 5

        track = TimeTrack()

        tetris_array_top = [1, 0, 0]
        tetris_array_mid = [1, 1, 0]
        tetris_array_bot = [1, 0, 0]
        tetris_array = [tetris_array_top, tetris_array_mid, tetris_array_bot]
        tetris = Patch(1, tetris_array, 2, 3, 3)

        p1.buy_patch(tetris, track, p2)

        self.assertEqual(p1.position, 3)
        self.assertEqual(p1.buttons, 3)
예제 #8
0
    def test_valid_placement(self):
        tetris_array_top = [1, 0, 0]
        tetris_array_mid = [1, 1, 0]
        tetris_array_bot = [1, 0, 0]

        tetris_array = [tetris_array_top, tetris_array_mid, tetris_array_bot]
        tetris = Patch(1, tetris_array, 2, 3, 0)

        new_board = QuiltBoard()

        self.assertEqual(new_board.valid_placement(tetris, 0, 0), True)
        self.assertEqual(new_board.valid_placement(tetris, 0, 7), True)
        self.assertEqual(new_board.valid_placement(tetris, 0, 8), False)
        self.assertEqual(new_board.valid_placement(tetris, 6, 0), True)
        self.assertEqual(new_board.valid_placement(tetris, 7, 0), False)

        new_board.place_patch(tetris, 0, 0)

        self.assertEqual(new_board.valid_placement(tetris, 0, 0), False)
        self.assertEqual(new_board.valid_placement(tetris, 0, 1), False)
예제 #9
0
    def test_place_patch(self):
        tetris_array_top = [1, 0, 0]
        tetris_array_mid = [1, 1, 0]
        tetris_array_bot = [1, 0, 0]

        test_board_array = [[0 for row in range(9)] for col in range(9)]

        tetris_array = [tetris_array_top, tetris_array_mid, tetris_array_bot]
        tetris = Patch(1, tetris_array, 2, 3, 0)

        new_board = QuiltBoard()

        self.assertEqual(new_board.board_array, test_board_array)

        new_board.place_patch(tetris, 0, 0)

        test_board_array[0][0] = 1
        test_board_array[1][0] = 1
        test_board_array[2][0] = 1
        test_board_array[1][1] = 1

        self.assertEqual(new_board.board_array, test_board_array)
예제 #10
0
    def mainloop(self):

        time_track_x = (self.WIDTH - (self.WIDTH / 3) - 1)
        piece_list_x = (self.WIDTH - (self.WIDTH / 6))

        track_scroll_y = 0
        piece_scroll_y = 0

        highlighted_patch_idx = 0
        selected_patch = None
        selected_patch_row = 0
        selected_patch_col = 0

        #current phase of a turn
        phase = MovePhase.BUYPHASE

        while self.running:
            if self.model.p1_turn():
                player = self.model.p1
                other_player = self.model.p2
            else:
                player = self.model.p2
                other_player = self.model.p1
            #Don't do any more processing if the game is over
            #if self.model.game_over():
            #	self.view.render(self.model, phase, track_scroll_y, piece_scroll_y, highlighted_patch_idx, selected_patch, selected_patch_row, selected_patch_col)

            #else:
            mouse_x, mouse_y = pygame.mouse.get_pos()

            #EVENT HANDLING
            #p1 is the human player
            if self.model.p1_turn() or phase == MovePhase.SPECIAL_PLACEPHASE:
                for event in pygame.event.get():
                    if event.type == pygame.MOUSEBUTTONDOWN:
                        #if mouse is hovering the time track, scroll the time track
                        if (mouse_x >= time_track_x
                                and mouse_x < piece_list_x):
                            if event.button == 4:
                                track_scroll_y = min(track_scroll_y + 30, 0)
                            if event.button == 5:
                                track_scroll_y = max(track_scroll_y - 30,
                                                     -self.HEIGHT * 8)
                        #if mouse is hovering the patch list, scroll the patch list
                        if (mouse_x >= piece_list_x):
                            if event.button == 4:
                                piece_scroll_y = min(piece_scroll_y + 30, 0)
                            if event.button == 5:
                                piece_scroll_y = max(piece_scroll_y - 30,
                                                     -self.HEIGHT * 4)
                    if event.type == pygame.KEYUP:
                        #if in the buy phase up/down arrows should change the selected pice
                        if phase == MovePhase.BUYPHASE:
                            if event.key == pygame.K_DOWN:
                                if highlighted_patch_idx < 2:
                                    highlighted_patch_idx += 1
                            if event.key == pygame.K_UP:
                                if highlighted_patch_idx > 0:
                                    highlighted_patch_idx -= 1
                            if event.key == pygame.K_RETURN:
                                #if the patch is purchasable by the current player, enter placement mode
                                if self.model.can_buy(highlighted_patch_idx):
                                    selected_patch = self.model.patch_list[
                                        highlighted_patch_idx]
                                    phase = MovePhase.PLACEPHASE
                            if event.key == pygame.K_TAB:
                                #check for 1x1 placement
                                passed_patch, passed_econ = self.model.jump()
                                if passed_patch:
                                    phase = MovePhase.SPECIAL_PLACEPHASE
                                    selected_patch = Patch(34, [[1]], 0, 0, 0)

                        if phase == MovePhase.PLACEPHASE or phase == MovePhase.SPECIAL_PLACEPHASE:
                            #if phase == MovePhase.PLACEPHASE:
                            if event.key == pygame.K_UP:
                                if selected_patch_row > 0:
                                    selected_patch_row -= 1
                            if event.key == pygame.K_DOWN:
                                if selected_patch_row < 8:
                                    selected_patch_row += 1
                            if event.key == pygame.K_LEFT:
                                if selected_patch_col > 0:
                                    selected_patch_col -= 1
                            if event.key == pygame.K_RIGHT:
                                if selected_patch_col < 8:
                                    selected_patch_col += 1
                            if event.key == pygame.K_SPACE:
                                selected_patch.rotate_cw()
                            if event.key == pygame.K_w or event.key == pygame.K_s:
                                selected_patch.flip()
                            if event.key == pygame.K_RSHIFT or event.key == pygame.K_LSHIFT:
                                if self.model.can_place(
                                        selected_patch, selected_patch_row,
                                        selected_patch_col):
                                    #if in placephase, buy the patch to advance to next phase
                                    if phase == MovePhase.PLACEPHASE:
                                        #check for 1x1 placement
                                        self.model.place_patch(
                                            player, self.model.
                                            patch_list[highlighted_patch_idx],
                                            selected_patch_row,
                                            selected_patch_col)
                                        passed_patch, passed_econ = self.model.buy_patch(
                                            highlighted_patch_idx)
                                        if passed_patch:
                                            phase = MovePhase.SPECIAL_PLACEPHASE
                                            selected_patch = Patch(
                                                34, [[1]], 0, 0, 0)
                                        else:
                                            phase = MovePhase.BUYPHASE
                                    #else in special place phase, phase ends when piece is placed (dont need to buy)
                                    else:
                                        self.model.place_patch(
                                            other_player, selected_patch,
                                            selected_patch_row,
                                            selected_patch_col)
                                        phase = MovePhase.BUYPHASE

                    if event.type == pygame.QUIT:
                        self.running = False

            #AI turn
            else:
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        self.running = False

                turn = self.ai.choose_turn_hand_craft(self.model)
                if isinstance(turn, BuyTurn):
                    #TEMPORARY HANDLING FOR IF THE PIECE CANT BE PLACED, NEED NEW SOLUTION FOR THIS
                    if not self.ai.can_place(
                            self.model.patch_list[turn.patch_idx],
                            self.model.p2.quilt):
                        passes_patch, passes_econ = player.will_pass_tile(
                            other_player.position - player.position + 1,
                            self.model.time_track)
                        turn = JumpTurn(passes_patch, passes_econ)
                    else:
                        row, col, patch_orientation = self.ai.choose_placement(
                            self.model.patch_list[turn.patch_idx],
                            self.model.p2.quilt)
                        self.model.place_patch(player, patch_orientation, row,
                                               col)
                #place 1x1 patch
                passed_patch, passed_econ = turn.run(self.model, None)
                if passed_patch:
                    row, col, patch_orientation = self.ai.choose_placement(
                        Patch(34, [[1]], 0, 0, 0), self.model.p2.quilt)
                    self.model.place_patch(player, Patch(34, [[1]], 0, 0, 0),
                                           row, col)

                #RENDERING

            self.view.render(self.model, phase, track_scroll_y, piece_scroll_y,
                             highlighted_patch_idx, selected_patch,
                             selected_patch_row, selected_patch_col)

        pygame.quit()
    def mainloop(self):

        time_track_x = (self.WIDTH - (self.WIDTH / 3) - 1)
        piece_list_x = (self.WIDTH - (self.WIDTH / 6))

        track_scroll_y = 0
        piece_scroll_y = 0

        highlighted_patch_idx = 0
        selected_patch = None
        selected_patch_row = 0
        selected_patch_col = 0

        #current player
        #TODO: should be a better way to do this than just if statements on this variable
        p1_turn = self.model.p1_turn()

        #current phase of a turn
        phase = MovePhase.BUYPHASE

        while self.running:
            if self.model.p1_turn():
                player = self.model.p1
                other_player = self.model.p2
            else:
                player = self.model.p2
                other_player = self.model.p1
            #Don't do any more processing if the game is over
            #if self.model.game_over():
            #	self.view.render(self.model, phase, track_scroll_y, piece_scroll_y, highlighted_patch_idx, selected_patch, selected_patch_row, selected_patch_col)

            #else:
            mouse_x, mouse_y = pygame.mouse.get_pos()

            #EVENT HANDLING
            for event in pygame.event.get():
                if event.type == pygame.MOUSEBUTTONDOWN:
                    #if mouse is hovering the time track, scroll the time track
                    if (mouse_x >= time_track_x and mouse_x < piece_list_x):
                        if event.button == 4:
                            track_scroll_y = min(track_scroll_y + 30, 0)
                        if event.button == 5:
                            track_scroll_y = max(track_scroll_y - 30,
                                                 -self.HEIGHT * 8)
                    #if mouse is hovering the patch list, scroll the patch list
                    if (mouse_x >= piece_list_x):
                        if event.button == 4:
                            piece_scroll_y = min(piece_scroll_y + 30, 0)
                        if event.button == 5:
                            piece_scroll_y = max(piece_scroll_y - 30,
                                                 -self.HEIGHT * 4)
                if event.type == pygame.KEYUP:
                    #if in the buy phase up/down arrows should change the selected pice
                    if phase == MovePhase.BUYPHASE:
                        if event.key == pygame.K_DOWN:
                            if highlighted_patch_idx < 2:
                                highlighted_patch_idx += 1
                        if event.key == pygame.K_UP:
                            if highlighted_patch_idx > 0:
                                highlighted_patch_idx -= 1
                        if event.key == pygame.K_RETURN:
                            #if the patch is purchasable by the current player, enter placement mode
                            if self.model.can_buy(highlighted_patch_idx):
                                selected_patch = self.model.patch_list[
                                    highlighted_patch_idx]
                                phase = MovePhase.PLACEPHASE
                        if event.key == pygame.K_TAB:
                            #check for 1x1 placement
                            if self.model.jump():
                                phase = MovePhase.SPECIAL_PLACEPHASE
                                selected_patch = Patch([[1]], 0, 0, 0)

                    if phase == MovePhase.PLACEPHASE or phase == MovePhase.SPECIAL_PLACEPHASE:
                        #if phase == MovePhase.PLACEPHASE:
                        if event.key == pygame.K_UP:
                            if selected_patch_row > 0:
                                selected_patch_row -= 1
                        if event.key == pygame.K_DOWN:
                            if selected_patch_row < 8:
                                selected_patch_row += 1
                        if event.key == pygame.K_LEFT:
                            if selected_patch_col > 0:
                                selected_patch_col -= 1
                        if event.key == pygame.K_RIGHT:
                            if selected_patch_col < 8:
                                selected_patch_col += 1
                        if event.key == pygame.K_SPACE:
                            selected_patch.rotate_cw()
                        if event.key == pygame.K_RSHIFT or event.key == pygame.K_LSHIFT:
                            if self.model.can_place(selected_patch,
                                                    selected_patch_row,
                                                    selected_patch_col):
                                #if in placephase, buy the patch to advance to next phase
                                if phase == MovePhase.PLACEPHASE:
                                    #check for 1x1 placement
                                    self.model.place_patch(
                                        player, self.model.
                                        patch_list[highlighted_patch_idx],
                                        selected_patch_row, selected_patch_col)
                                    passed_patch, passed_button_gen = self.model.buy_patch(
                                        highlighted_patch_idx)
                                    if passed_patch:
                                        phase = MovePhase.SPECIAL_PLACEPHASE
                                        selected_patch = Patch(
                                            34, [[1]], 0, 0, 0)
                                    else:
                                        phase = MovePhase.BUYPHASE
                                #else in special place phase, phase ends when piece is placed (dont need to buy)
                                else:
                                    self.model.place_patch(
                                        other_player, selected_patch,
                                        selected_patch_row, selected_patch_col)
                                    phase = MovePhase.BUYPHASE

                if event.type == pygame.QUIT:
                    self.running = False

            #RENDERING
            self.view.render(self.model, phase, track_scroll_y, piece_scroll_y,
                             highlighted_patch_idx, selected_patch,
                             selected_patch_row, selected_patch_col)

        pygame.quit()
예제 #12
0
	def build_patch_list(self):
		p1_r1 = [0, 1, 1] 
		p1_r2 = [0, 1, 1]
		p1_r3 = [1, 1, 0]
		p1_array = [p1_r1, p1_r2, p1_r3]
		p1 = Patch(1, p1_array, 8, 6, 3)

		p2_r1 = [0, 1, 0]
		p2_r2 = [0, 1, 0]
		p2_r3 = [1, 1, 1]
		p2_r4 = [0, 1, 0]
		p2_array = [p2_r1, p2_r2, p2_r3, p2_r4]
		p2 = Patch(2, p2_array, 0, 3, 1)

		p3_r1 = [1, 1, 0]
		p3_r2 = [0, 1, 0]
		p3_r3 = [0, 1, 0]
		p3_r4 = [0, 1, 1]
		p3_array = [p3_r1, p3_r2, p3_r3, p3_r4]
		p3 = Patch(3, p3_array, 1, 2, 0)

		p4_r1 = [1, 1]
		p4_r2 = [1, 0]
		p4_r3 = [1, 1]
		p4_array = [p4_r1, p4_r2, p4_r3]
		p4 = Patch(4, p4_array, 1, 2, 0)

		p5_r1 = [0, 1]
		p5_r2 = [0, 1]
		p5_r3 = [1, 1]
		p5_r4 = [0, 1]
		p5_array = [p5_r1, p5_r2, p5_r3, p5_r4]
		p5 = Patch(5, p5_array, 3, 4, 1)

		p6_r1 = [1, 0]
		p6_r2 = [1, 1]
		p6_r3 = [1, 1]
		p6_r4 = [0, 1]
		p6_array = [p6_r1, p6_r2, p6_r3, p6_r4]
		p6 = Patch(6, p6_array, 4, 2, 0)

		p7_r1 = [1, 0]
		p7_r2 = [1, 0]
		p7_r3 = [1, 1]
		p7_array = [p7_r1, p7_r2, p7_r3]
		p7 = Patch(7, p7_array, 4, 2, 1)

		p8_r1 = [0, 1, 0]
		p8_r2 = [1, 1, 1]
		p8_r3 = [1, 0, 1]
		p8_array = [p8_r1, p8_r2, p8_r3]
		p8 = Patch(8, p8_array, 3, 6, 2)

		p9_r1 = [0, 1]
		p9_r2 = [1, 1]
		p9_r3 = [0, 1]
		p9_array = [p9_r1, p9_r2, p9_r3]
		p9 = Patch(9, p9_array, 2, 2, 0)

		p10_r1 = [0, 1, 1, 0]
		p10_r2 = [1, 1, 1, 1]
		p10_array = [p10_r1, p10_r2]
		p10 = Patch(10, p10_array, 7, 4, 2)

		p11_r1 = [0, 1]
		p11_r2 = [1, 1]
		p11_r3 = [1, 0]
		p11_array = [p11_r1, p11_r2, p11_r3]
		p11 = Patch(11, p11_array, 3, 2, 1)

		p12_r1 = [0, 1]
		p12_r2 = [1, 1]
		p12_array = [p12_r1, p12_r2]
		p12 = Patch(12, p12_array, 1, 3, 0)

		p13_r1 = [0, 0, 1]
		p13_r2 = [0, 1, 1]
		p13_r3 = [1, 1, 0]
		p13_array = [p13_r1, p13_r2, p13_r3]
		p13 = Patch(13, p13_array, 10, 4, 3)

		p14_r1 = [1, 1, 1]
		p14_r2 = [0, 1, 0]
		p14_r3 = [1, 1, 1]
		p14_array = [p14_r1, p14_r2, p14_r3]
		p14 = Patch(14, p14_array, 2, 3, 0)

		p15_r1 = [0, 1, 0]
		p15_r2 = [0, 1, 0]
		p15_r3 = [1, 1, 1]
		p15_r4 = [0, 1, 0]
		p15_r5 = [0, 1, 0]
		p15_array = [p15_r1, p15_r2, p15_r3, p15_r4, p15_r5]
		p15 = Patch(15, p15_array, 1, 4, 1)

		p16_r1 = [1, 1, 1]
		p16_array = [p16_r1]
		p16 = Patch(16, p16_array, 2, 2, 0)

		p17_r1 = [1, 1, 1, 1]
		p17_array = [p17_r1]
		p17 = Patch(17, p17_array, 3, 3, 1)

		p18_r1 = [0, 1, 0]
		p18_r2 = [1, 1, 1]
		p18_r3 = [1, 1, 1]
		p18_r4 = [0, 1, 0]
		p18_array = [p18_r1, p18_r2, p18_r3, p18_r4]
		p18 = Patch(18, p18_array, 5, 3, 1)

		p19_r1 = [0, 1]
		p19_r2 = [0, 1]
		p19_r3 = [1, 1]
		p19_r4 = [1, 1]
		p19_array = [p19_r1, p19_r2, p19_r3, p19_r4]
		p19 = Patch(19, p19_array, 10, 5, 3)

		p20_r1 = [0, 1, 1, 1]
		p20_r2 = [1, 1, 0, 0]
		p20_array = [p20_r1, p20_r2]
		p20 = Patch(20, p20_array, 2, 3, 1)

		p21_r1 = [1, 0, 0, 1]
		p21_r2 = [1, 1, 1, 1]
		p21_array = [p21_r1, p21_r2]
		p21 = Patch(21, p21_array, 1, 5, 1)

		p22_r1 = [0, 0, 1, 0]
		p22_r2 = [1, 1, 1, 1]
		p22_r3 = [0, 1, 0, 0]
		p22_array = [p22_r1, p22_r2, p22_r3]
		p22 = Patch(22, p22_array, 2, 1, 0)

		p23_r1 = [0, 0, 0, 1]
		p23_r2 = [1, 1, 1, 1]
		p23_array = [p23_r1, p23_r2]
		p23 = Patch(23, p23_array, 10, 3, 2)

		p24_r1 = [1, 0, 0, 0]
		p24_r2 = [1, 1, 1, 1]
		p24_r3 = [1, 0, 0, 0]
		p24_array = [p24_r1, p24_r2, p24_r3]
		p24 = Patch(24, p24_array, 7, 2, 2)

		p25_r1 = [0, 1, 0]
		p25_r2 = [1, 1, 1]
		p25_r3 = [0, 1, 0]
		p25_array = [p25_r1, p25_r2, p25_r3]
		p25 = Patch(25, p25_array, 5, 4, 2)

		p26_r1 = [1, 1] 
		p26_r2 = [0, 1] 
		p26_r3 = [0, 1] 
		p26_array = [p26_r1, p26_r2, p26_r3]
		p26 = Patch(26, p26_array, 4, 6, 2)

		p27_r1 = [0, 1]
		p27_r2 = [1, 1]
		p27_r3 = [1, 1]
		p27_array = [p27_r1, p27_r2, p27_r3]
		p27 = Patch(27, p27_array, 2, 2, 0)

		p28_r1 = [0, 1, 1]
		p28_r2 = [1, 1, 0]
		p28_array = [p28_r1, p28_r2]
		p28 = Patch(28, p28_array, 7, 6, 3)

		p29_r1 = [0, 1]
		p29_r2 = [1, 1]
		p29_array = [p29_r1, p29_r2]
		p29 = Patch(29, p29_array, 3, 1, 0)

		p30_r1 = [0, 1, 0]
		p30_r2 = [0, 1, 0]
		p30_r3 = [1, 1, 1]
		p30_array = [p30_r1, p30_r2, p30_r3]
		p30 = Patch(30, p30_array, 5, 5, 2)

		p31_r1 = [1, 1]
		p31_r2 = [1, 1]
		p31_array = [p31_r1, p31_r2]
		p31 = Patch(31, p31_array, 6, 5, 2)

		p32_r1 = [1, 1, 1, 1, 1]
		p32_array = [p32_r1]
		p32 = Patch(32, p32_array, 7, 1, 1)

		p33_r1 = [1, 1]
		p33_array = [p33_r1]
		p33 = Patch(33, p33_array, 2, 1, 0)


		#TODO: There's gotta be a better way
		PATCH_LIST_CONST = [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, p28, p29, p30, p31, p32, p33]

		return PATCH_LIST_CONST
    def mainloop(self, num_samples):
        #run "num_samples" games and then calculate the win percentage
        p1_win = 0
        p1_running_sum = 0
        p2_running_sum = 0
        p1_win_count = 0
        p1_game_avgs = []
        p2_game_avgs = []
        p1_win_counts = []
        for i in range(num_samples):
            #reset the model for next game
            self.model = PatchworkModel()
            self.running = True

            while self.running:
                if self.model.p1_turn():
                    player = self.model.p1
                    other_player = self.model.p2
                else:
                    player = self.model.p2
                    other_player = self.model.p1

                #p1 is smart, p2 is dumb
                if self.model.p1_turn():
                    turn = self.ai.choose_turn_hand_craft(self.model)
                else:
                    turn = self.ai.choose_turn_random(self.model)

                if isinstance(turn, BuyTurn):
                    #TEMPORARY HANDLING FOR IF THE PIECE CANT BE PLACED, NEED NEW SOLUTION FOR THIS
                    if not self.ai.can_place(
                            self.model.patch_list[turn.patch_idx],
                            player.quilt):
                        turn = JumpTurn()
                    else:
                        row, col, patch_orientation = self.ai.choose_placement(
                            self.model.patch_list[turn.patch_idx],
                            player.quilt)
                        self.model.place_patch(player, patch_orientation, row,
                                               col)
                #run the turn (buy piece for buy, jump for jump), and check if patch is passed on time track
                passed_patch, passed_button_gen = turn.run(self.model)
                if passed_patch:
                    row, col, patch_orientation = self.ai.choose_placement(
                        Patch(34, [[1]], 0, 0, 0), other_player.quilt)
                    self.model.place_patch(other_player,
                                           Patch(34, [[1]], 0, 0, 0), row, col)

                #if game is over, exit running loop and update p1_win counter
                if self.model.game_over():
                    if self.model.p1_win() == 1:
                        p1_win += 1

                    #keep track of p1/p2 end scores to calculate averages at end (hoping to see progress)
                    if ((i + 1) % self.INTERVAL_SIZE) == 0:
                        p1_game_avgs.append(p1_running_sum /
                                            self.INTERVAL_SIZE)
                        p2_game_avgs.append(p2_running_sum /
                                            self.INTERVAL_SIZE)
                        p1_running_sum = 0
                        p2_running_sum = 0
                        p1_win_count = 0

                    p1_running_sum += self.model.p1.get_score()
                    p2_running_sum += self.model.p2.get_score()
                    if self.model.p1_win() == 1:
                        p1_win_count += 1

                    self.running = False

            #If there's only 1 sample just print out the basic output
            if num_samples == 2 or num_samples == 1:
                print("P1 score: " + str(self.model.p1.get_score()) +
                      ", P2 score: " + str(self.model.p2.get_score()))
                print("P1 buttons: " + str(self.model.p1.buttons) +
                      ", P2 buttons: " + str(self.model.p2.buttons))
                print("-------------------------------")
                print("P1 board")
                for row in range(9):
                    for col in range(9):
                        print(self.model.p1.quilt.board_array[row][col],
                              end="")
                    print()
                print("-------------------------------")
                print("P2 board")
                for row in range(9):
                    for col in range(9):
                        print(self.model.p2.quilt.board_array[row][col],
                              end="")
                    print()
                print("-------------------------------")

            if i == 0:
                print("Simulating", end="")
                sys.stdout.flush()
            elif (i % 4) == 0:
                sys.stdout.write("\b\b\b   \b\b\b")
                sys.stdout.flush()
            else:
                sys.stdout.write(".")
                sys.stdout.flush()

        print("Games run: " + str(num_samples))
        print("P1 wins: " + str(p1_win) + ", P2 wins: " +
              str(num_samples - p1_win))
        print("P1 win %: " + str((p1_win / num_samples) * 100) +
              ", P2 win %: " +
              str(((num_samples - p1_win) / num_samples) * 100))

        print()

        for i in range(len(self.ai.feature_weights["patch_weights_early"])):
            print("Patch ID: " + str(i + 1) + ", Early Weight: " +
                  str(self.ai.feature_weights["patch_weights_early"][i]) +
                  ", Mid Weight: " +
                  str(self.ai.feature_weights["patch_weights_mid"][i]) +
                  ", Late Weight: " +
                  str(self.ai.feature_weights["patch_weights_late"][i]))

        print()

        print("GAME AVGS: ")
        for i in range(len(p1_game_avgs)):
            print(
                str(i * self.INTERVAL_SIZE) + " - " +
                str((i * self.INTERVAL_SIZE) + self.INTERVAL_SIZE) +
                " | Player 1: " + str(p1_game_avgs[i]) + ", Player 2: " +
                str(p2_game_avgs[i]) + ", Difference: " +
                str(p1_game_avgs[i] - p2_game_avgs[i]))
    def mainloop_learning(self, num_samples):
        #run "num_samples" games and then calculate the win percentage
        p1_win = 0
        p1_running_sum = 0
        p2_running_sum = 0
        p1_win_count = 0
        p1_game_avgs = []
        p2_game_avgs = []
        p1_win_counts = []

        p1_button_gen_sum = 0
        p1_buttons_sum = 0
        p1_board_util_sum = 0

        p1_button_gen_sums = []
        p1_buttons_sums = []
        p1_board_util_sums = []
        p1_quilts = []

        p2_button_gen_sum = 0
        p2_buttons_sum = 0
        p2_board_util_sum = 0

        p2_button_gen_sums = []
        p2_buttons_sums = []
        p2_board_util_sums = []

        p1_jump_ct = 0
        p2_jump_ct = 0

        p1_buy_ct = 0
        p2_buy_ct = 0

        p1_delayed_jump_ct = 0
        p2_delayed_jump_ct = 0

        for i in range(num_samples):
            #reset the model for next game
            self.model = PatchworkModel()
            self.running = True

            self.p1_feature_state = FeatureStateModel(self.model.p1,
                                                      self.model.p2)
            self.p2_feature_state = FeatureStateModel(self.model.p2,
                                                      self.model.p1)

            while self.running:
                if self.model.p1_turn():
                    player = self.model.p1
                    state_model = self.p1_feature_state
                    other_player = self.model.p2
                else:
                    player = self.model.p2
                    state_model = self.p2_feature_state
                    other_player = self.model.p1

                #p1 is learning, p2 is hand crafted ai
                if self.model.p1_turn():
                    #picks turn based on learned weights and updates those weights
                    turn = self.ai.choose_turn_learning(
                        self.model, self.p1_feature_state,
                        self.feature_weights)
                else:
                    turn = self.ai.choose_turn_random(self.model)

                    #update weights based on p2 moves as well
                    future_state = self.ai.find_future_state(
                        turn, self.p2_feature_state)

                    reward = self.p2_feature_state.calculate_reward(
                        turn.passes_player, turn.passes_econ, 0)

                    self.feature_weights.update_feature_weights(
                        reward,
                        future_state.get_state_utility(self.feature_weights),
                        self.p2_feature_state)

                if isinstance(turn, JumpTurn):
                    #DEBUGGING
                    if self.model.p1_turn():
                        p1_jump_ct += 1
                    else:
                        p2_jump_ct += 1

                #handling turn running
                if isinstance(turn, BuyTurn):
                    #DEBUGGING
                    if self.model.p1_turn():
                        p1_buy_ct += 1
                    else:
                        p2_buy_ct += 1

                    #check if it's possible for the player to place the selected patch
                    if not self.ai.can_place(
                            self.model.patch_list[turn.patch_idx],
                            player.quilt):
                        passes_patch, passes_econ, passes_player = player.will_pass_tile(
                            other_player.position - player.position + 1,
                            self.model.time_track, other_player)
                        turn = JumpTurn(passes_patch, passes_econ,
                                        passes_player)
                        if self.model.p1_turn():
                            p1_buy_ct -= 1
                            p1_delayed_jump_ct += 1
                        else:
                            p2_buy_ct -= 1
                            p2_delayed_jump_ct += 1
                    else:
                        row, col, patch_orientation = self.ai.choose_placement(
                            self.model.patch_list[turn.patch_idx],
                            player.quilt)
                        self.model.place_patch(player, patch_orientation, row,
                                               col)
                #run the turn (buy piece for buy, jump for jump), and update passed_patch/passed_button_gen booleans
                passed_patch, passed_button_gen = turn.run(
                    self.model, state_model)

                #placing 1x1 patch if it was passed
                if passed_patch:
                    row, col, patch_orientation = self.ai.choose_placement(
                        Patch(34, [[1]], 0, 0, 0), other_player.quilt)
                    self.model.place_patch(other_player,
                                           Patch(34, [[1]], 0, 0, 0), row, col)

                #if game is over, exit running loop and update p1_win counter
                if self.model.game_over():
                    p1_rewards = self.p1_feature_state.calculate_reward(
                        False, True, self.model.p1_win())
                    p2_rewards = self.p2_feature_state.calculate_reward(
                        False, True, self.model.p1_win())

                    self.feature_weights.update_feature_weights(
                        p1_rewards,
                        self.p1_feature_state.get_state_utility(
                            self.feature_weights), self.p1_feature_state)
                    self.feature_weights.update_feature_weights(
                        p2_rewards,
                        self.p2_feature_state.get_state_utility(
                            self.feature_weights), self.p2_feature_state)

                    p1_quilts.append(self.model.p1.quilt.board_array)
                    #CALCULATING OUTPUTS FOR PROGRESS TRACKING
                    #keep track of p1/p2 end scores to calculate averages at end (hoping to see progress)
                    if ((i + 1) % self.INTERVAL_SIZE) == 0:
                        p1_game_avgs.append(p1_running_sum /
                                            self.INTERVAL_SIZE)
                        p2_game_avgs.append(p2_running_sum /
                                            self.INTERVAL_SIZE)
                        p1_win_counts.append(p1_win_count)
                        p1_running_sum = 0
                        p2_running_sum = 0
                        p1_win_count = 0

                        p1_button_gen_sums.append(p1_button_gen_sum /
                                                  self.INTERVAL_SIZE)
                        p1_buttons_sums.append(p1_buttons_sum /
                                               self.INTERVAL_SIZE)
                        p1_board_util_sums.append(p1_board_util_sum /
                                                  self.INTERVAL_SIZE)

                        p1_button_gen_sum = 0
                        p1_buttons_sum = 0
                        p1_board_util_sum = 0

                        p2_button_gen_sums.append(p2_button_gen_sum /
                                                  self.INTERVAL_SIZE)
                        p2_buttons_sums.append(p2_buttons_sum /
                                               self.INTERVAL_SIZE)
                        p2_board_util_sums.append(p2_board_util_sum /
                                                  self.INTERVAL_SIZE)

                        p2_button_gen_sum = 0
                        p2_buttons_sum = 0
                        p2_board_util_sum = 0

                    if self.model.p1_win() == 1:
                        p1_win_count += 1
                        p1_win += 1

                    p1_running_sum += self.model.p1.get_score()
                    p2_running_sum += self.model.p2.get_score()

                    p1_button_gen_sum += self.model.p1.quilt.button_gen
                    p1_buttons_sum += self.model.p1.buttons
                    p1_board_util_sum += self.ai.get_quilt_utility(
                        self.model.p1.quilt)

                    p2_button_gen_sum += self.model.p2.quilt.button_gen
                    p2_buttons_sum += self.model.p2.buttons
                    p2_board_util_sum += self.ai.get_quilt_utility(
                        self.model.p2.quilt)

                    #exit while loop, game is over
                    self.running = False

            #If there's only 1 sample just print out the basic output
            if num_samples == 2 or num_samples == 1:
                print("P1 score: " + str(self.model.p1.get_score()) +
                      ", P2 score: " + str(self.model.p2.get_score()))
                print("P1 buttons: " + str(self.model.p1.buttons) +
                      ", P2 buttons: " + str(self.model.p2.buttons))
                print("-------------------------------")
                print("P1 board")
                for row in range(9):
                    for col in range(9):
                        print(self.model.p1.quilt.board_array[row][col],
                              end="")
                    print()
                print("-------------------------------")
                print("P2 board")
                for row in range(9):
                    for col in range(9):
                        print(self.model.p2.quilt.board_array[row][col],
                              end="")
                    print()
                print("-------------------------------")

            if i == 0:
                print("Simulating", end="")
                sys.stdout.flush()
            elif (i % 4) == 0:
                sys.stdout.write("\b\b\b   \b\b\b")
                sys.stdout.flush()
            else:
                sys.stdout.write(".")
                sys.stdout.flush()

        print()
        print("Games run: " + str(num_samples))
        print("P1 wins: " + str(p1_win) + ", P2 wins: " +
              str(num_samples - p1_win))
        print("P1 win %: " + str((p1_win / num_samples) * 100) +
              ", P2 win %: " +
              str(((num_samples - p1_win) / num_samples) * 100))

        print()

        print("WEIGHTS: ")
        print("Button Gen Weight: " +
              str(self.feature_weights.button_gen_weight))
        print("Board Coverage Weight: " +
              str(self.feature_weights.board_coverage_weight))
        print("Button Weight: " + str(self.feature_weights.buttons_weight))
        print("Player Distance Weight: " +
              str(self.feature_weights.player_distance_weight))

        print()

        #f1 = open("ai_button_gen.txt", "w")
        #f2 = open("ai_button_total.txt", "w")
        #f3 = open("ai_quilt_coverage.txt", "w")
        #f4 = open("ai_score.txt", "w")
        #f5 = open("ai_score_diff.txt", "w")
        print("GAME AVGS: ")
        for i in range(len(p1_game_avgs)):
            print(
                str(i * self.INTERVAL_SIZE) + " - " +
                str((i * self.INTERVAL_SIZE) + self.INTERVAL_SIZE) +
                " | Player 1: " + str(p1_game_avgs[i]) + ", Player 2: " +
                str(p2_game_avgs[i]) + ", Difference: " +
                str(p1_game_avgs[i] - p2_game_avgs[i]) + ", P1 Wins: " +
                str(p1_win_counts[i]) + ", P2 Wins: " +
                str(self.INTERVAL_SIZE - p1_win_counts[i]) + ", P1 Win %: " +
                str((p1_win_counts[i] / self.INTERVAL_SIZE) * 100))
            #f.write(str((p1_win_counts[i]/5)*100) + ", ")

        print("AI TENDENCIES: ")
        print("P1 (LEARNED AI) FEATURE AVERAGES")
        for i in range(len(p1_button_gen_sums)):
            print(
                str(i * self.INTERVAL_SIZE) + " - " +
                str((i * self.INTERVAL_SIZE) + self.INTERVAL_SIZE) +
                " | Button Gen: " + str(p1_button_gen_sums[i]) +
                ", Buttons: " + str(p1_buttons_sums[i]) + ", Board Util: " +
                str(p1_board_util_sums[i]))
            #f1.write(str(p1_button_gen_sums[i]) + ", ")
            #f2.write(str(p1_buttons_sums[i]) + ", ")
            #f3.write(str(p1_board_util_sums[i]) + ", ")
            #f4.write(str(p1_game_avgs[i]) + ", ")
            #f5.write(str(p1_game_avgs[i] - p2_game_avgs[i]) + ", ")
        print()

        #print("QUILTS: ")
        #for i in range(len(p1_quilts)):
        #	print(str(i) + ":")
        #	for row in range(len(p1_quilts[i])):
        #		for col in range(len(p1_quilts[i][row])):
        #			print(p1_quilts[i][row][col], end = "")
        #		print()

        #	print()
        #	print()
        print("P2 (RANDOM AI) FEATURE AVERAGES")
        for i in range(len(p2_button_gen_sums)):
            print(
                str(i * self.INTERVAL_SIZE) + " - " +
                str((i * self.INTERVAL_SIZE) + self.INTERVAL_SIZE) +
                " | Button Gen: " + str(p2_button_gen_sums[i]) +
                ", Buttons: " + str(p2_buttons_sums[i]) + ", Board Util: " +
                str(p2_board_util_sums[i]))