def test_attach_tetromino_blocks(self): """Check if Tetromino is properly attached to board""" def check_if_attached_properly(gb: gameboard.Gameboard): """Check if for currently state of gameboard call attach_tetromino_blocks will attach blocks properly""" gb.attach_tetromino_blocks() x, y = gb.falling_tetromino.current_x, gb.falling_tetromino.current_y for y_shift, row in enumerate(gb.falling_tetromino.fields): for x_shift, block in enumerate(row): if block == config.BUFFER_BLOCK: # checks only Tetromino BUFFER_BLOCKS (only these are attached) self.assertEqual(gb.fields[y + y_shift][x + x_shift], config.FALLEN_BLOCK) # Case for Tetromino on initial position gb = gameboard.Gameboard() check_if_attached_properly(gb) # Case for Tetromino moved three times down gb = gameboard.Gameboard() for _ in range(3): gb.fall_tetromino_down() check_if_attached_properly(gb) # Case for Tetromino moved one time down, rotated and then shifted three times right gb = gameboard.Gameboard() gb.fall_tetromino_down() gb.falling_tetromino.rotate() gb.falling_tetromino.current_x += 3 check_if_attached_properly(gb)
def test_is_tetromino_colliding(self): gb = gameboard.Gameboard() self.assertEqual(gb.is_tetromino_colliding(), False) # Test for borders gb.falling_tetromino = tetromino.Tetromino("I", times_rotated=1, x=0) # for "I" shape, the most left block will overlaping with gameboard left border self.assertEqual(gb.is_tetromino_colliding(), True) gb.falling_tetromino = tetromino.Tetromino("I", times_rotated=1, x=config.BOARD_COLUMNS-4) self.assertEqual(gb.is_tetromino_colliding(), True) # for bottom row (border) gb.falling_tetromino = tetromino.Tetromino("Z", x=4, y=config.BOARD_ROWS-3) self.assertEqual(gb.is_tetromino_colliding(), True) # Test for some FALLEN BLOCKS gb.falling_tetromino = tetromino.Tetromino("Z", x=8, y=4) gb.fields[8][3] = config.FALLEN_BLOCK gb.fields[8][4] = config.FALLEN_BLOCK gb.fields[8][5] = config.FALLEN_BLOCK gb.fields[7][3] = config.FALLEN_BLOCK self.assertEqual(gb.is_tetromino_colliding(), True) # Check for changing single block from FALLEN to EMPTY (block witch causing collision) gb = gameboard.Gameboard() gb.falling_tetromino = tetromino.Tetromino("O", x=0, y=0) gb.fields[1][2] = config.FALLEN_BLOCK self.assertEqual(gb.is_tetromino_colliding(), True) gb.fields[1][2] = config.EMPTY_BLOCK self.assertEqual(gb.is_tetromino_colliding(), False)
def test_is_row_fully_filled(self): gb = gameboard.Gameboard() # It has no sense if bottom row is filled (it is built by BORDER_BLOCK and filled means built only by FALLEN_BLOCK) self.assertFalse(gb.is_row_fully_filled(gb.fields[config.BOARD_BOTTOM_ROW])) # The rest rows also should return False as new gameboard should have only empty rows (and one border at bottom) for row in gb.fields: self.assertFalse(gb.is_row_fully_filled(row)) for index in range(config.BOARD_FIRST_COLUMN, config.BOARD_LAST_COLUMN+1): gb.fields[0][index] = config.FALLEN_BLOCK self.assertTrue(gb.is_row_fully_filled(gb.fields[0])) # Return one block to EMPTY_BLOCK to check is row not fully filled gb.fields[0][4] = config.EMPTY_BLOCK self.assertFalse(gb.is_row_fully_filled(gb.fields[0])) # Next row has 4 blocks filled (FALLEN_BLOCK) and rest empty for index in range(config.BOARD_FIRST_COLUMN, config.BOARD_LAST_COLUMN+1, 3): gb.fields[1][index] = config.FALLEN_BLOCK self.assertFalse(gb.is_row_fully_filled(gb.fields[1])) # This row has only one block FALLEN gb.fields[2][1] = config.FALLEN_BLOCK self.assertFalse(gb.is_row_fully_filled(gb.fields[2]))
def initialize_gamestate(self, game_info): self.gamestate = gamestate.GameState( friendly_player=self.client.name, enemy_player='?', gameboard=gb.Gameboard(game_info['Width'], game_info['Height']), view_distance=game_info['FogOfWar']) self.gamestate.turn_number = game_info['Turn'] self.gamestate.total_food = game_info['TotalFood']
def start_game(self, force_game, force_reg): if not os.path.exists('piskvorkator.ini'): self.config.add_section('config') self.config['config']['address'] = 'https://piskvorky.jobs.cz' self.config['config']['player_id'] = '' self.config['config']['player_token'] = '' self.config.add_section('ai') self.config['ai']['defense_parameter_1'] = '1.2' self.config['ai']['defense_parameter_tick_1'] = '-0.075' self.config['ai']['stochastic_rate_1'] = '0.01' self.config['ai']['defense_parameter_2'] = '1.2' self.config['ai']['defense_parameter_tick_2'] = '-0.075' self.config['ai']['stochastic_rate_2'] = '0.01' self.config.add_section('saved') self.config['saved']['game_token'] = '' with open('piskvorkator.ini', 'w') as configfile: self.config.write(configfile) gb.custom_print('Configuration file was not found, created new!', 15) self.config.read('piskvorkator.ini') self.player_token = self.config['config']['player_token'] self.player_id = self.config['config']['player_id'] self.address = self.config['config']['address'] if self.handle_login(force_reg) == 0: return 0 if len(self.config['saved']['game_token']) != 0: if force_game: gb.custom_print('Saved game abandoned!', 10) else: gb.custom_print('Saved game found!', 10) return 4 response = requests.post(self.address + '/api/v1/connect', json={'userToken': self.player_token}) content = response.json() if response.status_code == 201: gb.custom_print('New game successfully started!', 10) self.game_token = content['gameToken'] self.config['saved']['game_token'] = content['gameToken'] with open('piskvorkator.ini', 'w') as configfile: self.config.write(configfile) self.gb = gb.Gameboard((41, 59), self.debug, self.logger) self.game_in_progress = 1 self.configure_logger() return 1 else: gb.custom_print( 'Something went wrong! {}'.format(content['errors']), 9) return 0
def test_generate_new_tetromino(self): # Every time the Tetromino itself is diffrent this method should return diffrent value gb = gameboard.Gameboard() # gb.generate_new_tetromino = unittest.mock.MagicMock(return_value=tetromino.Tetromino("I")) # TODO Check if every call gives properly placed tetromino for shape in config.TETROMINO_SHAPES: for rotate in range(0, 3): gb.generate_new_tetromino = unittest.mock.MagicMock(return_value=tetromino.Tetromino(shape, rotate)) self.assertEqual(type(gb.falling_tetromino), tetromino.Tetromino)
def game(): """Runs whole game""" pygame.init() screen = pre_configure_window() buffer = tetromino.Tetromino("I", times_rotated=0, x=3, y=0) actuall_gameboard = gameboard.Gameboard() time_steps_done_before_fall = 0 game_over = False # main gameloop while not game_over: actuall_gameboard.draw_gameboard( screen) # only gameboard are redrawing in all frame time.sleep( config.GAME_SINGLE_FRAME_SEC) # sleeps for every 50 miliseconds buffer.move(actuall_gameboard) # controlled from keyboard buffer.draw(screen) time_steps_done_before_fall += 1 if time_steps_done_before_fall == config.TIME_STEPS_TO_FALL_BUFFER: has_falled = buffer.fall_down(actuall_gameboard) if has_falled: actuall_gameboard.add_blocks(buffer) buffer = evaluator.Evaluator.generate_tetromino( actuall_gameboard, config.MALICIOUS_LEVEL) if buffer.fall_down( actuall_gameboard ): # while newly added tetromino instantly touching fallen blocks game_over = True print( f"Thank You for your play - waiting to see u next time!" ) actuall_gameboard.delete_lines() time_steps_done_before_fall = 0 pygame.display.update()
def test_delete_rows(self): """Check if delete rows returns proper quantity of deleted rows and the Gameboard has proper fields after deletion""" def fill_row_no(gb : gameboard.Gameboard, row_no : int): for i in range(config.BOARD_FIRST_COLUMN, config.BOARD_LAST_COLUMN+1): gb.fields[row_no][i] = config.FALLEN_BLOCK gb = gameboard.Gameboard() # If gameboard is new (and empty) there are no empty rows to delete self.assertEqual(gb.delete_rows(), 0) fill_row_no(gb, 0) fill_row_no(gb, 1) fill_row_no(gb, 2) fill_row_no(gb, 3) fill_row_no(gb, 4) fill_row_no(gb, 5) fill_row_no(gb, 6) self.assertEqual(gb.delete_rows(), 7) self.assertEqual(gb.delete_rows(), 0) # After deletion there must not be any filled row fill_row_no(gb, 0) gb.fields[0][3] = config.EMPTY_BLOCK # Almost fully filled row (except third block) self.assertEqual(gb.delete_rows(), 0) # Check if positions of blocks after deletion and moving down are proper fill_row_no(gb, config.BOARD_LAST_ROW) fill_row_no(gb, config.BOARD_LAST_ROW-1) row_to_check1, row_to_check2 = 6, 2 col_to_check1, col_to_check2 = 3, 8 gb.fields[row_to_check1][col_to_check1] = config.FALLEN_BLOCK gb.fields[row_to_check2][col_to_check2] = config.FALLEN_BLOCK self.assertEqual(gb.delete_rows(), 2) self.assertEqual(gb.fields[row_to_check1][col_to_check1], config.EMPTY_BLOCK) # Blocks should be empty self.assertEqual(gb.fields[row_to_check2][col_to_check2], config.EMPTY_BLOCK) self.assertEqual(gb.fields[row_to_check1+2][col_to_check1], config.FALLEN_BLOCK) # There was two deleted rows so blocks moved two rows down self.assertEqual(gb.fields[row_to_check1+2][col_to_check1], config.FALLEN_BLOCK)
def __init__(self): super().__init__() self.initUI() self.x = 50 self.y = 50 self.mouseReleaseEvent = self.mouseReleaseEvent self.mousePressEvent = self.mousePressEvent self.mouseMoveEvent = self.mouseMoveEvent self.renderer = Renderer(self) self.dragging = False self.xOff = 0 self.yOff = 0 self.pieceSelected = False self.selectedPieceX = -1 self.selectedPieceY = -1 self.targetX = 0 self.targetY = 0 self.board = gb.Gameboard()
def reload_game(self): RED = (255, 0, 0) BLUE = (0, 0, 255) YELLOW = (255, 255, 0) PURPLE = (255, 0, 255) CYAN = (0, 255, 255) #create gameboard with player names if self.saved_number_of_players == 2: gameboard = g.Gameboard(['Kristof', 'The Ugly Enemy'], [RED, BLUE]) self.master = gameboard elif self.saved_number_of_players == 3: gameboard = g.Gameboard(self.saved_names, [RED, BLUE, YELLOW]) self.master = gameboard elif self.saved_number_of_players == 4: gameboard = g.Gameboard(self.saved_names, [RED, BLUE, YELLOW, PURPLE]) self.master = gameboard else: gameboard = g.Gameboard(self.saved_names, [RED, BLUE, YELLOW, PURPLE, CYAN]) self.master = gameboard #adjust want_maintenance self.want_maintenance = False if self.saved_want_maintenance: self.master.buttons[0].want_maintenance = True #adjust moneys and crystals for i in range(len(self.saved_moneys)): gameboard.players[i].money = int(self.saved_moneys[i]) gameboard.players[i].crystals = int(self.saved_crystals[i]) #add planets to players - without initially removing evenly allocated planets from players for i in range(len(self.saved_planet_names)): # print '\n'+self.saved_planet_names[i] # print 'looking for owner name:', self.saved_planet_owner_names[i] for player in self.master.players: if self.saved_planet_owner_names[i] == player.name: # print 'found owner:', player.name k = 0 for j in range(len(self.master.planets)): if self.master.planets[ j - k].name == self.saved_planet_names[i]: planet_to_be_added = self.master.planets[j - k] # print 'found in self.master.planets:', self.master.planets[j-k].name for other_player in self.master.players: if self.master.planets[ j - k] in other_player.planets: other_player.planets.remove( self.master.planets[j - k]) k += 1 player.planets.append(planet_to_be_added) # print 'planet', planet_to_be_added.name, 'added to player', player.name player.planets[-1].owner = player player.planets[-1].set_owner_colour() if self.saved_planet_has_space_factories[i]: player.planets[-1].has_space_factory = True break break #add ships to players for i in range(len(self.saved_ships)): for player in self.master.players: if self.saved_ship_owner_names[i] == player.name: if self.saved_ships[i] == 'star destroyer': self.master.add_ship_to_player( Star_destroyer([ self.master.TILE_SIZE * x for x in self.saved_ship_positions[i] ], player), player) elif self.saved_ships[i] == 'fighter': self.master.add_ship_to_player( Fighter([ self.master.TILE_SIZE * x for x in self.saved_ship_positions[i] ], player), player) elif self.saved_ships[i] == 'transport': self.master.add_ship_to_player( Transport([ self.master.TILE_SIZE * x for x in self.saved_ship_positions[i] ], player), player) else: raise Exception( 'unknown ship type in reload_game method') if self.saved_ship_already_travelled[i]: player.ships[-1].already_travelled = True break gameboard.start()
start_x = int(start_x) start_y = int(start_y) except ValueError: print "Invalid Input: coordinates must be an integer" continue if start_x > 10 or start_x < 1 or start_y > 10 or start_y < 1: print "Coordinate must be between 1 and 10" continue start_x = start_x - 1 start_y = start_y - 1 flag_count = 10 game_board = gameboard.Gameboard(10, 10, flag_count, start_x, start_y) game_board.process_player_selection(start_x, start_y) game_board.print_game() break while not game_over: while not game_over: if flag_count < 1 and game_board.check_win(): print printout("You have won!", MAGENTA) exit() flag = raw_input("Do you want to place/remove a flag? (y/c/n): ") if str(flag) == 'quit': exit() if str(flag) == 'y' and flag_count > 0:
def reconnect(self): if self.game_in_progress == 0: self.game_token = self.config['saved']['game_token'] gb.custom_print('Attempting to reconnect...', 15) self.gb = gb.Gameboard((41, 59), self.debug, self.logger) self.clear_log() self.configure_logger() response = requests.post(self.address + '/api/v1/checkStatus', json={ 'userToken': self.player_token, 'gameToken': self.game_token }) content = response.json() if response.status_code == 200: if self.game_in_progress == 0: self.player = 1 if content[ 'playerCrossId'] == self.player_id else 2 self.opponent = 1 if self.player == 2 else 2 self.configure_ai() if content['playerCrossId'] == None or content[ 'playerCircleId'] == None: gb.custom_print('Connected, waiting for opponent...', 15) self.game_in_progress = 1 return 1 if len(content['coordinates']) == 0: gb.custom_print('Game started!', 10) self.game_in_progress = 1 return 2 last_coordinates = None for turn in reversed(content['coordinates']): coordinates = (turn['x'], turn['y']) pl = self.player if turn[ 'playerId'] == self.player_id else self.opponent self.gb.place_symbol( pl, self.translate_coordinates(coordinates, 0)) if pl == self.opponent: last_coordinates = coordinates if self.game_in_progress == 0: if pl == self.player: gb.custom_print( 'I played on coordinates {}!'.format(coordinates), 14) else: gb.custom_print( 'Opponent played on coordinates {}!'.format( coordinates), 12) if self.game_in_progress == 1: gb.custom_print( 'Reconnected, opponents last play was on coordinates {}'. format(last_coordinates), 12) if content['actualPlayerId'] == self.player_id: gb.custom_print('It\'s my turn now...', 14) self.game_in_progress = 1 return 3 else: gb.custom_print('It\'s opponents turn now, waiting...', 12) self.game_in_progress = 1 return 2 elif response.status_code == 226: self.game_in_progress = 0 gb.custom_print('Game already ended!', 10) return 5 else: gb.custom_print( 'Something went wrong! {}'.format(content['errors']), 9) if self.game_in_progress == 1: self.config['saved']['game_token'] = '' with open('piskvorkator.ini', 'w') as configfile: self.config.write(configfile) return 0
def test_gameboard_max_right_column_is_border(self): """Check if maximum left blocks of fields are border type""" gb = gameboard.Gameboard() for block in gb.fields: self.assertEqual(block[config.BOARD_COLUMNS-1], config.BORDER_BLOCK)
def test_gameboard_bottom_row_is_border(self): """Check if gameboard bottom row is made by border type of blocks""" gb = gameboard.Gameboard() for block in gb.fields[config.BOARD_BOTTOM_ROW]: self.assertEqual(block, config.BORDER_BLOCK)
def test_gameboard_fields_size(self): """Check if gameboad has proper size""" gb = gameboard.Gameboard() self.assertEqual(len(gb.fields), config.BOARD_ROWS) # number of rows for gb_row in gb.fields: self.assertEqual((len(gb_row)), config.BOARD_COLUMNS) # every row has blocks num
def __init__(self, screen: pygame.Surface, level: int): self.gameboard = gameboard.Gameboard() self.level = level self.score = 0 self.screen = screen
def train(model, start, first_iteration=0, model_name='current_model'): initial_learning_rate = 1e-4 gb = gameboard.Gameboard() optimizer = optim.Adam(model.parameters(), lr=initial_learning_rate) device = 'cuda' if torch.cuda.is_available() else 'cpu' criterion = nn.MSELoss() replay_memory = [] action = torch.zeros([model.number_of_actions], dtype=torch.float32) action[0] = 1 reward, terminal = gb.frame_step(action) # image_data, reward, terminal = game_state.frame_step(action) board_data = gb.get_board_normalized().to(device)[None, ...] state = torch.cat((board_data, board_data, board_data, board_data)).unsqueeze(0) epsilon = model.initial_epsilon iteration = first_iteration epsilon_decrements = np.linspace(model.initial_epsilon, model.final_epsilon, model.number_of_iterations) while iteration < model.number_of_iterations: # get output from the neural network print('ITERATION {} =================='.format(iteration + 1)) # update learning rate adjust_learning_rate(optimizer, iteration, initial_learning_rate) print('Learning Rate: {}'.format(optimizer.param_groups[0]['lr'])) output = model(state) print('Output: {}'.format(output)) # initialize action action = torch.zeros([model.number_of_actions], dtype=torch.float32) action.to(device) # epsilon greedy exploration random_action = random.random() <= epsilon or reward < -1 if random_action: print("Performed random action!") if reward < -1: print('Bad first pick!') action_index = [torch.randint(model.number_of_actions, torch.Size([]), dtype=torch.int) if random_action else torch.argmax(output)][0] print('First action index: {}'.format(action_index.item())) ''' if not gb.simulate_move_successful(action_index.item()): # We played something that would not result in a move. print('Trying second option') output[torch.argmax(output)] = 0 action_index = [torch.randint(model.number_of_actions, torch.Size([]), dtype=torch.int) if random_action else torch.argmax(output)][0] print('Second action index: {}'.format(action_index.item())) ''' action_index.to(device) action[action_index] = 1 # get next state and reward reward, terminal = gb.frame_step(action) board_data_1 = gb.get_board_normalized()[None, ...] state_1 = torch.cat((state.squeeze(0)[1:, :, :], board_data_1)).unsqueeze(0) action = action.unsqueeze(0) reward = torch.from_numpy(np.array([reward], dtype=np.float32)).unsqueeze(0) # save transition to replay memory replay_memory.append((state, action, reward, state_1, terminal)) # if replay memory is full, remove the oldest transition if len(replay_memory) > model.replay_memory_size: replay_memory.pop(0) # epsilon annealing epsilon = epsilon_decrements[iteration] # sample random minibatch minibatch = random.sample(replay_memory, min(len(replay_memory), model.minibatch_size)) # unpack minibatch state_batch = torch.cat(tuple(d[0] for d in minibatch)).to(device) action_batch = torch.cat(tuple(d[1] for d in minibatch)).to(device) reward_batch = torch.cat(tuple(d[2] for d in minibatch)).to(device) state_1_batch = torch.cat(tuple(d[3] for d in minibatch)).to(device) output_1_batch = model(state_1_batch) # set y_j to r_j for terminal state, otherwise to r_j + gamma*max(Q) y_batch = torch.cat(tuple(reward_batch[i] if minibatch[i][4] else reward_batch[i] + model.gamma * torch.max(output_1_batch[i]) for i in range(len(minibatch)))) # extract Q-value output_state_batch = model(state_batch) blarg = output_state_batch * action_batch q_value = torch.sum(blarg, dim=1) # PyTorch accumulates gradients by default, so they need to be reset in each pass optimizer.zero_grad() # returns a new Tensor, detached from the current graph, the result will never require gradient y_batch = y_batch.detach() # calculate loss loss = criterion(q_value, y_batch) print(loss) # do backward pass loss.backward() optimizer.step() # set state to be state_1 state = state_1 iteration += 1 if iteration % 5000 == 0: torch.save(model, "pretrained_model/{}".format(model_name) + str(iteration) + ".pth") print_string = "iteration: {} \t reward: {} \t Q max: {} \t Max tile: {}\n".format(iteration, reward, np.max( output.cpu().detach().numpy()), gb.get_highest_tile()) print("iteration:", iteration, "elapsed time:", time.time() - start, "epsilon:", epsilon, "action:", action_index.cpu().detach().numpy(), "reward:", reward.numpy()[0][0], "Q max:", np.max(output.cpu().detach().numpy())) print('\n\n\n') write_record("outputs/{}.txt".format(model_name), print_string)
layout1.append([-1, 1, 1, 1, 1, 1, -1]) layout1.append([1, 1, 1, 1, 1, 1, 1]) layout1.append([1, 1, 1, 0, 1, 1, 1]) layout1.append([1, 1, 1, 1, 1, 1, 1]) layout1.append([-1, 1, 1, 1, 1, 1, -1]) layout1.append([-1, -1, 1, 1, 1, -1, -1]) # bad layout here. Can't be empty. layout2 = [] # Also a bad layout, Not a nested array. layout3 = [0, 0, 0] # Bad layout, rows are not the same length. layout4 = [] layout4.append([0, 0, 0]) layout4.append([0, 0]) layout4.append([0, 0, 0]) # Bad layout, invalid indexes, must be -1, 0, or 1. layout5 = [] layout5.append([0, 0, 0]) layout5.append([2, 0, 0]) layout5.append([1, 1, 1]) root = Tkinter.Tk() root.title('Chinese Solitaire') board = gameboard.Gameboard(layout1, root) board.mainloop() root.destroy()
def __init__(self): self.ui = userinput.UserInput() self.gameboard = gameboard.Gameboard() self.validator = validate.Validate() self.color = 'white' self.captured_pieces = [] self.white_pieces = [] self.black_pieces = [] for i in 'abcdefgh': self.white_pieces.append( piece.Piece(i + '2', name='pawn', color='white', name_representation='\u2659')) self.black_pieces.append( piece.Piece(i + '7', name='pawn', color='black', name_representation='\u265F')) for i in 'ah': self.white_pieces.append( piece.Piece(i + '1', name='rook', color='white', name_representation='\u2656')) self.black_pieces.append( piece.Piece(i + '8', name='rook', color='black', name_representation='\u265C')) for i in 'bg': self.white_pieces.append( piece.Piece(i + '1', name='knight', color='white', name_representation='\u2658')) self.black_pieces.append( piece.Piece(i + '8', name='knight', color='black', name_representation='\u265E')) for i in 'cf': self.white_pieces.append( piece.Piece(i + '1', name='bishop', color='white', name_representation='\u2657')) self.black_pieces.append( piece.Piece(i + '8', name='bishop', color='black', name_representation='\u265D')) self.white_pieces.append( piece.Piece('d1', name='queen', color='white', name_representation='\u2655')) self.black_pieces.append( piece.Piece('d8', name='queen', color='black', name_representation='\u265B')) self.white_pieces.append( piece.Piece('e1', name='king', color='white', name_representation='\u2654')) self.black_pieces.append( piece.Piece('e8', name='king', color='black', name_representation='\u265A'))