Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/local/bin/python3
- import random
- import sys
- class CellRoom:
- def generateGame(self):
- ## Constants
- self.UNDEFINED = 0
- self.FROM_NOWHERE = 1
- self.FROM_NORTH = 2
- self.FROM_EAST = 3
- self.FROM_SOUTH = 4
- self.FROM_WEST = 5
- self.LEFT = 0
- self.RIGHT = 1
- ln = input()
- tests = int(ln)
- total = 0
- for t in range(tests):
- sys.stderr.write(str(t))
- ln = input()
- #print(ln)
- w, h = (int(s) for s in ln.split())
- matrix = [[int(j) for j in input().split()] for i in range(h)]
- self.GAME_WIDTH = w
- self.GAME_HEIGHT = h
- ansrow = -1
- anscol = -1
- best = 0
- beststring = ''
- for it in range(500):
- self.initGame()
- for i in range(10):
- self.permutate()
- ##self.logGameWithPath()
- ##self.logGameWithArrow()
- for i in range(20):
- self.start = self.moveExtremity(self.start)
- #self.logGameWithPath()
- #self.logGameWithArrow()
- path = self.logFriendly()
- cr = self.start[0];
- cc = self.start[1]
- ans = 1
- ans = ans + (ans % matrix[cr][cc])
- for i in range(self.GAME_WIDTH * self.GAME_HEIGHT - 1):
- if path[i] == 'N':
- cr-=1
- elif path[i] == 'S':
- cr+=1
- elif path[i] == 'W':
- cc-=1
- else:
- cc+=1
- #print(str(cr) + ' ' + str(cc))
- ans = ans + (ans % matrix[cr][cc])
- if ans > best:
- ansrow = self.start[0]
- anscol = self.start[1]
- beststring = path
- best = ans
- #self.verifyGame()
- print(str(anscol + 1) + ' ' + str(ansrow + 1))
- print(beststring)
- print(best)
- total += best
- sys.stderr.write('TOTAL ' + str(total))
- def logFriendly(self):
- #print ('' + str(self.start[1] + 1) + ' ' + str(self.start[0] + 1) + '')
- crow = self.start[0]
- ccol = self.start[1]
- ans = 1
- ret = ''
- for i in range(self.GAME_WIDTH * self.GAME_HEIGHT - 1):
- a = -1
- if (crow > 0) and (self.gameGrid[crow - 1][ccol] == self.FROM_SOUTH):
- a = 0
- if (crow < self.GAME_HEIGHT - 1) and (self.gameGrid[crow + 1][ccol] == self.FROM_NORTH):
- a = 1
- if (ccol > 0) and (self.gameGrid[crow][ccol - 1] == self.FROM_EAST):
- a = 2
- if (ccol < self.GAME_WIDTH - 1) and (self.gameGrid[crow][ccol + 1] == self.FROM_WEST):
- a = 3
- if a == -1:
- print('greska')
- elif a == 0:
- ret += 'N'
- crow -= 1
- elif a == 1:
- ret += 'S'
- crow += 1
- elif a == 2:
- ret += 'W'
- ccol -= 1
- else:
- ret += 'E'
- ccol += 1
- return ret
- def logGameWithPath(self):
- #print ('game width: ' + str(self.GAME_WIDTH))
- #print ('game height: ' + str(self.GAME_HEIGHT))
- print ('' + str(self.start[1] + 1) + ' ' + str(self.start[0] + 1) + '')
- gameText = ''
- for i in range(len(self.gameGrid)):
- for j in range(len(self.gameGrid[i])):
- if (self.gameGrid[i][j] == self.FROM_NORTH) or ((i > 0) and (self.gameGrid[i - 1][j] == self.FROM_SOUTH)):
- gameText = gameText + ' |'
- else:
- gameText = gameText + ' '
- gameText = gameText + ' \n'
- for j in range(len(self.gameGrid[i])):
- if (self.gameGrid[i][j] == self.FROM_WEST) or ((j > 0) and (self.gameGrid[i][j - 1] == self.FROM_EAST)):
- gameText = gameText + '-O'
- else:
- gameText = gameText + ' O'
- gameText = gameText + ' \n'
- for j in range(len(self.gameGrid[i])):
- gameText = gameText + ' '
- gameText = gameText + ' \n'
- print (gameText)
- def logGameWithArrow(self):
- print ('' + str(self.start[1] + 1) + ' ' + str(self.start[0] + 1) + '')
- gameText = ''
- for gameLine in self.gameGrid:
- for j in gameLine:
- if j == self.FROM_NOWHERE:
- gameText = gameText + 'X'
- elif j == self.FROM_NORTH:
- gameText = gameText + 'V'
- elif j == self.FROM_EAST:
- gameText = gameText + '('
- elif j == self.FROM_SOUTH:
- gameText = gameText + '^'
- elif j == self.FROM_WEST:
- gameText = gameText + ')'
- gameText = gameText + '\n'
- print (gameText)
- def moveExtremity(self, extremity):
- ## Search the points.
- possibleNewOrigins = []
- if ((extremity[0] < self.GAME_HEIGHT - 1) and (self.gameGrid[extremity[0] + 1][extremity[1]] != self.FROM_NORTH)):
- possibleNewOrigins.append(self.FROM_NORTH)
- besidePoint = [extremity[0] + 1, extremity[1]]
- elif ((extremity[1] > 0) and (self.gameGrid[extremity[0]][extremity[1] - 1] != self.FROM_EAST)):
- possibleNewOrigins.append(self.FROM_EAST)
- besidePoint = [extremity[0], extremity[1] - 1]
- elif ((extremity[0] > 0) and (self.gameGrid[extremity[0] - 1][extremity[1]] != self.FROM_SOUTH)):
- possibleNewOrigins.append(self.FROM_SOUTH)
- besidePoint = [extremity[0] - 1, extremity[1]]
- elif ((extremity[1] < self.GAME_WIDTH - 1) and (self.gameGrid[extremity[0]][extremity[1] + 1] != self.FROM_WEST)):
- possibleNewOrigins.append(self.FROM_WEST)
- besidePoint = [extremity[0], extremity[1] + 1]
- besidePointNewOrigin = possibleNewOrigins[random.randint(0, len(possibleNewOrigins) - 1)]
- if besidePointNewOrigin == self.FROM_NORTH:
- besidePoint = [extremity[0] + 1, extremity[1]]
- elif besidePointNewOrigin == self.FROM_EAST:
- besidePoint = [extremity[0], extremity[1] - 1]
- elif besidePointNewOrigin == self.FROM_SOUTH:
- besidePoint = [extremity[0] - 1, extremity[1]]
- elif besidePointNewOrigin == self.FROM_WEST:
- besidePoint = [extremity[0], extremity[1] + 1]
- ##print ('New start: [' + str(extremity[0]) + ', ' + str(extremity[1]) + ']')
- ##print ('besidePoint: [' + str(besidePoint[0]) + ', ' + str(besidePoint[1]) + ']')
- if self.gameGrid[besidePoint[0]][besidePoint[1]] == self.FROM_NORTH:
- newExtremity = [besidePoint[0] - 1, besidePoint[1]]
- elif self.gameGrid[besidePoint[0]][besidePoint[1]] == self.FROM_EAST:
- newExtremity = [besidePoint[0], besidePoint[1] + 1]
- elif self.gameGrid[besidePoint[0]][besidePoint[1]] == self.FROM_SOUTH:
- newExtremity = [besidePoint[0] + 1, besidePoint[1]]
- elif self.gameGrid[besidePoint[0]][besidePoint[1]] == self.FROM_WEST:
- newExtremity = [besidePoint[0], besidePoint[1] - 1]
- self.reversePath(extremity, newExtremity)
- self.gameGrid[besidePoint[0]][besidePoint[1]] = besidePointNewOrigin
- self.gameGrid[newExtremity[0]][newExtremity[1]] = self.FROM_NOWHERE
- ##print ('extremity: [' + str(newExtremity[0]) + ', ' + str(newExtremity[1]) + ']')
- return newExtremity
- def reversePath(self, start, end):
- currentPoint = start
- ##print ('start: [' + str(currentPoint[0]) + ', ' + str(currentPoint[1]) + ']')
- ##print ('end: [' + str(end[0]) + ', ' + str(end[1]) + ']')
- while (currentPoint[0] != end[0]) or (currentPoint[1] != end[1]):
- ##print ('currentPoint: [' + str(currentPoint[0]) + ', ' + str(currentPoint[1]) + ']')
- if (currentPoint[0] < self.GAME_HEIGHT - 1) and (self.gameGrid[currentPoint[0] + 1][currentPoint[1]] == self.FROM_NORTH) and (self.gameGrid[currentPoint[0]][currentPoint[1]] != self.FROM_SOUTH):
- self.gameGrid[currentPoint[0]][currentPoint[1]] = self.FROM_SOUTH
- currentPoint[0] = currentPoint[0] + 1
- elif (currentPoint[1] > 0) and (self.gameGrid[currentPoint[0]][currentPoint[1] - 1] == self.FROM_EAST) and (self.gameGrid[currentPoint[0]][currentPoint[1]] != self.FROM_WEST):
- self.gameGrid[currentPoint[0]][currentPoint[1]] = self.FROM_WEST
- currentPoint[1] = currentPoint[1] - 1
- elif (currentPoint[0] > 0) and (self.gameGrid[currentPoint[0] - 1][currentPoint[1]] == self.FROM_SOUTH) and (self.gameGrid[currentPoint[0]][currentPoint[1]] != self.FROM_NORTH):
- self.gameGrid[currentPoint[0]][currentPoint[1]] = self.FROM_NORTH
- currentPoint[0] = currentPoint[0] - 1
- elif (currentPoint[1] < self.GAME_WIDTH - 1) and (self.gameGrid[currentPoint[0]][currentPoint[1] + 1] == self.FROM_WEST) and (self.gameGrid[currentPoint[0]][currentPoint[1]] != self.FROM_EAST):
- self.gameGrid[currentPoint[0]][currentPoint[1]] = self.FROM_EAST
- currentPoint[1] = currentPoint[1] + 1
- ##print ('reversePath: [' + str(currentPoint[0]) + ', ' + str(currentPoint[1]) + ']')
- self.gameGrid[currentPoint[0]][currentPoint[1]] = self.UNDEFINED
- def verifyGame(self):
- moveCount = 0
- currentPoint = [self.start[0], self.start[1]]
- isEnd = 0
- while (isEnd == 0):
- if (currentPoint[0] < self.GAME_HEIGHT - 1) and (self.gameGrid[currentPoint[0] + 1][currentPoint[1]] == self.FROM_NORTH):
- currentPoint[0] = currentPoint[0] + 1
- elif (currentPoint[1] > 0) and (self.gameGrid[currentPoint[0]][currentPoint[1] - 1] == self.FROM_EAST):
- currentPoint[1] = currentPoint[1] - 1
- elif (currentPoint[0] > 0) and (self.gameGrid[currentPoint[0] - 1][currentPoint[1]] == self.FROM_SOUTH):
- currentPoint[0] = currentPoint[0] - 1
- elif (currentPoint[1] < self.GAME_WIDTH - 1) and (self.gameGrid[currentPoint[0]][currentPoint[1] + 1] == self.FROM_WEST):
- currentPoint[1] = currentPoint[1] + 1
- else:
- isEnd = 1
- if isEnd == 0:
- moveCount = moveCount + 1
- if moveCount == ((self.GAME_HEIGHT * self.GAME_WIDTH) - 1):
- print ('OK')
- else:
- print ('ko!!!')
- def initGame(self):
- self.gameGrid = []
- for i in range(self.GAME_HEIGHT):
- gameLine = []
- for j in range(self.GAME_WIDTH):
- gameLine.append(self.UNDEFINED)
- self.gameGrid.append(gameLine)
- self.initComplexMap()
- def initComplexMap(self):
- startPoint = random.randint(0, 3)
- if startPoint == 0:
- self.start = [0, 0]
- elif startPoint == 1:
- self.start = [0, self.GAME_WIDTH - 1]
- elif startPoint == 2:
- self.start = [self.GAME_HEIGHT - 1, 0]
- elif startPoint == 3:
- self.start = [self.GAME_HEIGHT - 1, self.GAME_WIDTH - 1]
- self.gameGrid[self.start[0]][self.start[1]] = self.FROM_NOWHERE
- currentPoint = [self.start[0], self.start[1]]
- while ((0 < currentPoint[0]) and (self.gameGrid[currentPoint[0] - 1][currentPoint[1]] == self.UNDEFINED)) or ((currentPoint[0] < self.GAME_HEIGHT - 1) and (self.gameGrid[currentPoint[0] + 1][currentPoint[1]] == self.UNDEFINED)) or ((0 < currentPoint[1]) and (self.gameGrid[currentPoint[0]][currentPoint[1] - 1] == self.UNDEFINED)) or ((currentPoint[1] < self.GAME_WIDTH - 1) and (self.gameGrid[currentPoint[0]][currentPoint[1] + 1] == self.UNDEFINED)):
- possibilities = []
- if ((0 < currentPoint[0]) and (self.gameGrid[currentPoint[0] - 1][currentPoint[1]] == self.UNDEFINED)) and (((0 == currentPoint[1]) or (self.gameGrid[currentPoint[0] - 1][currentPoint[1] - 1] != self.UNDEFINED)) or ((currentPoint[1] == self.GAME_WIDTH - 1) or (self.gameGrid[currentPoint[0] - 1][currentPoint[1] + 1] != self.UNDEFINED))):
- possibilities.append([currentPoint[0] - 1, currentPoint[1], self.FROM_SOUTH])
- if ((currentPoint[0] < self.GAME_HEIGHT - 1) and (self.gameGrid[currentPoint[0] + 1][currentPoint[1]] == self.UNDEFINED)) and (((0 == currentPoint[1]) or (self.gameGrid[currentPoint[0] + 1][currentPoint[1] - 1] != self.UNDEFINED)) or ((currentPoint[1] == self.GAME_WIDTH - 1) or (self.gameGrid[currentPoint[0] + 1][currentPoint[1] + 1] != self.UNDEFINED))):
- possibilities.append([currentPoint[0] + 1, currentPoint[1], self.FROM_NORTH])
- if ((0 < currentPoint[1]) and (self.gameGrid[currentPoint[0]][currentPoint[1] - 1] == self.UNDEFINED)) and (((0 == currentPoint[0]) or (self.gameGrid[currentPoint[0] - 1][currentPoint[1] - 1] != self.UNDEFINED)) or ((currentPoint[0] == self.GAME_HEIGHT - 1) or (self.gameGrid[currentPoint[0] + 1][currentPoint[1] - 1] != self.UNDEFINED))):
- possibilities.append([currentPoint[0], currentPoint[1] - 1, self.FROM_EAST])
- if ((currentPoint[1] < self.GAME_WIDTH - 1) and (self.gameGrid[currentPoint[0]][currentPoint[1] + 1] == self.UNDEFINED)) and (((0 == currentPoint[0]) or (self.gameGrid[currentPoint[0] - 1][currentPoint[1] + 1] != self.UNDEFINED)) or ((currentPoint[0] == self.GAME_HEIGHT - 1) or (self.gameGrid[currentPoint[0] + 1][currentPoint[1] + 1] != self.UNDEFINED))):
- possibilities.append([currentPoint[0], currentPoint[1] + 1, self.FROM_WEST])
- possibility = possibilities.pop(random.randint(0, len(possibilities) - 1))
- currentPoint = [possibility[0], possibility[1]]
- self.gameGrid[possibility[0]][possibility[1]] = possibility[2]
- def initSimpleMap(self):
- direction = self.RIGHT
- if random.randint(0, 1) == 0:
- for i in range(self.GAME_HEIGHT):
- if direction == self.RIGHT:
- self.gameGrid[i][0] = self.FROM_NORTH
- for j in range(1, self.GAME_WIDTH):
- self.gameGrid[i][j] = self.FROM_WEST
- direction = self.LEFT
- else:
- for j in range(self.GAME_WIDTH - 1):
- self.gameGrid[i][j] = self.FROM_EAST
- self.gameGrid[i][self.GAME_WIDTH - 1] = self.FROM_NORTH
- direction = self.RIGHT
- self.gameGrid.append(gameLine)
- self.gameGrid[0][0] = self.FROM_NOWHERE
- else:
- for j in range(self.GAME_WIDTH):
- if direction == self.RIGHT:
- self.gameGrid[0][j] = self.FROM_WEST
- for i in range(1, self.GAME_HEIGHT):
- self.gameGrid[i][j] = self.FROM_NORTH
- direction = self.LEFT
- else:
- for i in range(self.GAME_HEIGHT - 1):
- self.gameGrid[i][j] = self.FROM_SOUTH
- self.gameGrid[self.GAME_HEIGHT - 1][j] = self.FROM_WEST
- direction = self.RIGHT
- self.gameGrid[0][0] = self.FROM_NOWHERE
- def listPermutation(self):
- self.permutableZones = []
- for i in range(self.GAME_HEIGHT - 1):
- for j in range(self.GAME_WIDTH - 1):
- if (self.gameGrid[i + 1][j] == self.FROM_NORTH) and (self.gameGrid[i][j + 1] == self.FROM_SOUTH):
- self.permutableZones.append([[i + 1, j], [i, j + 1]])
- elif (self.gameGrid[i][j] == self.FROM_SOUTH) and (self.gameGrid[i + 1][j + 1] == self.FROM_NORTH):
- self.permutableZones.append([[i, j], [i + 1, j + 1]])
- elif (self.gameGrid[i][j] == self.FROM_EAST) and (self.gameGrid[i + 1][j + 1] == self.FROM_WEST):
- self.permutableZones.append([[i, j], [i + 1, j + 1]])
- elif (self.gameGrid[i][j + 1] == self.FROM_WEST) and (self.gameGrid[i + 1][j] == self.FROM_EAST):
- self.permutableZones.append([[i, j + 1], [i + 1, j]])
- def permutate(self):
- self.listPermutation()
- if len(self.permutableZones) > 0:
- permutation = self.permutableZones.pop(random.randint(0, len(self.permutableZones) - 1))
- start = permutation[0]
- end = permutation[1]
- ##print ('Entry of the loop: (' + str(start[0]) + ', ' + str(start[1]) + ')')
- ##print ('Exit of the loop: (' + str(end[0]) + ', ' + str(end[1]) + ')')
- if self.isLoop(end, start):
- self.findPermutation(start, end)
- else:
- end = permutation[0]
- start = permutation[1]
- if not self.isLoop(end, start):
- print ('Wrong!')
- self.findPermutation(start, end)
- def isInLoop(self, searchedPoint):
- found = False
- for point in self.currentLoop:
- if (searchedPoint[0] == point[0]) and (searchedPoint[1] == point[1]):
- found = True
- return found
- def isLoop(self, originalPoint, destination):
- self.currentLoop = []
- point = []
- point.append(originalPoint[0])
- point.append(originalPoint[1])
- self.currentLoop.append([originalPoint[0], originalPoint[1]])
- while ((point[0] != destination[0]) or (point[1] != destination[1])) and (self.gameGrid[point[0]][point[1]] != self.FROM_NOWHERE):
- ##print ('Loop point: (' + str(point[0]) + ', ' + str(point[1]) + ')')
- newY = point[0]
- newX = point[1]
- if self.gameGrid[point[0]][point[1]] == self.FROM_SOUTH:
- newY = point[0] + 1
- elif self.gameGrid[point[0]][point[1]] == self.FROM_NORTH:
- newY = point[0] - 1
- elif self.gameGrid[point[0]][point[1]] == self.FROM_WEST:
- newX = point[1] - 1
- elif self.gameGrid[point[0]][point[1]] == self.FROM_EAST:
- newX = point[1] + 1
- point[0] = newY
- point[1] = newX
- self.currentLoop.append([newY, newX])
- return ((point[0] == destination[0]) and (point[1] == destination[1]))
- def findPermutation(self, start, end):
- self.findIntersections()
- if len(self.intersections) > 0:
- self.modifyIntersection(start, end)
- def findIntersections(self):
- self.intersections = []
- for i in range(1, len(self.currentLoop) - 1):
- point = self.currentLoop[i]
- if self.gameGrid[point[0]][point[1]] == self.FROM_NORTH:
- if (0 < point[1]) and (self.gameGrid[point[0] - 1][point[1] - 1] == self.FROM_SOUTH) and not self.isInLoop([point[0] - 1, point[1] - 1]):
- self.intersections.append([[point[0], point[1]], [point[0] - 1, point[1] - 1]])
- elif (point[1] < self.GAME_WIDTH - 1) and (self.gameGrid[point[0] - 1][point[1] + 1] == self.FROM_SOUTH) and not self.isInLoop([point[0] - 1, point[1] + 1]):
- self.intersections.append([[point[0], point[1]], [point[0] - 1, point[1] + 1]])
- elif self.gameGrid[point[0]][point[1]] == self.FROM_SOUTH:
- if (0 < point[1]) and (self.gameGrid[point[0] + 1][point[1] - 1] == self.FROM_NORTH) and not self.isInLoop([point[0] + 1, point[1] - 1]):
- self.intersections.append([[point[0], point[1]], [point[0] + 1, point[1] - 1]])
- elif (point[1] < self.GAME_WIDTH - 1) and (self.gameGrid[point[0] + 1][point[1] + 1] == self.FROM_NORTH) and not self.isInLoop([point[0] + 1, point[1] + 1]):
- self.intersections.append([[point[0], point[1]], [point[0] + 1, point[1] + 1]])
- elif self.gameGrid[point[0]][point[1]] == self.FROM_WEST:
- if (0 < point[0]) and (self.gameGrid[point[0] - 1][point[1] - 1] == self.FROM_EAST) and not self.isInLoop([point[0] - 1, point[1] - 1]):
- self.intersections.append([[point[0], point[1]], [point[0] - 1, point[1] - 1]])
- elif (point[0] < self.GAME_HEIGHT - 1) and (self.gameGrid[point[0] + 1][point[1] - 1] == self.FROM_EAST) and not self.isInLoop([point[0] + 1, point[1] - 1]):
- self.intersections.append([[point[0], point[1]], [point[0] + 1, point[1] - 1]])
- elif self.gameGrid[point[0]][point[1]] == self.FROM_EAST:
- if (0 < point[0]) and (self.gameGrid[point[0] - 1][point[1] + 1] == self.FROM_WEST) and not self.isInLoop([point[0] - 1, point[1] + 1]):
- self.intersections.append([[point[0], point[1]], [point[0] - 1, point[1] + 1]])
- elif (point[0] < self.GAME_HEIGHT - 1) and (self.gameGrid[point[0] + 1][point[1] + 1] == self.FROM_WEST) and not self.isInLoop([point[0] + 1, point[1] + 1]):
- self.intersections.append([[point[0], point[1]], [point[0] + 1, point[1] + 1]])
- ## Permutate the connections of path.
- ## It receives and returns a valid map.
- def modifyIntersection(self, start, end):
- ##self.logGameWithPath()
- ##self.printGameOld()
- intersection = self.intersections[random.randint(0, len(self.intersections) - 1)]
- self.modifyPath([start, end])
- self.modifyPath(intersection)
- def modifyPath(self, intersection):
- ##print ('modifyPath: (' + str(intersection[0][0]) + ', ' + str(intersection[0][1]) + ') with (' + str(intersection[1][0]) + ', ' + str(intersection[1][1]) + ')')
- firstPoint = self.gameGrid[intersection[0][0]][intersection[0][1]]
- secondPoint = self.gameGrid[intersection[1][0]][intersection[1][1]]
- if (self.gameGrid[intersection[0][0]][intersection[0][1]] == self.FROM_NORTH) or (self.gameGrid[intersection[0][0]][intersection[0][1]] == self.FROM_SOUTH):
- if (intersection[0][1] < intersection[1][1]):
- firstPoint = self.FROM_EAST
- secondPoint = self.FROM_WEST
- else:
- firstPoint = self.FROM_WEST
- secondPoint = self.FROM_EAST
- if (self.gameGrid[intersection[0][0]][intersection[0][1]] == self.FROM_EAST) or (self.gameGrid[intersection[0][0]][intersection[0][1]] == self.FROM_WEST):
- if (intersection[0][0] < intersection[1][0]):
- firstPoint = self.FROM_SOUTH
- secondPoint = self.FROM_NORTH
- else:
- firstPoint = self.FROM_NORTH
- secondPoint = self.FROM_SOUTH
- self.gameGrid[intersection[0][0]][intersection[0][1]] = firstPoint
- self.gameGrid[intersection[1][0]][intersection[1][1]] = secondPoint
- cellRoom = CellRoom()
- cellRoom.generateGame()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement