-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathagent.py
More file actions
235 lines (191 loc) · 7.85 KB
/
Copy pathagent.py
File metadata and controls
235 lines (191 loc) · 7.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
import math, sys
import random
import gymnasium as gym
import math
import random
import matplotlib
import matplotlib.pyplot as plt
from collections import namedtuple, deque
from itertools import count
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from lux.game import Game
from lux.game_map import Cell, RESOURCE_TYPES
from lux.constants import Constants
from lux.game_constants import GAME_CONSTANTS
from lux import annotate
from simple.dqn import DQN, ReplayMemory
DIRECTIONS = Constants.DIRECTIONS
game_state = None
wood_gain = 1
coal_gain = 2
uran_gain = 3
city_gain = 500
worker_gain = 7.5
def get_input(observation, game_state, unit):
"""
A függvény visszadja a neurális hálózat bemenetéhez szükséges adatokat
- Legközelebbi nyersanyag távolsága
- Worker maradék helye
- Legközelebbi város távolsága
- Legközelebbi város üzemanyaga
- Legközelebbi város üzemanyag igénye
- Est-Nap ciklus
- Tud-e építeni a worker
"""
# Closest resource
player = game_state.players[observation.player]
width, height = game_state.map.width, game_state.map.height
resource_tiles: list[Cell] = []
for y in range(height):
for x in range(width):
cell = game_state.map.get_cell(x, y)
if cell.has_resource():
resource_tiles.append(cell)
closest_resource_dist = math.inf
closest_resource_tile = None
for resource_tile in resource_tiles:
if resource_tile.resource.type == Constants.RESOURCE_TYPES.COAL and not player.researched_coal(): continue
if resource_tile.resource.type == Constants.RESOURCE_TYPES.URANIUM and not player.researched_uranium(): continue
dist = resource_tile.pos.distance_to(unit.pos)
if dist < closest_resource_dist:
closest_resource_dist = dist
closest_resource_tile = resource_tile
# Space left
space_left = unit.get_cargo_space_left()
# Closest city
closest_city_dist = math.inf
closest_city_tile = None
for k, city in player.cities.items():
for city_tile in city.citytiles:
dist = city_tile.pos.distance_to(unit.pos)
if dist < closest_city_dist:
closest_city_dist = dist
closest_city_tile = city_tile
# Closest city fuel
closest_city_fuel = city.fuel
# Closest city light_upkeep
closest_city_light_upkeep = city.light_upkeep
# Day Night cycle
cycle_position = observation["step"] % 40
# Can the unit build a city
can_build = 1 if unit.can_build(game_state.map) else 0
return [closest_resource_dist, space_left, closest_city_dist, closest_city_fuel, closest_city_light_upkeep,
cycle_position, can_build]
def agent(observation, configuration):
global game_state
### Do not edit ###
if observation["step"] == 0:
game_state = Game()
game_state._initialize(observation["updates"])
game_state._update(observation["updates"][2:])
game_state.id = observation.player
else:
game_state._update(observation["updates"])
actions = []
### AI Code goes down here! ###
player = game_state.players[observation.player]
opponent = game_state.players[(observation.player + 1) % 2]
width, height = game_state.map.width, game_state.map.height
resource_tiles: list[Cell] = []
for y in range(height):
for x in range(width):
cell = game_state.map.get_cell(x, y)
if cell.has_resource():
resource_tiles.append(cell)
# we iterate over all our units and do something with them
for unit in player.units:
# Test
# with open("log.txt", "a") as f:
# print(get_input(observation, game_state, unit), file=f)
if unit.is_worker() and unit.can_act():
closest_dist = math.inf
closest_resource_tile = None
if unit.get_cargo_space_left() > 0:
# if the unit is a worker and we have space in cargo, lets find the nearest resource tile and try to mine it
for resource_tile in resource_tiles:
if resource_tile.resource.type == Constants.RESOURCE_TYPES.COAL and not player.researched_coal(): continue
if resource_tile.resource.type == Constants.RESOURCE_TYPES.URANIUM and not player.researched_uranium(): continue
dist = resource_tile.pos.distance_to(unit.pos)
if dist < closest_dist:
closest_dist = dist
closest_resource_tile = resource_tile
if closest_resource_tile is not None:
actions.append(unit.move(unit.pos.direction_to(closest_resource_tile.pos)))
else:
# if unit is a worker and there is no cargo space left, and we have cities, lets return to them
if len(player.cities) > 0:
closest_dist = math.inf
closest_city_tile = None
for k, city in player.cities.items():
for city_tile in city.citytiles:
dist = city_tile.pos.distance_to(unit.pos)
if dist < closest_dist:
closest_dist = dist
closest_city_tile = city_tile
if closest_city_tile is not None:
move_dir = unit.pos.direction_to(closest_city_tile.pos)
actions.append(unit.move(move_dir))
# you can add debug annotations using the functions in the annotate object
# actions.append(annotate.circle(0, 0))
return actions
def get_rewards(last_game_state, last_observation, new_observation, new_game_state):
new_player = new_game_state.players[new_observation.player]
last_player = last_game_state.players[last_observation.player]
width, height = last_game_state.map.width, last_game_state.map.height
def get_city_reward_per_player(new_player, last_player):
last_city_tiles = 0
for city in last_player.cities:
last_city_tiles += len(city.citytiles)
new_city_tiles = 0
for city in new_player.cities:
new_city_tiles += len(city.citytiles)
new_cities = (new_city_tiles - last_city_tiles) * city_gain
return new_cities
def get_new_worker_reward_per_player(new_player, last_player):
last_unit_count = 0
for unit in last_player.units:
if (unit.is_worker()):
last_unit_count += 1
new_unit_count = 0
for unit in new_player.units:
if (unit.is_worker()):
new_unit_count += 1
new_workers = (last_unit_count - new_unit_count) * worker_gain
return new_workers
def get_new_cargo_reward_per_player(new_player, last_player):
last_coal = 0
last_uran = 0
last_wood = 0
for unit in last_player.units:
if (unit.is_worker()):
last_coal += unit.cargo.coal()
last_uran += unit.cargo.uran()
last_wood += unit.cargo.wood()
new_coal = 0
new_uran = 0
new_wood = 0
for unit in new_player.units:
if (unit.is_worker()):
new_coal += unit.cargo.coal()
new_uran += unit.cargo.uran()
new_wood += unit.cargo.wood()
reward_coal = (last_coal - new_coal) * coal_gain
reward_uran = (last_uran - new_uran) * uran_gain
reward_wood = (last_wood - new_wood) * wood_gain
return reward_coal + reward_uran + reward_wood
def complicated_reward_for_player(last_player):
last_coal = 0
last_uran = 0
last_wood = 0
for unit in last_player.units:
if (unit.is_worker()):
last_coal += unit.cargo.coal()
last_uran += unit.cargo.uran()
last_wood += unit.cargo.wood()