def loadGame(self, jsonText): jsonData = json.loads(jsonText, encoding = "utf-8") game = Game(jsonData) # init state self.game = game self.gameField = game.startField self.rndGenerator = Random(game.sourceSeeds[0]) self.unitIndex = self.rndGenerator.next() % len(self.game.units) self.currentUnit = self.game.units[self.unitIndex] self.currentUnitOffsets = self.game.unitStartOffsets[self.unitIndex] self.currentUnitRotation = 0 self.lastCleanedLines = 0 self.score = 0 self.drawField() drawUnit(self.scene, self.currentUnit, self.currentUnitOffsets) return
class VizFrame(QtGui.QWidget): def __init__(self): super(VizFrame, self).__init__() self.initUI() self.currentFile = "test_data/problem_23.json" self.loadFileData(self.currentFile) def initUI(self): self.setGeometry(300,300,250,150) self.setWindowTitle('Event handler') self.resize(800, 600) grview = QGraphicsView(self) self.scene = QGraphicsScene() grview.setScene(self.scene) grview.resize(640, 480) sidebar = QWidget(self) sidebarLayout = QVBoxLayout() sidebar.move(640, 0) sidebar.setFixedWidth(160) self.srcTextEdit = QTextEdit(self) self.srcTextEdit.setFixedHeight(100) self.solTextEdit = QTextEdit(self) self.solTextEdit.setFixedHeight(100) panel = QWidget(self) panel.setGeometry(QRect(640, 100, 160, 40)) panelButtons = QHBoxLayout(self) btnLoad = QPushButton ("Load") def onLoadClick(): jsonStr = str(self.srcTextEdit.toPlainText()) self.loadGame(jsonStr) return btnLoad.clicked.connect(onLoadClick) btnPrev = QPushButton ("<<") def onPrevClick(): dir = os.path.dirname(self.currentFile) file = os.path.basename(self.currentFile) files = filter(lambda f: fnmatch.fnmatch(f, '*.json'), os.listdir(dir)) jsonFile = files[files.index(file) - 1] self.loadFileData(os.path.join(dir, jsonFile)) btnPrev.clicked.connect(onPrevClick) btnNext = QPushButton (">>") def onNextClick(): dir = os.path.dirname(self.currentFile) file = os.path.basename(self.currentFile) files = filter(lambda f: fnmatch.fnmatch(f, '*.json'), os.listdir(dir)) jsonFile = files[files.index(file) + 1] self.loadFileData(os.path.join(dir, jsonFile)) btnNext.clicked.connect(onNextClick) panelButtons.addWidget(btnPrev) panelButtons.addWidget(btnLoad) panelButtons.addWidget(btnNext) panel.setLayout(panelButtons) btnPlay = QPushButton("Play") def onPlayClick(): solStr = str(self.solTextEdit.toPlainText()) self.play(solStr) return btnPlay.clicked.connect(onPlayClick) btnSolve = QPushButton("Solve") def onSolveClick(): solver = icfp_solver.Solver(self.game) solStr = solver.solve(self.game.sourceSeeds[0]) solStr = self.game.makeCommands(self.game.sourceSeeds[0], [solStr]) self.solTextEdit.setText(solStr) return btnSolve.clicked.connect(onSolveClick) sidebarLayout.addWidget(self.srcTextEdit) sidebarLayout.addWidget(panel) sidebarLayout.addWidget(self.solTextEdit) sidebarLayout.addWidget(btnPlay) sidebarLayout.addWidget(btnSolve) sidebar.setLayout(sidebarLayout) self.show() return def keyPressEvent(self, e): if e.key() == QtCore.Qt.Key_Space: self.nextUnit() elif e.key() == QtCore.Qt.Key_S: self.makeMove(MoveType.RC) elif e.key() == QtCore.Qt.Key_W: self.makeMove(MoveType.RCC) elif e.key() == QtCore.Qt.Key_Q: self.makeMove(MoveType.W) elif e.key() == QtCore.Qt.Key_E: self.makeMove(MoveType.E) elif e.key() == QtCore.Qt.Key_A: self.makeMove(MoveType.SW) elif e.key() == QtCore.Qt.Key_D: self.makeMove(MoveType.SE) return def makeMove(self, moveType): (_a, o, r) = self.game.makeMove(self.gameField , self.currentUnit, self.currentUnitOffsets, self.currentUnitRotation, moveType) result = True if _a: self.currentUnitOffsets = o self.currentUnitRotation = r else: # lock unit cells = self.currentUnit.moveAndRotate(self.currentUnitOffsets, self.currentUnitRotation) self.gameField = self.gameField.fillCells(cells) [self.game.filledCells.append(c) for c in cells] # clear lines lines = self.gameField.countLines() if lines > 0: self.gameField = self.gameField.cleanLines() # calculate score points = len(self.currentUnit.members) + 100 * (1 + lines) * lines / 2 if self.lastCleanedLines > 1: line_bonus = math.floor((self.lastCleanedLines - 1) * points / 10) else: line_bonus = 0 move_score = points + line_bonus self.lastCleanedLines = lines self.score += move_score print("Score: ", move_score, self.score) # spawn next unit self.nextUnit() cells = self.currentUnit.moveAndRotate(self.currentUnitOffsets, self.currentUnitRotation) result = self.gameField.checkCells(cells) self.redraw() return result def loadGame(self, jsonText): jsonData = json.loads(jsonText, encoding = "utf-8") game = Game(jsonData) # init state self.game = game self.gameField = game.startField self.rndGenerator = Random(game.sourceSeeds[0]) self.unitIndex = self.rndGenerator.next() % len(self.game.units) self.currentUnit = self.game.units[self.unitIndex] self.currentUnitOffsets = self.game.unitStartOffsets[self.unitIndex] self.currentUnitRotation = 0 self.lastCleanedLines = 0 self.score = 0 self.drawField() drawUnit(self.scene, self.currentUnit, self.currentUnitOffsets) return def loadFileData(self, file): self.currentFile = file with open(self.currentFile) as data_file: data = data_file.read() self.srcTextEdit.setText(data) self.loadGame(data) def nextUnit(self): self.unitIndex = self.rndGenerator.next() % len(self.game.units) self.currentUnit = self.game.units[self.unitIndex] self.currentUnitOffsets = self.game.unitStartOffsets[self.unitIndex] self.currentUnitRotation = 0 self.drawField() drawUnit(self.scene, self.currentUnit, self.currentUnitOffsets) return def drawField(self): w = self.game.startField.width h = self.game.startField.height self.scene.clear() for x in xrange(0, w): for y in xrange(0, h): drawHex(self.scene, x, y, not self.gameField.field[y, x]) return def redraw(self): self.drawField() drawUnit(self.scene, self.currentUnit, self.currentUnitOffsets, self.currentUnitRotation) return def play(self, solStr): moveCount = 0 for c in solStr.lower(): moveCount += 1 if (c not in ['\r', '\n', '\t']): move = MoveType.fromChar(c) res = self.makeMove(move) if not res: break QtGui.QApplication.processEvents() print "moves {0} / {1}".format(moveCount, len(solStr)) return
def convert(self, str, seed): rnd = Random(seed + 1) return "".join([MoveType.toChars[s][rnd.next() % len(MoveType.toChars[s])] for s in str])
def makeCommands(self, seed, default_commands, einificate = True): """ main method - should return sequence of commands """ self.rndGenerator = Random(seed) unitIndex = self.rndGenerator.next() % len(self.units) currentUnit = self.units[unitIndex] currentOffset = self.unitStartOffsets[unitIndex] currentRotation = 0 currentField = self.startField cmds = self.strToCommands(default_commands[0]) valid_commands = [] previousWasBad = False last_cmd = MoveType.IGN unitsCounter = 0 while(True): if previousWasBad: break cmd_index = -1 for cmd in cmds: cmd_index = (cmd_index + 1) % len(cmds) (moveResult, newOffset, newRotation, cmd2) = self.substituteMove(currentField, currentUnit, currentOffset, currentRotation, cmd) if moveResult: if einificate and cmd2 == MoveType.SW and last_cmd != MoveType.W: #print "eification" offset = currentOffset rotation = currentRotation eiResult = True for ei in self.strToCommands("Ei!"): (mr, offset, rotation) = self.makeMove(currentField, currentUnit, offset, rotation, ei) if not mr: eiResult = False break if eiResult: valid_commands.append("Ei!") #print "eificated" else: if cmd2 == cmd: valid_commands.append(default_commands[0][cmd_index]) else: valid_commands.append(cmd2) else: if cmd2 == cmd: valid_commands.append(default_commands[0][cmd_index]) else: valid_commands.append(cmd2) previousWasBad = False currentOffset = newOffset currentRotation = newRotation last_cmd = cmd2 else: #todo: spawn new Unit here if previousWasBad: break valid_commands.append(default_commands[0][cmd_index]) previousWasBad = True if unitsCounter >= self.sourceLength: break currentField = currentField.fillCells(currentUnit.moveAndRotate(currentOffset, currentRotation)).cleanLines() unitIndex = self.rndGenerator.next() % len(self.units) currentUnit = self.units[unitIndex] currentOffset = self.unitStartOffsets[unitIndex] currentRotation = 0 unitsCounter += 1 #return "".join([ # default_commands[0] for i in range(len(valid_commands) // len(default_commands[0]))]) + default_commands[0][:(len(valid_commands) % len(default_commands[0]))] return "".join(valid_commands)
class Game(object): def __init__(self, data): logging.debug("in game construction") logging.debug(data) self.startField = Field(**data) self.filledCells = [Cell(**cell_info) for cell_info in data["filled"]] self.sourceLength = data["sourceLength"] self.sourceSeeds = data["sourceSeeds"] self.id = data["id"] self.startField = self.startField.fillCells(self.filledCells) self.units = [Unit(**unit_info) for unit_info in data["units"]] self.unitStartOffsets = [self.startField.computePivotStartOffset(unit) for unit in self.units] def convert(self, str, seed): rnd = Random(seed + 1) return "".join([MoveType.toChars[s][rnd.next() % len(MoveType.toChars[s])] for s in str]) ##following line is an example of cells emptyness check: #print self.startField.fillCells([Cell({"x":1, "y":1})]).checkCells([Cell({"x":1, "y":1})]) def process(self, phrasesOfPower): return [Solution(self.id, seed, self, phrasesOfPower) for seed in self.sourceSeeds] def makeMove(self, currentField, unit, currentOffset, currentRotation, moveType): """ performs move for current unit and checks it position in currentField """ newOffset = currentOffset newRotation = currentRotation if moveType == MoveType.W: newOffset = Cell.fromTriplet(currentOffset.toTriplet().west()) if moveType == MoveType.E: newOffset = Cell.fromTriplet(currentOffset.toTriplet().east()) if moveType == MoveType.SE: newOffset = Cell.fromTriplet(currentOffset.toTriplet().southEast()) if moveType == MoveType.SW: newOffset = Cell.fromTriplet(currentOffset.toTriplet().southWest()) if moveType == MoveType.RC: newRotation = (currentRotation + 1) % 6 if moveType == MoveType.RCC: newRotation = (currentRotation - 1) % 6 #next - check if unit can be placed at new position cells = unit.moveAndRotate(newOffset, newRotation) moveResult = currentField.checkCells(cells) return (moveResult, newOffset, newRotation) def strToCommands(self, str): return filter(lambda x: x!= MoveType.IGN, [MoveType.fromChar(ch) for ch in str]) def substituteMove(self, currentField, currentUnit, currentOffset, currentRotation, cmd): for cmd2 in [cmd, MoveType.SE, MoveType.SW, MoveType.RC, MoveType.RCC, MoveType.E, MoveType.W]: (moveResult, newOffset, newRotation) = self.makeMove(currentField, currentUnit, currentOffset, currentRotation, cmd) if moveResult: return (moveResult, newOffset, newRotation, cmd2) return (False, currentOffset, currentRotation, cmd) def makeCommands(self, seed, default_commands, einificate = True): """ main method - should return sequence of commands """ self.rndGenerator = Random(seed) unitIndex = self.rndGenerator.next() % len(self.units) currentUnit = self.units[unitIndex] currentOffset = self.unitStartOffsets[unitIndex] currentRotation = 0 currentField = self.startField cmds = self.strToCommands(default_commands[0]) valid_commands = [] previousWasBad = False last_cmd = MoveType.IGN unitsCounter = 0 while(True): if previousWasBad: break cmd_index = -1 for cmd in cmds: cmd_index = (cmd_index + 1) % len(cmds) (moveResult, newOffset, newRotation, cmd2) = self.substituteMove(currentField, currentUnit, currentOffset, currentRotation, cmd) if moveResult: if einificate and cmd2 == MoveType.SW and last_cmd != MoveType.W: #print "eification" offset = currentOffset rotation = currentRotation eiResult = True for ei in self.strToCommands("Ei!"): (mr, offset, rotation) = self.makeMove(currentField, currentUnit, offset, rotation, ei) if not mr: eiResult = False break if eiResult: valid_commands.append("Ei!") #print "eificated" else: if cmd2 == cmd: valid_commands.append(default_commands[0][cmd_index]) else: valid_commands.append(cmd2) else: if cmd2 == cmd: valid_commands.append(default_commands[0][cmd_index]) else: valid_commands.append(cmd2) previousWasBad = False currentOffset = newOffset currentRotation = newRotation last_cmd = cmd2 else: #todo: spawn new Unit here if previousWasBad: break valid_commands.append(default_commands[0][cmd_index]) previousWasBad = True if unitsCounter >= self.sourceLength: break currentField = currentField.fillCells(currentUnit.moveAndRotate(currentOffset, currentRotation)).cleanLines() unitIndex = self.rndGenerator.next() % len(self.units) currentUnit = self.units[unitIndex] currentOffset = self.unitStartOffsets[unitIndex] currentRotation = 0 unitsCounter += 1 #return "".join([ # default_commands[0] for i in range(len(valid_commands) // len(default_commands[0]))]) + default_commands[0][:(len(valid_commands) % len(default_commands[0]))] return "".join(valid_commands)