fixed
This commit is contained in:
parent
0f8b6ec693
commit
3b5feb0d9f
167
main.py
167
main.py
|
@ -6,6 +6,7 @@ import numpy as np
|
|||
import random
|
||||
import argparse
|
||||
|
||||
|
||||
ozai_url = 'http://localhost:8000/api/'
|
||||
|
||||
|
||||
|
@ -108,6 +109,8 @@ def init_game(names=["a", "b"]):
|
|||
if response.status_code == 200:
|
||||
game_id = response.json()
|
||||
print("Game ID:", game_id)
|
||||
#delay
|
||||
sleep(7)
|
||||
return game_id
|
||||
else:
|
||||
return None
|
||||
|
@ -127,7 +130,7 @@ def create_game(names=["a", "b"]):
|
|||
join_game(game_id, name)
|
||||
return game_id
|
||||
|
||||
def submit_action(game_id, player_name, source=0, destination=0, color="start", policy="strict"):
|
||||
def submit_action(game_id, player_name, source=0, destination=0, color="start", policy="random"):
|
||||
# Submit an action to the game. The action is a dictionary with the keys being the action type and the values being the arguments.
|
||||
# Example: {"player": 0, "market": true, "factory": 0, "color": "blue", "patternLine": 0}
|
||||
if source != "market":
|
||||
|
@ -143,11 +146,20 @@ def submit_action(game_id, player_name, source=0, destination=0, color="start",
|
|||
'source': source,
|
||||
'destination': destination
|
||||
}
|
||||
|
||||
print(f"action {action}")
|
||||
response = requests.put(ozai_url + 'game/' + game_id, json=action)
|
||||
if response.status_code == 200:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
print(f"response {response}")
|
||||
if response.status_code != 200:
|
||||
action = {
|
||||
'player': str(player_name),
|
||||
'policy': "loose",
|
||||
'color': str(color).lower(),
|
||||
'source': source,
|
||||
'destination': destination
|
||||
}
|
||||
response = requests.put(ozai_url + 'game/' + game_id, json=action)
|
||||
return response
|
||||
|
||||
def get_gamestate(game_id) -> GameState:
|
||||
response = requests.get(ozai_url + 'game/' + game_id)
|
||||
|
@ -247,6 +259,125 @@ def strategy_2(move,GameState,player):
|
|||
return True
|
||||
return False
|
||||
|
||||
|
||||
def strategy_advanced_old(move, GameState, player):
|
||||
if move[1] == 'floor':
|
||||
# Avoid overfilling the floor
|
||||
if sum(player.floor.values()) + move[3] > 7:
|
||||
return False
|
||||
return True
|
||||
|
||||
remaining_space = move[1] + 1 - player.pattern_lines[move[1]]['number']
|
||||
|
||||
# Prioritize moves that fill the pattern line exactly, enabling a wall tile placement.
|
||||
if move[3] == remaining_space:
|
||||
return True
|
||||
|
||||
# Deprioritize moves that will overfill a pattern line
|
||||
if move[3] > remaining_space:
|
||||
return False
|
||||
|
||||
# Ensure that placing the tile does not block you from placing other colors on the same row
|
||||
row_color_in_wall = any(player.wall[move[1]][i] == move[2] for i in range(5))
|
||||
if row_color_in_wall:
|
||||
return False
|
||||
|
||||
# Prioritize moves that fill pattern lines near completion (1 tile left)
|
||||
if player.pattern_lines[move[1]]['number'] == remaining_space - 1:
|
||||
return True
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def strategy_advanced(move, GameState, player):
|
||||
# Destructure move for clarity
|
||||
factory, pattern_line, tile_color, tile_count = move
|
||||
|
||||
# Floor management: Avoid overfilling the floor line
|
||||
if pattern_line == 'floor':
|
||||
if sum(player.floor.values()) + tile_count > 7:
|
||||
return False
|
||||
return True
|
||||
|
||||
# Calculate the remaining space in the selected pattern line
|
||||
remaining_space = pattern_line + 1 - player.pattern_lines[pattern_line]['number']
|
||||
|
||||
# If the move exactly fills the pattern line, prioritize it
|
||||
if tile_count == remaining_space:
|
||||
return True
|
||||
|
||||
# Deprioritize moves that overfill a pattern line (tiles that would spill over)
|
||||
if tile_count > remaining_space:
|
||||
return False
|
||||
|
||||
# Check if placing the tile blocks placing other colors in the same row
|
||||
# This prevents placing a tile in a pattern line where the corresponding wall row already has that color
|
||||
if any(player.wall[pattern_line][i] == tile_color for i in range(5)):
|
||||
return False
|
||||
|
||||
# Prioritize filling pattern lines that are close to completion (one tile away)
|
||||
if remaining_space == 1:
|
||||
return True
|
||||
|
||||
# If none of the conditions above trigger, accept the move
|
||||
return True
|
||||
|
||||
|
||||
|
||||
|
||||
def strategy_lookahead(move, GameState, player):
|
||||
def simulate_future_state(GameState, move, player):
|
||||
"""
|
||||
Simulate the GameState after making the current move and return the hypothetical player's state.
|
||||
"""
|
||||
future_GameState = GameState # Assume deep copy or similar for actual implementation
|
||||
# Apply the move
|
||||
if move[1] == 'floor':
|
||||
future_floor_count = sum(player.floor.values()) + move[3]
|
||||
if future_floor_count > 7:
|
||||
return None # Overfilling the floor is a bad move
|
||||
else:
|
||||
player.pattern_lines[move[1]]['number'] += move[3]
|
||||
if player.pattern_lines[move[1]]['number'] == move[1] + 1:
|
||||
# Tile will be placed on the wall in the next turn
|
||||
player.wall[move[1]][player.wall[move[1]].index(False)] = move[2]
|
||||
player.pattern_lines[move[1]]['number'] = 0 # Reset the pattern line
|
||||
|
||||
# Simulate scoring or any other immediate effect
|
||||
# (Depending on how your game state works, update this appropriately)
|
||||
|
||||
return player
|
||||
|
||||
def evaluate_future_state(future_player):
|
||||
"""
|
||||
Evaluate the future state for the player and return a score.
|
||||
"""
|
||||
# Simple heuristic: prioritize a mix of empty spaces filled, tiles on the wall, and penalty on the floor
|
||||
score = sum(sum(row) for row in future_player.wall) - sum(future_player.floor.values())
|
||||
return score
|
||||
|
||||
# Evaluate the immediate impact
|
||||
immediate_impact = strategy_advanced(move, GameState, player)
|
||||
|
||||
if not immediate_impact:
|
||||
return False
|
||||
|
||||
# Simulate the game state after the current move
|
||||
future_player_state = simulate_future_state(GameState, move, player)
|
||||
|
||||
if future_player_state is None:
|
||||
return False # Avoid moves that lead to a bad future state
|
||||
|
||||
# Evaluate the future state
|
||||
future_score = evaluate_future_state(future_player_state)
|
||||
|
||||
# Set a threshold or comparison logic to decide whether the move is good enough
|
||||
if future_score > evaluate_future_state(player): # Basic comparison with current state
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def strategy_random(move, GameState,player):
|
||||
return True #do not filter any moves
|
||||
|
||||
|
@ -259,21 +390,25 @@ def do_move(game_id, player_name, filter_strategy=strategy_random):
|
|||
for move in moves:
|
||||
if filter_strategy(move,GameState,player):
|
||||
filtered_moves.append(move)
|
||||
|
||||
if len(filtered_moves) <= 1:
|
||||
raise Exception("No valid moves")
|
||||
# Submit a random move, of the filtered ones.
|
||||
move = random.choice(filtered_moves)
|
||||
submit_action(game_id, player_name, move[0], move[1], move[2])
|
||||
return move
|
||||
except:
|
||||
#if filtered all moves, just submit a random move from the moves
|
||||
result = random.choice(moves)
|
||||
return result
|
||||
move = random.choice(moves)
|
||||
return move
|
||||
|
||||
def play_game(gameid, players, strategy):
|
||||
print(f"Playing game {gameid} with players {players} and strategy {strategy.__name__}")
|
||||
while not game_over(gameid):
|
||||
for player in players:
|
||||
mov = do_move(gameid, player, filter_strategy=strategy)
|
||||
if game_over(game_id):
|
||||
submit_action(gameid, player, mov[0], mov[1], mov[2])
|
||||
print(f"Player {player} did move {mov}, current score: {get_score(gameid, player)}, current round {get_gamestate(gameid).rounds}")
|
||||
if game_over(gameid):
|
||||
#get the score of the players
|
||||
score = []
|
||||
for player in players:
|
||||
|
@ -283,9 +418,9 @@ def play_game(gameid, players, strategy):
|
|||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description='Play a game with specified strategies.')
|
||||
parser.add_argument('--game_id', type=int, default=0, help='The id of the game to play.')
|
||||
parser.add_argument('--game_id', type=str, default="", help='The id of the game to play.')
|
||||
parser.add_argument('--players', nargs='+', default=["a", "b"], help='The names of the players.')
|
||||
parser.add_argument('--strategy', type=str, default="", help='The strategy to use. Can be "1", "2", or "" for random.')
|
||||
parser.add_argument('--strategy', type=str, default="", help='The strategy to use. Can be "1", "2", "advanced", "lookahead", or "" for random.')
|
||||
parser.add_argument('--ozai_url', type=str, default='http://localhost:8000/api/', help='The url to the ozai server.')
|
||||
args = parser.parse_args()
|
||||
|
||||
|
@ -297,11 +432,19 @@ if __name__ == "__main__":
|
|||
#use global ozai url and update it
|
||||
ozai_url = args.ozai_url
|
||||
|
||||
if game_id == 0:
|
||||
if game_id == "":
|
||||
game_id = create_game(names=players)
|
||||
|
||||
if strategy == "1":
|
||||
play_game(game_id, players, strategy_1)
|
||||
elif strategy == "2":
|
||||
play_game(game_id, players, strategy_2)
|
||||
elif strategy == "advanced":
|
||||
play_game(game_id, players, strategy_advanced)
|
||||
elif strategy == "lookahead":
|
||||
play_game(game_id, players, strategy_lookahead)
|
||||
elif strategy == "ai":
|
||||
import ml
|
||||
play_game(game_id, players, ml.strategy_ai)
|
||||
else:
|
||||
play_game(game_id, players, strategy_random)
|
Loading…
Reference in New Issue