# rlSimpleGameFeatures.py - Feature-based Reinforcement Learner
# AIFCA Python3 code Version 0.9.4 Documentation at http://aipython.org
# Download the zip file and read aipython.pdf for documentation
# Artificial Intelligence: Foundations of Computational Agents http://artint.info
# Copyright David L Poole and Alan K Mackworth 2017-2022.
# This work is licensed under a Creative Commons
# Attribution-NonCommercial-ShareAlike 4.0 International License.
# See: http://creativecommons.org/licenses/by-nc-sa/4.0/deed.en
from rlSimpleEnv import Simple_game_env
from rlProblem import RL_env
def get_features(state,action):
"""returns the list of feature values for the state-action pair
"""
assert action in Simple_game_env.actions
(x,y,d,p) = state
# f1: would go to a monster
f1 = monster_ahead(x,y,action)
# f2: would crash into wall
f2 = wall_ahead(x,y,action)
# f3: action is towards a prize
f3 = towards_prize(x,y,action,p)
# f4: damaged and action is toward repair station
f4 = towards_repair(x,y,action) if d else 0
# f5: damaged and towards monster
f5 = 1 if d and f1 else 0
# f6: damaged
f6 = 1 if d else 0
# f7: not damaged
f7 = 1-f6
# f8: damaged and prize ahead
f8 = 1 if d and f3 else 0
# f9: not damaged and prize ahead
f9 = 1 if not d and f3 else 0
features = [1,f1,f2,f3,f4,f5,f6,f7,f8,f9]
# the next 20 features are for 5 prize locations
# and 4 distances from outside in all directions
for pr in Simple_game_env.prize_locs+[None]:
if p==pr:
features += [x, 4-x, y, 4-y]
else:
features += [0, 0, 0, 0]
# fp04 feature for y when prize is at 0,4
# this knows about the wall to the right of the prize
if p==(0,4):
if x==0:
fp04 = y
elif y<3:
fp04 = y
else:
fp04 = 4-y
else:
fp04 = 0
features.append(fp04)
return features
def monster_ahead(x,y,action):
"""returns 1 if the location expected to get to by doing
action from (x,y) can contain a monster.
"""
if action == "right" and (x+1,y) in Simple_game_env.monster_locs:
return 1
elif action == "left" and (x-1,y) in Simple_game_env.monster_locs:
return 1
elif action == "up" and (x,y+1) in Simple_game_env.monster_locs:
return 1
elif action == "down" and (x,y-1) in Simple_game_env.monster_locs:
return 1
else:
return 0
def wall_ahead(x,y,action):
"""returns 1 if there is a wall in the direction of action from (x,y).
This is complicated by the internal walls.
"""
if action == "right" and (x==Simple_game_env.xdim-1 or (x,y) in Simple_game_env.vwalls):
return 1
elif action == "left" and (x==0 or (x-1,y) in Simple_game_env.vwalls):
return 1
elif action == "up" and y==Simple_game_env.ydim-1:
return 1
elif action == "down" and y==0:
return 1
else:
return 0
def towards_prize(x,y,action,p):
"""action goes in the direction of the prize from (x,y)"""
if p is None:
return 0
elif p==(0,4): # take into account the wall near the top-left prize
if action == "left" and (x>1 or x==1 and y<3):
return 1
elif action == "down" and (x>0 and y>2):
return 1
elif action == "up" and (x==0 or y<2):
return 1
else:
return 0
else:
px,py = p
if p==(4,4) and x==0:
if (action=="right" and y<3) or (action=="down" and y>2) or (action=="up" and y<2):
return 1
else:
return 0
if (action == "up" and y0 and y<4 or x==0 and y<2):
return 1
elif action == "left" and x>1:
return 1
elif action == "right" and x==0 and y<3:
return 1
elif action == "down" and x==0 and y>2:
return 1
else:
return 0
def simp_features(state,action):
"""returns a list of feature values for the state-action pair
"""
assert action in Simple_game_env.actions
(x,y,d,p) = state
# f1: would go to a monster
f1 = monster_ahead(x,y,action)
# f2: would crash into wall
f2 = wall_ahead(x,y,action)
# f3: action is towards a prize
f3 = towards_prize(x,y,action,p)
return [1,f1,f2,f3]