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)
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)
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)
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)
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)
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)
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)
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)
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)
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()
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]))