-
Notifications
You must be signed in to change notification settings - Fork 349
Expand file tree
/
Copy pathGridworld.py
More file actions
127 lines (107 loc) · 4.78 KB
/
Copy pathGridworld.py
File metadata and controls
127 lines (107 loc) · 4.78 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
from GridBoard import *
class Gridworld:
def __init__(self, size=4, mode='static'):
if size >= 4:
self.board = GridBoard(size=size)
else:
print("Minimum board size is 4. Initialized to size 4.")
self.board = GridBoard(size=4)
#Add pieces, positions will be updated later
self.board.addPiece('Player','P',(0,0))
self.board.addPiece('Goal','+',(1,0))
self.board.addPiece('Pit','-',(2,0))
self.board.addPiece('Wall','W',(3,0))
if mode == 'static':
self.initGridStatic()
elif mode == 'player':
self.initGridPlayer()
else:
self.initGridRand()
#Initialize stationary grid, all items are placed deterministically
def initGridStatic(self):
#Setup static pieces
self.board.components['Player'].pos = (0,3) #Row, Column
self.board.components['Goal'].pos = (0,0)
self.board.components['Pit'].pos = (0,1)
self.board.components['Wall'].pos = (1,1)
#Check if board is initialized appropriately (no overlapping pieces)
#also remove impossible-to-win boards
def validateBoard(self):
valid = True
player = self.board.components['Player']
goal = self.board.components['Goal']
wall = self.board.components['Wall']
pit = self.board.components['Pit']
all_positions = [piece for name,piece in self.board.components.items()]
all_positions = [player.pos, goal.pos, wall.pos, pit.pos]
if len(all_positions) > len(set(all_positions)):
return False
corners = [(0,0),(0,self.board.size), (self.board.size,0), (self.board.size,self.board.size)]
#if player is in corner, can it move? if goal is in corner, is it blocked?
if player.pos in corners or goal.pos in corners:
val_move_pl = [self.validateMove('Player', addpos) for addpos in [(0,1),(1,0),(-1,0),(0,-1)]]
val_move_go = [self.validateMove('Goal', addpos) for addpos in [(0,1),(1,0),(-1,0),(0,-1)]]
if 0 not in val_move_pl or 0 not in val_move_go:
#print(self.display())
#print("Invalid board. Re-initializing...")
valid = False
return valid
#Initialize player in random location, but keep wall, goal and pit stationary
def initGridPlayer(self):
#height x width x depth (number of pieces)
self.initGridStatic()
#place player
self.board.components['Player'].pos = randPair(0,self.board.size)
if (not self.validateBoard()):
#print('Invalid grid. Rebuilding..')
self.initGridPlayer()
#Initialize grid so that goal, pit, wall, player are all randomly placed
def initGridRand(self):
#height x width x depth (number of pieces)
self.board.components['Player'].pos = randPair(0,self.board.size)
self.board.components['Goal'].pos = randPair(0,self.board.size)
self.board.components['Pit'].pos = randPair(0,self.board.size)
self.board.components['Wall'].pos = randPair(0,self.board.size)
if (not self.validateBoard()):
#print('Invalid grid. Rebuilding..')
self.initGridRand()
def validateMove(self, piece, addpos=(0,0)):
outcome = 0 #0 is valid, 1 invalid, 2 lost game
pit = self.board.components['Pit'].pos
wall = self.board.components['Wall'].pos
new_pos = addTuple(self.board.components[piece].pos, addpos)
if new_pos == wall:
outcome = 1 #block move, player can't move to wall
elif max(new_pos) > (self.board.size-1): #if outside bounds of board
outcome = 1
elif min(new_pos) < 0: #if outside bounds
outcome = 1
elif new_pos == pit:
outcome = 2
return outcome
def makeMove(self, action):
#need to determine what object (if any) is in the new grid spot the player is moving to
#actions in {u,d,l,r}
def checkMove(addpos):
if self.validateMove('Player', addpos) in [0,2]:
new_pos = addTuple(self.board.components['Player'].pos, addpos)
self.board.movePiece('Player', new_pos)
if action == 'u': #up
checkMove((-1,0))
elif action == 'd': #down
checkMove((1,0))
elif action == 'l': #left
checkMove((0,-1))
elif action == 'r': #right
checkMove((0,1))
else:
pass
def reward(self):
if (self.board.components['Player'].pos == self.board.components['Pit'].pos):
return -10
elif (self.board.components['Player'].pos == self.board.components['Goal'].pos):
return 10
else:
return -1
def display(self):
return self.board.render()