· 5 years ago · Dec 23, 2020, 02:20 PM
1"""GLOBAL VARIABLES and IMPORTS"""
2from car import Car
3
4EMPTY = '-'
5VERTICAL = 0 # for testing
6HORIZONTAL = 1 # for testing
7ERROR = "Error"
8########################################################################################################################
9
10class Board:
11 """
12 Class for game board objects. Boards are the setting main structure where the game to takes place.
13 Each round in game is set on a single board. Board objects track the different car objects in play
14 using a dictionary, and can determine what are all the possible_moves for each car object.
15 Every board has size parameters (width, hieght),which in this task should have a pre-determined
16 permanent value (7), a printable matrix representing the game board itself and the coordinates
17 a car object needs to win the game.
18 """
19
20 def __init__(self):
21 self._WIDTH = 7 # permanent value set by task guidelines
22 self._HEIGHT = 7 # permanent value set by task guidelines
23 self._VICTORY = 3, 7 # permanent value set by task guidelines
24 self.matrix = [[EMPTY] * self._WIDTH] * self._HEIGHT # create an empty board
25 self.cars_on_board = dict # dictionary of all existing cars
26
27 def __str__(self):
28 """
29 This function is called when a board object is to be printed.
30 :return: A string of the current status of the board
31 """
32 matrix_string = ""
33 for y in range(len(self.matrix)):
34 for x in range(len(self.matrix[y])):
35 matrix_string = matrix_string + ' ' + str(self.matrix[y][x])
36 matrix_string = matrix_string + '\n'
37 return matrix_string
38
39 def cell_list(self):
40 """ This function returns the coordinates of cells in this board
41 :return: list of coordinates
42 """
43 lst = []
44 for y in range(self._HEIGHT):
45 for x in range(self._WIDTH):
46 temp_tuple = (y, x)
47 lst.append(temp_tuple)
48 return lst
49
50 def possible_moves(self):
51 """ This function returns the legal moves of all cars in this board
52 :return: list of tuples of the form (name,movekey,description)
53 representing legal moves
54 """
55 legal_moves = []
56 for car in self.cars_on_board.items(): # get all car objects on board (consider using set over dict)
57 car: Car # find a way to fix loop so as to not need this line
58 possible_moves:dict = car.possible_moves()
59 for movekey in possible_moves.keys():
60 required_cell = (car.movement_requirements(movekey))
61 if self.cell_content(required_cell) is None: # if cell is empty (cell_content returns None), move is valid
62 move_temp = (car.get_name(),movekey,possible_moves[movekey])
63 legal_moves.append(move_temp)
64 else: # if required cell is not empty, do not add move to legal_moves list
65 continue
66 # From the provided example car_config.json file, the return value could be
67 # [('O','d',"some description"),('R','r',"some description"),('O','u',"some description")]
68 return legal_moves
69
70 def target_location(self):
71 """
72 This function returns the coordinates of the location which is to be filled for victory.
73 :return: (row,col) of goal location
74 """
75 return self._VICTORY
76
77 def cell_content(self, coordinate):
78 """
79 Checks if the given coordinates are empty.
80 :param coordinate: tuple of (row,col) of the coordinate to check
81 :return: The name if the car in coordinate, None if empty
82 """
83 if coordinate[0] > self._HEIGHT or coordinate[1] > self._WIDTH:
84 print("ERROR: coordinates are outside of board")
85 return ERROR
86 cell = self.matrix[coordinate[0]][coordinate[1]]
87 if cell == EMPTY: # cell is empty
88 return None
89 else:
90 return cell
91
92 def add_car(self, car):
93 """
94 Adds a car to the game.
95 :param car: car object of car to add
96 :return: True upon success. False if failed
97 """
98 # fail: location taken, car already exist on board, coordinates out of board
99 # car data is valid (name, orientation, location) by default:
100 # "You may assume the car is a legal car object following the API"
101 car_name = car.get_name()
102 if car_name in self.cars_on_board().keys(): # check if car already exist
103 return False
104 for cell in car.car_coordinates():
105 if self.cell_content(cell): # check if cells in car coordinates have a car in them (return False if so)
106 return False
107 else:
108 continue
109
110 # if car does not already exist, and all cells in it's coordinates are empty
111 print('initial: ', self.cars_on_board)
112 self.cars_on_board().update({car_name: car})
113 print('updated: ', self.cars_on_board)
114 return True
115
116 # return None # invalid input
117
118 def move_car(self, name, movekey):
119 """
120 moves car one step in given direction.
121 :param name: name of the car to move
122 :param movekey: Key of move in car to activate
123 :return: True upon success, False otherwise
124 """
125 car = self.cars_on_board[name]
126 if car.get_name() not in self.cars_on_board().keys(): # check if car exist
127 return False
128
129 origin_y = car.location()[0]
130 origin_x = car.location()[1]
131 # consider adding a check to see move is in possible_moves
132 if movekey == 'u':
133 car.location()[0] + 1
134 self.matrix[origin_y][origin_x] = EMPTY # update the cell the car left
135 elif movekey == 'd':
136 car.location()[0] - 1
137 self.matrix[origin_y][origin_x] = EMPTY
138 elif movekey == 'r':
139 car.location()[1] + 1
140 self.matrix[origin_y][origin_x] = EMPTY
141 elif movekey == 'l':
142 car.location()[1] - 1
143 self.matrix[origin_y][origin_x] = EMPTY
144 else:
145 return None # invalid movekey input
146
147
148
149########################################################################################################
150"""TESTING"""
151
152b1 = Board()
153# print(b1)
154
155# #################
156# # cell list
157# print("\nTEST POSSIBLE CELL LIST")
158# # 1
159# got = b1.cell_list()
160# expected = [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4),
161# (1, 5), (1, 6), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (3, 0), (3, 1), (3, 2),
162# (3, 3), (3, 4), (3, 5), (3, 6), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (5, 0),
163# (5, 1), (5, 2), (5, 3), (5, 4), (5, 5), (5, 6), (6, 0), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5),
164# (6, 6)]
165# if got == expected:
166# print('1) success')
167# else:
168# print('1) fail')
169# print(' ', got)
170#
171# #################
172# # possible moves
173# print("\nTEST POSSIBLE MOVES")
174# # 1
175# # cj1, cj2 = Car('O', 2, (2,3), 0), Car('R', 2, (0,0), 1)
176# # b1.cars_on_board = {cj1, cj2}
177# # got = b1.possible_moves()
178# # expected = [('O','d',"down"),('R','r',"right"),('O','u',"up")]
179# # if got == expected:
180# # print('1) success')
181# # else:
182# # print('1) fail')
183# # print(' ', got)
184#
185#
186# #################
187# # target location
188# print("\nTEST TARGET LOCATION")
189# # 1
190# got = b1.target_location()
191# expected = (3, 7)
192# if got == expected:
193# print('1) success')
194# else:
195# print('1) fail')
196# print(' ', got)
197
198# #################
199# # cell content
200# print("\nTEST CELL CONTENT")
201# # 1
202# got = b1.cell_content((0, 0))
203# expected = None
204# if got == expected:
205# print('1) success')
206# else:
207# print('1) fail')
208# print(' got: ', got, ' expects: ', expected)
209
210# # 2
211# coordinates = (1, 1)
212# b1.matrix[coordinates[0]][coordinates[1]] = 'Y'
213# got = b1.cell_content((1, 1))
214# expected = 'Y'
215# if got == expected:
216# print('2) success')
217# else:
218# print('2) fail')
219# print(' got: ', got, ' expects: ', expected)
220
221#################
222# add_car
223print("\nTEST ADD CAR")
224
225# # 1
226c1 = Car('Y', 2, (3, 0), HORIZONTAL)
227got = b1.add_car(c1)
228expected = True
229if got == expected:
230 print('1) normal input: success')
231else:
232 print('1) normal input: fail')
233 print(' got: ', got, ' expects: ', expected)
234
235# 2 required cells already taken (by c1)
236c2 = Car('R', 1, (3, 0), HORIZONTAL)
237got = b1.add_car(c2)
238expected = False
239if got == expected:
240 print('2) required cells already taken (by c1): success')
241else:
242 print('2) required cells already taken (by c1): fail')
243 print(' got: ', got, ' expects: ', expected)
244
245# 3 car already exist on the game board(c1), note that this need c1 to exist for test to work
246
247c3 = Car('Y', 1, (5, 2), VERTICAL)
248got = b1.add_car(c3)
249expected = False
250if got == expected:
251 print('3) car already exist on the game board: success')
252else:
253 print('3) car already exist on the game board: fail')
254 print(' got: ', got, ' expects: ', expected)
255
256# dict = {}
257# print('initial: ', dict)
258# dict.update({c1.get_name(): c1})
259# print('updated: ', dict)
260
261#################
262# move car
263# 1 typical input
264c1 = Car('Y', 2, (3, 0), HORIZONTAL)
265print('pre move: \n', b1)
266got = b1.move_car('Y', 'r')
267print('after move: \n', b1)
268expected = True
269if got == expected:
270 print('1) normal input: success')
271 print("check new location and if old cell was cleaned - auto test only checks final output")
272else:
273 print('1) normal input: fail')
274 print(' got: ', got, ' expects: ', expected)
275
276# 2 car does not exist
277c2 = Car('R', 1, (3, 0), HORIZONTAL)
278print('pre move: \n', b1)
279got = b1.move_car('Y', 'r')
280print('after move: \n', b1)
281expected = False
282if got == expected:
283 print('2) normal input: success')
284else:
285 print('2) normal input: fail')
286 print(' got: ', got, ' expects: ', expected)