def __init__(self, player_details, canvas): self.players = [ Player(name, order, is_human) for (order, (name, is_human)) in enumerate(player_details) ] self.tiles = Tiles() self.locations = Locations(self) self.active_tile = None self.active_target = None self.mode = GameMode.SELECTING_TILE self.canvas = canvas self.source = [] self.target = [] # TODO: Move fonts into Settings or separate fonts module? self.small_floor_tile_scores_font = pygame.font.SysFont( 'Arial', Settings.floor_tile_scores_font_size) self.large_floor_tile_scores_font = pygame.font.SysFont( 'Arial', int(Settings.floor_tile_scores_font_size * Settings.player_area_multiplier)) self.button_font = self.large_floor_tile_scores_font # TODO: Move this in with the ButtonLocation? x, y = Settings.player_area_location multiplier = Settings.player_area_multiplier x += Settings.pattern_area_width * multiplier x += 2 * Settings.tile_width * multiplier width = 3 * Settings.tile_width * multiplier y += (Settings.area_height - Settings.tile_height * 1.9) * multiplier height = Settings.tile_height * multiplier self.locations.all.append( ButtonLocation(self, x, y, width, height, 'Continue', 'confirm'))
def ckan_tiles(self, draw): hand = Tiles() hand.tiles = self.hand.tiles[:] hand.add_tiles(draw) search = [] quad = [tile for tile in hand.tiles if hand.tiles.count(tile) == 4] while len(quad) > 0: first_quad = [tile for tile in quad if tile == quad[0]] search.append(first_quad) for tile in first_quad: quad.remove(tile) pon = [ meld for meld in self.melds.melds if meld.tiles.count(meld.tiles[0]) == 3 ] if pon: for meld in pon: if meld.tiles[0] in hand.tiles: search.append([ meld, [tile for tile in hand.tiles if tile == meld.tiles[0]][0] ]) if search: return search return False
def test_can_flip_tiles(): tiles = Tiles(800, 8, 100, 0) # [-, -, -, -, -, -, -, -] # [-, -, -, -, -, -, -, -] # [-, -, -, -, W, -, -, -] # [-, -, -, W, W, -, -, -] # [-, -, -, W, W, B, -, -] # [-, -, -, B, W, W, -, -] # [-, -, B, -, -, -, -, -] # [-, -, -, -, -, -, -, -] tiles.tiles[2][4].set_color(COLOR_WHITE) tiles.tiles[3][3].set_color(COLOR_WHITE) tiles.tiles[3][4].set_color(COLOR_WHITE) tiles.tiles[4][3].set_color(COLOR_WHITE) tiles.tiles[4][4].set_color(COLOR_WHITE) tiles.tiles[4][5].set_color(COLOR_BLACK) tiles.tiles[5][3].set_color(COLOR_BLACK) tiles.tiles[5][4].set_color(COLOR_WHITE) tiles.tiles[5][5].set_color(COLOR_WHITE) tiles.tiles[6][2].set_color(COLOR_BLACK) row, col = 0, 0 coordinates = tiles.can_flip_tiles(row, col, COLOR_BLACK) assert len(coordinates) == 0 row, col = 2, 3 coordinates = tiles.can_flip_tiles(row, col, COLOR_BLACK) assert len(coordinates) == 3
def test_flip_tiles(): ts = Tiles(8, 8) flips = {"right": [(3, 3)]} ts.flip_tiles(0, flips) assert ts.tiles[3][3].color == 0 assert ts.tile_counts["white"] == 1 assert ts.tile_counts["black"] == 3
def __init__(self, WIDTH, HEIGHT, GRID, game_controller): self.WIDTH = WIDTH self.HEIGHT = HEIGHT self.GRID = GRID self.row = self.HEIGHT // self.GRID self.centre = self.GRID // 2 self.gc = game_controller # Initial tile numbers self.black = 0 self.white = 0 # Controls each player's turn to make a move self.whiteTurn = False # The game board as a nested list self.table = [] self.available = [] for i in range(1, self.row + 1): self.available.append(i) self.table.append( [i for i in range(1, self.WIDTH // self.GRID + 1)]) self.tiles = Tiles(self.GRID, self.table) # 8 directions for seaching legal moves and flipping self.ROW_VEC = [1, -1, 0, 0, -1, 1, -1, 1] self.COL_VEC = [0, 0, -1, 1, -1, -1, 1, 1] self.flip_time = 0 self.gc.end_time = self.flip_time
def rail_items(self, data, mode, list_=True): highlights = True if 'highlights' in mode else False focus = data.get('StartPosition', False) for i in data.get('Tiles', []): context = Context(self.plugin) item = Tiles(self.plugin, i).item if highlights: if item['type'] == 'Highlights': item['cm'] = context.goto(item) self.items.add_item(item) elif item.get('related', []): for i in item['related']: if i.get('Videos', []): _item = Tiles(self.plugin, i).item _item['cm'] = context.goto(_item) self.items.add_item(_item) else: if item.get('related', []): cm_items = [] for i in item['related']: if i.get('Videos', []): cm_items.append(Tiles(self.plugin, i).item) context.related(cm_items) item['cm'] = context.goto(item) self.items.add_item(item) if list_: self.items.list_items(focus)
def test_add_black(): t = Tiles(800, 100, 90) t.add_black(0, 0) assert t.black_num == 3 assert t.squares[0][0] == 0 assert t.player_tiles[0][0].x == 50 assert t.player_tiles[0][0].y == 50
def test_add_white(): t = Tiles(800, 100, 90) t.add_white(0, 0) assert t.white_num == 3 assert t.squares[0][0] == 0 assert t.computer_tiles[0][0].x == 50 assert t.computer_tiles[0][0].y == 50
def __init__(self, length, size, side, offset): self.length = length self.side = side self.size = size # side length for each cube self.offset = offset self.tiles = Tiles(self.length, self.size, self.side, self.offset)
def __init__(self, parent, lat=32.10932741542229, lon=34.89818882620658, zoom=15): super().__init__(parent) Projection.__init__(self) Tiles.__init__(self, self.tileRetrieved) self.recentre(lat, lon, zoom) self.drag = False self.dragStartCoords = (0, 0) self.layers = [] self.Bind(wx.EVT_SIZE, self.sizeChanged) self.Bind(wx.EVT_PAINT, self.updatePanel) self.Bind(wx.EVT_MOUSEWHEEL, self.scroll_event) self.Bind(wx.EVT_LEFT_DOWN, self.click) self.Bind(wx.EVT_LEFT_UP, self.release) self.Bind(wx.EVT_MOTION, self.mousemove) self.Bind(wx.EVT_MOUSEWHEEL, self.scroll_event) size = self.GetSize() self.mousePosition = wx.Point(size.GetWidth() / 2, size.GetHeight() / 2) self.SetBackgroundStyle(wx.BG_STYLE_PAINT)
async def riichi(self, draw, game): #this *should* check the hand to make sure its closed opened = [meld for meld in self.melds.melds if meld.opened] if opened: return False #determine what tiles are discardable to be in tenpai shanten = shanten_calculator(str(self.hand) + str(draw)) if (shanten == 0 or shanten == -1) and self.points >= 1000 and not self.in_riichi: riichi_tiles = [] temp_hand = Tiles() temp_hand.tiles = self.hand.tiles[:] temp_hand.add_tiles(draw) for tile in temp_hand.tiles: temp = Tiles() temp.tiles = temp_hand.tiles[:] temp.remove_tiles(tile) if winning_tiles(str(temp)) and tile not in riichi_tiles: riichi_tiles.append(tile) if riichi_tiles: try: reach = await self.user_input('Would you like to riichi?') except asyncio.exceptions.TimeoutError: reach = 'n' if reach != 'y' and reach != 'yes': return False else: return False discard = Tile('8', 'z') while discard not in self.hand.tiles and discard != draw: try: query = "Which tile would you like to riichi on? Type cancel to cancel riichi.\n" + ' '.join( map(str, riichi_tiles)) discard = await self.user_input(query) discard = Tile(discard[0], discard[1]) except asyncio.exceptions.TimeoutError: return False except ValueError: discard = Tile('8', 'z') except IndexError: discard = Tile('8', 'z') #self.discard_tile(choice) if game.tenhou and game.wall.remaining > 65: self.double_riichi = True self.in_riichi = True self.ippatsu = True self.points -= 1000 game.riichi += 1 return discard else: return False '''
def test_evaluate_valid_moves(): tiles = Tiles(800, 8, 100, 0) assert len(tiles.tile_flip_lookup) == 0 # fulfill tile flip lookup dictionary tiles.evaluate_valid_moves(COLOR_BLACK) assert len(tiles.tile_flip_lookup) == 4
def __init__(self, WIDTH, HEIGHT, game_controller): self.WIDTH = WIDTH self.HEIGHT = HEIGHT self.SPACING = 100 self.COLS = self.WIDTH // self.SPACING self.ROWS = self.HEIGHT // self.SPACING self.squares = Tiles(self.COLS, self.ROWS) # Control the interation between players and tiles self.gc = game_controller
def test_flip_tiles(): tiles = Tiles(800, 8, 100, 0) coordinates = [(0, 0), (0, 1), (0, 2)] prev_count = count_tiles(tiles.tiles) tiles.flip_tiles(coordinates, COLOR_BLACK) curr_count = count_tiles(tiles.tiles) assert curr_count == prev_count + 3
def test_one_line_check(self): t = Tiles(100, 8, 255, 0) self.assertEqual(t.tiles[t.num // 2 - 1][t.num // 2 - 1].color, 255) self.assertTrue(t.one_line_check(t.num // 2 - 2, t.num // 2 - 1, 1, 0, 0, False)) self.assertEqual(t.tiles[t.num // 2 - 1][t.num // 2 - 1].color, 255) self.assertTrue(t.one_line_check(t.num // 2 - 2, t.num // 2 - 1, 1, 0, 0, True)) self.assertEqual(t.tiles[t.num // 2 - 1][t.num // 2 - 1].color, 0)
def test_calculate_flips(): tiles = Tiles(800, 8, 100, 0) row, col = 5, 3 coordinates = tiles.can_flip_tiles(row, col, COLOR_BLACK) assert len(coordinates) == 0 row, col = 3, 2 coordinates = tiles.can_flip_tiles(row, col, COLOR_BLACK) assert len(coordinates) == 1
def __init__(self, WIDTH, HEIGHT, SPOT): """Create board for othello game""" self.WIDTH = WIDTH self.HEIGHT = HEIGHT self.SPACING = 100 self.SPOT = SPOT self.tiles = Tiles(self.SPOT) self.STROKE = 3 self.legal = [] self.black = 0 self.white = 255 self.dir = [[0, -1], [0, 1], [-1, 0], [1, 0], [-1, -1], [1, 1], [-1, 1], [1, -1]]
def winning_tiles(tiles): if isinstance(tiles, str): tiles = tiles.replace(' ', '') test_tiles = OneOfEach() return [ tile for tile in test_tiles.tiles if shanten_calculator(tiles + str(tile)) == -1 ] elif issubclass(type(tiles), Tiles): return winning_tiles(str(tiles)) elif isinstance(tiles, list): temp = Tiles() temp.add_tiles(tiles) return winning_tiles(str(temp))
def test_user_move(self): gc = GameController(800) tiles = Tiles(100, 8, 255, 0) b = Board(800, 100, 8, gc, tiles, 255, 0) self.assertEqual(b.tiles.tiles[2][3].color, -1) b.user_move(250, 320) self.assertEqual(b.tiles.tiles[2][3].color, 0)
def test_change_color(self): gc = GameController(600) tiles = Tiles(100, 8, 255, 0) b = Board(600, 100, 8, gc, tiles, 255, 0) self.assertEqual(b.COLOR, 0) b.change_color() self.assertEqual(b.COLOR, 255)
def test_constructor(): tiles = Tiles(800, 100) assert tiles.SPACE == 100 assert tiles.LENGTH == 800 for i in range(tiles.LENGTH//tiles.SPACE): for j in range(tiles.LENGTH//tiles.SPACE): assert tiles.tiles_list[i][j] is None
def context_items(data): cm_items = [] from tiles import Tiles for i in data: if i.get('Videos', []): cm_items.append(Tiles(i).item) return cm_items
def test_constructor(): cb = ChessBoard(WIDTH, HEIGHT, ROW_NUM) tiles = Tiles(cb) gm = GameManager(cb, tiles) assert gm.black_turn == True assert gm.WIDTH == 800 assert gm.HEIGHT == 800 for y in range(ROW_NUM): for x in range(ROW_NUM): if y == 3 and x == 3: assert gm.tile_list[y][x].color == 'white' elif y == 4 and x == 4: assert gm.tile_list[y][x].color == 'white' elif y == 4 and x == 3: assert gm.tile_list[y][x].color == 'black' elif y == 3 and x == 4: assert gm.tile_list[y][x].color == 'black' else: assert gm.tile_list[y][x] == None assert gm.black_count == 2 assert gm.white_count == 2 assert gm.X_ADD == [0, 1, -1, 0, 1, -1, 1, -1] assert gm.Y_ADD == [1, 0, 0, -1, 1, -1, -1, 1] assert gm.has_input_name == False assert gm.TIME_DURATION == 1500 assert gm.FILE_NAME == 'scores.txt'
def test_islegal(): t = Tiles(800, 100, 90) gm = GameManager(t) assert gm.islegal(gm.tiles.player_tiles, gm.tiles.computer_tiles, 0, 0) == [] assert gm.islegal(gm.tiles.player_tiles, gm.tiles.computer_tiles, 3, 2) == [(3, 3)]
def test_flipping(): tiles = Tiles(6, 6, 80) # "col" tiles.flipping(2, 3, "col", tiles.BLACK, 2) assert tiles.tiles_list[2][2].color == tiles.BLACK # "row" tiles.flipping(3, 4, "row", tiles.BLACK, 3) assert tiles.tiles_list[3][3].color == tiles.BLACK # "leftdiag" tiles.flipping(1, 3, "leftdiag", tiles.WHITE, 1, 1) assert tiles.tiles_list[2][2].color == tiles.WHITE assert tiles.tiles_list[3][3].color == tiles.WHITE # "rightdiag" tiles.flipping(1, 3, "rightdiag", tiles.WHITE, 1, 4) assert tiles.tiles_list[2][3].color == tiles.WHITE assert tiles.tiles_list[3][2].color == tiles.WHITE
def test_decide_next_step(): cb = ChessBoard(WIDTH, HEIGHT, ROW_NUM) tiles = Tiles(cb) gm = GameManager(cb, tiles) y, x = gm.decide_next_step() assert y == 2 and x == 4
def test_position_left(): """Test the position_left method of the Board class.""" tiles = Tiles(600, 100) board = Board(600, 100, tiles) assert board.position_left() == (board.length // board.space)**2 - 4 board.add_tile(0, 0, 'black') assert board.position_left() == (board.length // board.space)**2 - 5
def test_constructor(self): t = Tiles(100, 8, 255, 0) self.assertEqual(t.space, 100) self.assertEqual(t.num, 8) self.assertEqual(t.WHITE, 255) self.assertEqual(t.BLACK, 0) t_list = [] for row in range(t.num): for col in range(t.num): if col == 0: t_list.append([]) t_list[row].append(Tile(t.space, row, col, -1)) t_list[t.num // 2 - 1][t.num // 2 - 1].set_color(t.WHITE) t_list[t.num // 2 - 1][t.num // 2].set_color(t.BLACK) t_list[t.num // 2][t.num // 2 - 1].set_color(t.BLACK) t_list[t.num // 2][t.num // 2].set_color(t.WHITE) self.assertEqual(t.tiles[t.num // 2 - 1][t.num // 2 - 1].color, t_list[t.num // 2 - 1][t.num // 2 - 1].color) self.assertEqual(t.tiles[t.num // 2 - 1][t.num // 2].color, t_list[t.num // 2 - 1][t.num // 2].color) self.assertEqual(t.tiles[t.num // 2][t.num // 2 - 1].color, t_list[t.num // 2][t.num // 2 - 1].color) self.assertEqual(t.tiles[t.num // 2][t.num // 2].color, t_list[t.num // 2][t.num // 2].color)
def test_legal_move(): """Test the legal_move method of the Board class.""" tiles = Tiles(800, 100) board = Board(800, 100, tiles) for pair in board.on_board: assert board.legal_move(pair[0], pair[1], 'white') is False assert board.legal_move(pair[0], pair[1], 'blacj') is False
def test_sum_of_white(): """Test the sum_of_white method of the Board class.""" tiles = Tiles(600, 100) board = Board(600, 100, tiles) assert board.sum_of_white() == 2 board.add_tile(0, 0, 'white') assert board.sum_of_white() == 3
def test_flip_diagonal(): """Test the flip_diagonal method of the Board class.""" tiles = Tiles(800, 100) board = Board(800, 100, tiles) assert len(board.flip_diagonal(0, 0, 'white')) == 0 assert len(board.flip_diagonal(0, 0, 'black')) == 0 i, j = board.count // 2 + 1, board.count // 2 - 2 board.add_tile(i, j, 'white') i, j = board.count // 2 + 2, board.count // 2 - 3 assert len(board.flip_diagonal(i, j, 'white')) == 0 assert len(board.flip_diagonal(i, j, 'black')) == 1 i, j = board.count // 2 - 2, board.count // 2 + 1 board.add_tile(i, j, 'white') i, j = board.count // 2 - 3, board.count // 2 + 2 assert len(board.flip_diagonal(i, j, 'white')) == 0 assert len(board.flip_diagonal(i, j, 'black')) == 1 i, j = board.count // 2 - 2, board.count // 2 - 2 board.add_tile(i, j, 'black') i, j = board.count // 2 - 3, board.count // 2 - 3 assert len(board.flip_diagonal(i, j, 'white')) == 1 assert len(board.flip_diagonal(i, j, 'black')) == 0 i, j = board.count // 2 + 1, board.count // 2 + 1 board.add_tile(i, j, 'black') i, j = board.count // 2 + 2, board.count // 2 + 2 assert len(board.flip_diagonal(i, j, 'white')) == 1 assert len(board.flip_diagonal(i, j, 'black')) == 0
def __init__(self): #initialise game board tiles and array sizes self.tiles = Tiles() self.gridsize = 2*self.tiles.gridsize self.boardsize = 1 + 2*self.gridsize #create robots map too self.robot_colours=["yellow","red","green","blue","silver"] #self.robot_colours=["yellow"] self.robots={colour:None for colour in self.robot_colours}
def __init__(self, window, width=10, height=16, xinit=2, yinit=2, tile_width=15): self.tiles = Tiles(tile_width, window) self.window = window self.height = height self.xinit = xinit self.yinit = yinit self.width = width self.total_lines = 0 self.board = [[0 for j in range(width)] for i in range(height)] self.shape = None self._draw() self.clear()
def draw(self, renderContext): extent = renderContext.extent() if extent.isEmpty() or extent.width() == float("inf"): qDebug("Drawing is skipped because map extent is empty or inf.") return True map2pixel = renderContext.mapToPixel() mupp = map2pixel.mapUnitsPerPixel() rotation = map2pixel.mapRotation() painter = renderContext.painter() viewport = painter.viewport() isWebMercator = True transform = renderContext.coordinateTransform() if transform: isWebMercator = transform.destCRS().postgisSrid() == 3857 # frame layer isn't drawn if the CRS is not web mercator or map is rotated if self.layerDef.serviceUrl[0] == ":" and "frame" in self.layerDef.serviceUrl: # or "number" in self.layerDef.serviceUrl: msg = "" if not isWebMercator: msg = self.tr("Frame layer is not drawn if the CRS is not EPSG:3857") elif rotation: msg = self.tr("Frame layer is not drawn if map is rotated") if msg: self.showMessageBar(msg, QgsMessageBar.INFO, 2) return True if not isWebMercator: # get extent in project CRS cx, cy = 0.5 * viewport.width(), 0.5 * viewport.height() center = map2pixel.toMapCoordinatesF(cx, cy) mapExtent = RotatedRect(center, mupp * viewport.width(), mupp * viewport.height(), rotation) if transform: transform = QgsCoordinateTransform(transform.destCRS(), transform.sourceCrs()) geometry = QgsGeometry.fromPolyline([map2pixel.toMapCoordinatesF(cx - 0.5, cy), map2pixel.toMapCoordinatesF(cx + 0.5, cy)]) geometry.transform(transform) mupp = geometry.length() # get bounding box of the extent in EPSG:3857 geometry = mapExtent.geometry() geometry.transform(transform) extent = geometry.boundingBox() else: qDebug("Drawing is skipped because CRS transformation is not ready.") return True elif rotation: # get bounding box of the extent mapExtent = RotatedRect(extent.center(), mupp * viewport.width(), mupp * viewport.height(), rotation) extent = mapExtent.boundingBox() # calculate zoom level tile_mpp1 = self.layerDef.TSIZE1 / self.layerDef.TILE_SIZE zoom = int(math.ceil(math.log(tile_mpp1 / mupp, 2) + 1)) zoom = max(0, min(zoom, self.layerDef.zmax)) #zoom = max(self.layerDef.zmin, zoom) # zoom limit if zoom < self.layerDef.zmin: if self.plugin.navigationMessagesEnabled: msg = self.tr("Current zoom level ({0}) is smaller than zmin ({1}): {2}").format(zoom, self.layerDef.zmin, self.layerDef.title) self.showMessageBar(msg, QgsMessageBar.INFO, 2) return True while True: # calculate tile range (yOrigin is top) size = self.layerDef.TSIZE1 / 2 ** (zoom - 1) matrixSize = 2 ** zoom ulx = max(0, int((extent.xMinimum() + self.layerDef.TSIZE1) / size)) uly = max(0, int((self.layerDef.TSIZE1 - extent.yMaximum()) / size)) lrx = min(int((extent.xMaximum() + self.layerDef.TSIZE1) / size), matrixSize - 1) lry = min(int((self.layerDef.TSIZE1 - extent.yMinimum()) / size), matrixSize - 1) # bounding box limit if self.layerDef.bbox: trange = self.layerDef.bboxDegreesToTileRange(zoom, self.layerDef.bbox) ulx = max(ulx, trange.xmin) uly = max(uly, trange.ymin) lrx = min(lrx, trange.xmax) lry = min(lry, trange.ymax) if lrx < ulx or lry < uly: # tile range is out of the bounding box return True # tile count limit tileCount = (lrx - ulx + 1) * (lry - uly + 1) if tileCount > self.MAX_TILE_COUNT: # as tile count is over the limit, decrease zoom level zoom -= 1 # if the zoom level is less than the minimum, do not draw if zoom < self.layerDef.zmin: msg = self.tr("Tile count is over limit ({0}, max={1})").format(tileCount, self.MAX_TILE_COUNT) self.showMessageBar(msg, QgsMessageBar.WARNING, 4) return True continue # zoom level has been determined break self.logT("TileLayer.draw: {0} {1} {2} {3} {4}".format(zoom, ulx, uly, lrx, lry)) # save painter state painter.save() # set pen and font painter.setPen(Qt.black) font = QFont(painter.font()) font.setPointSize(10) painter.setFont(font) if self.layerDef.serviceUrl[0] == ":": painter.setBrush(QBrush(Qt.NoBrush)) self.drawDebugInfo(renderContext, zoom, ulx, uly, lrx, lry) else: # create a Tiles object and a list of urls to fetch tile image data tiles = Tiles(zoom, ulx, uly, lrx, lry, self.layerDef) urls = [] cachedTiles = self.tiles cacheHits = 0 for ty in range(uly, lry + 1): for tx in range(ulx, lrx + 1): data = None url = self.layerDef.tileUrl(zoom, tx, ty) if cachedTiles and zoom == cachedTiles.zoom and url in cachedTiles.tiles: data = cachedTiles.tiles[url].data tiles.addTile(url, Tile(zoom, tx, ty, data)) if data is None: urls.append(url) elif data: # memory cache exists cacheHits += 1 # else: # tile not found self.tiles = tiles if len(urls) > 0: # fetch tile data files = self.fetchFiles(urls, renderContext) for url, data in files.items(): tiles.setImageData(url, data) if self.iface: stats = self.downloader.stats() allCacheHits = cacheHits + stats["cacheHits"] msg = self.tr("{0} files downloaded. {1} caches hit.").format(stats["downloaded"], allCacheHits) barmsg = None if self.downloader.errorStatus != Downloader.NO_ERROR: if self.downloader.errorStatus == Downloader.TIMEOUT_ERROR: barmsg = self.tr("Download Timeout - {0}").format(self.name()) elif stats["errors"] > 0: msg += self.tr(" {0} files failed.").format(stats["errors"]) if stats["successed"] + allCacheHits == 0: barmsg = self.tr("Failed to download all {0} files. - {1}").format(stats["errors"], self.name()) self.showStatusMessage(msg, 5000) if barmsg: self.showMessageBar(barmsg, QgsMessageBar.WARNING, 4) # apply layer style oldOpacity = painter.opacity() painter.setOpacity(0.01 * (100 - self.transparency)) oldSmoothRenderHint = painter.testRenderHint(QPainter.SmoothPixmapTransform) if self.smoothRender: painter.setRenderHint(QPainter.SmoothPixmapTransform) # do not start drawing tiles if rendering has been stopped if renderContext.renderingStopped(): self.log("draw(): renderingStopped!") painter.restore() return True # draw tiles if isWebMercator and rotation == 0: self.drawTiles(renderContext, tiles) # self.drawTilesDirectly(renderContext, tiles) else: # reproject tiles self.drawTilesOnTheFly(renderContext, mapExtent, tiles) # restore old state painter.setOpacity(oldOpacity) if self.smoothRender: painter.setRenderHint(QPainter.SmoothPixmapTransform, oldSmoothRenderHint) # draw credit on the bottom right corner if self.creditVisibility and self.layerDef.attribution: margin, paddingH, paddingV = (3, 4, 3) # scale scaleX, scaleY = self.getScaleToVisibleExtent(renderContext) scale = max(scaleX, scaleY) painter.scale(scale, scale) visibleSWidth = painter.viewport().width() * scaleX / scale visibleSHeight = painter.viewport().height() * scaleY / scale rect = QRect(0, 0, visibleSWidth - margin, visibleSHeight - margin) textRect = painter.boundingRect(rect, Qt.AlignBottom | Qt.AlignRight, self.layerDef.attribution) bgRect = QRect(textRect.left() - paddingH, textRect.top() - paddingV, textRect.width() + 2 * paddingH, textRect.height() + 2 * paddingV) painter.fillRect(bgRect, QColor(240, 240, 240, 150)) painter.drawText(rect, Qt.AlignBottom | Qt.AlignRight, self.layerDef.attribution) # restore painter state painter.restore() return True
class Board(object): #boardstate is an integer array representing the game board state, where: #0=floor/space #1=wall #2=centre tiles #3=robot #-1=flag, negative since positive values block robot movement def __init__(self): #initialise game board tiles and array sizes self.tiles = Tiles() self.gridsize = 2*self.tiles.gridsize self.boardsize = 1 + 2*self.gridsize #create robots map too self.robot_colours=["yellow","red","green","blue","silver"] #self.robot_colours=["yellow"] self.robots={colour:None for colour in self.robot_colours} def initialise(self): #generate random configuration of board tiles self.boardstate, self.flaglocs = self.tiles.generate_game_board() #initialize target #pick a random target from 17 possibles self.flag_order = np.random.permutation(len(self.flaglocs)) self.turn = 0 self.flagloc=self.flaglocs[self.flag_order[self.turn]]["location"] self.boardstate[getIJBoard(*self.flagloc)]=-1 self.flag_colour=self.flaglocs[self.flag_order[self.turn]]["colour"] #randomise robot start position(s) for colour in self.robot_colours: self.robots[colour]=Robot(colour,self) if self.flag_colour=="rainbow": self.active_robot="silver" else: self.active_robot=self.flag_colour self.victory=False self.moves_taken=0 self.last_pressed=None #display configuration for i in range(self.boardsize): print self.boardstate[i] def undo_move(self): #erase current location self.boardstate[getIJBoard(*tuple(self.robots[self.active_robot].position))]=0 #reset to last position self.robots[self.active_robot].position=self.robots[self.active_robot].last_position self.boardstate[getIJBoard(*tuple(self.robots[self.active_robot].position))]=3 #reset flag #check whether a robot is here first if self.boardstate[getIJBoard(*self.flagloc)]==0: self.boardstate[getIJBoard(*self.flagloc)]=-1 self.victory=False self.moves_taken = max(self.moves_taken - 1, 0) def reset_flag(self): for colour in self.robot_colours: #erase current location self.boardstate[getIJBoard(*tuple(self.robots[colour].position))]=0 #reset to turn start self.robots[colour].position=self.robots[colour].turn_start_position self.robots[colour].last_position=self.robots[colour].turn_start_position self.boardstate[getIJBoard(*tuple(self.robots[colour].position))]=3 #reset flag #check whether a robot is here first if self.boardstate[getIJBoard(*self.flagloc)]==0: self.boardstate[getIJBoard(*self.flagloc)]=-1 self.victory=False self.moves_taken=0 def new_flag(self): self.turn+=1 if self.turn<17: #choose new flag location and colour, leave robots in place self.flagloc=self.flaglocs[self.flag_order[self.turn]]["location"] self.flag_colour=self.flaglocs[self.flag_order[self.turn]]["colour"] #update robot turn start info for colour in self.robot_colours: #reset turn start position self.robots[colour].turn_start_position=self.robots[colour].position self.robots[colour].last_position=self.robots[colour].turn_start_position #reset flag #check whether a robot is here first TODO if self.boardstate[getIJBoard(*self.flagloc)]==0: self.boardstate[getIJBoard(*self.flagloc)]=-1 self.victory=False self.moves_taken=0 else: #all flag positions solved for this game - user must (r)eset or start a (n)ew game return def new_game(self): #choose new board configurations and initialise again self.initialise() #move_active_robot def process_keypress(self,key): #check for victory state - only allows reset options if self.victory: if key not in (pygame.K_r,pygame.K_n,pygame.K_f,pygame.K_u,pygame.K_s): print "In victory state, please reset turn or start a new game" return #check for undo (pressed u) if key==pygame.K_u and (self.last_pressed in (pygame.K_LEFT,pygame.K_RIGHT,pygame.K_UP,pygame.K_DOWN)): self.undo_move() #check for reset (pressed r) elif key==pygame.K_r: self.reset_flag() #check for new turn (pressed f) elif key==pygame.K_f: self.new_flag() #check for new game (pressed n) elif key==pygame.K_n: self.new_game() #check for show flag (pressed s) elif key==pygame.K_s: #do not reset last pressed return #check for movement elif key in (pygame.K_LEFT,pygame.K_RIGHT,pygame.K_UP,pygame.K_DOWN): self.robots[self.active_robot].move(self,key) #check for switch active robot elif key in (pygame.K_1,pygame.K_2,pygame.K_3,pygame.K_4,pygame.K_5,pygame.K_KP1,pygame.K_KP2,pygame.K_KP3,pygame.K_KP4,pygame.K_KP5): self.active_robot=self.robot_colours[int(pygame.key.name(key))-1] else: #no action for this key print "Input not recognised" #save input for reference self.last_pressed = key return def check_victory(self): #need to reach the flag with the same coloured robot if (tuple(self.robots[self.active_robot].position)==self.flagloc) and ((self.flag_colour==self.active_robot) or (self.flag_colour=="rainbow")): self.victory=True return True else: self.victory=False return False
class Board: def __init__(self, window, width=10, height=16, xinit=2, yinit=2, tile_width=15): self.tiles = Tiles(tile_width, window) self.window = window self.height = height self.xinit = xinit self.yinit = yinit self.width = width self.total_lines = 0 self.board = [[0 for j in range(width)] for i in range(height)] self.shape = None self._draw() self.clear() def add_shape(self): assert not self.shape sh, col = random.choice(shape_color) self.shape = Shape(sh, self.window, col, self.width/2, 0, self.xinit, self.yinit) if self.collides(self.shape): raise GameOver() self.shape.draw() def eat_shape(self): self.shape.erase() for x,y in self.shape.shape: self.board[y+self.shape.y][x+self.shape.x] = 1 self.shape = None def frame(self, pressed_keys): if not self.shape: return shapex = self.shape.x shapey = self.shape.y shape_shape = deepcopy(self.shape.shape) self.shape.update_pos(pressed_keys) if self.collides(self.shape): self.shape.x = shapex self.shape.y = shapey self.shape.shape = shape_shape else: self.shape.draw() def collides(self, shape): for x,y in shape.shape: x += shape.x y += shape.y if x < 0 or x >= self.width: return True if y >= self.height or y < 0: return True if self.board[y][x] == 1: return True return False def collides_bottom(self, shape): for x,y in shape.shape: x += shape.x y += shape.y if y+1 >= self.height: return True if self.board[y+1][x]: return True return False def tick(self): self._erase() if not self.shape: self.add_shape() elif not self.collides_bottom(self.shape): self.shape.erase() self.shape.move_down() self.shape.draw() elif self.collides_bottom(self.shape): self.eat_shape() self.check_lines() self._draw() def check_lines(self): for i in range(self.height): if self.check_line(self.board[i]): self.board.pop(i) self.total_lines += 1 print self.total_lines self.board = [[0 for i in range(self.width)]] + self.board def check_line(self, line): for i in line: if not i: return False return True def _draw(self, draw_f=Tiles.square): for y in range(self.height): for x in range(self.width): if self.board[y][x]: draw_f(self.tiles, x+self.xinit, y+self.yinit) def _erase(self): self._draw(draw_f=Tiles.erase) def clear(self): for y in range(self.height): for x in range(self.width): self.tiles.erase(x+self.xinit, y+self.yinit)