Re: Create a game map?
Hi,
Probably an unpopular suggestion, but worth chucking out there:
I know there's lots of boilerplate code in here, but I've taken the _Base class from my pyrts project.
With the below code you can instantiate maps and tiles with relative ease. Of course there's no provision for storing objects, but that's only a matter of extending what I've written.
I use this kind of setup a lot. If you want to see more sql in action, look at the pyrts source code, or check the running instance.
from enum import Enum as PythonEnum
from inspect import isclass
from sqlalchemy import (
create_engine, Column, Integer, ForeignKey, Enum, inspect
)
from sqlalchemy.exc import DatabaseError
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('sqlite:///:memory:') Session = sessionmaker(bind=engine) session = Session() class TileTypes(PythonEnum): """The possible types for tiles.""" sand = 0 grass = 1 water = 2 wall = 3 lava = 4 class _Base: """Create a primary key and some useful methods.""" id = Column(Integer, primary_key=True) def save(self): """Save this object.""" session.add(self) try: session.commit() except DatabaseError: session.rollback() raise def delete(self): session.delete(self) try: session.commit() except DatabaseError: session.rollback() raise @classmethod def query(cls, *args, **kwargs): """Return a query object with this class.""" return session.query(cls).filter(*args).filter_by(**kwargs) @classmethod def count(cls, *args, **kwargs): """Return the number of instances of this class in the database.""" return cls.query(*args, **kwargs).count() @classmethod def first(cls, *args, **kwargs): """Return the first instance of this class in the database.""" return cls.query(*args, **kwargs).first() @classmethod def get(cls, id): """Get an object with the given id.""" return cls.query().get(id) @classmethod def one(cls, *args, **kwargs): return cls.query(*args, **kwargs).one() @classmethod def all(cls, *args, **kwargs): """Return all child objects.""" return cls.query(*args, **kwargs).all() @classmethod def classes(cls): """Return all table classes.""" for item in cls._decl_class_registry.values(): if isclass(item) and issubclass(item, cls): yield item @classmethod def number_of_objects(cls): """Returns the number of objects in the database.""" count = 0 for base in cls.classes(): count += base.count() return count def __repr__(self): name = type(self).__name__ string = '%s (' % name attributes = [] i = inspect(type(self)) for column in i.c: name = column.name attributes.append('%s=%r' % (name, getattr(self, name))) string += ', '.join(attributes) return string + ')' @classmethod def get_class_from_table(cls, table): """Return the class whose __table__ attribute is the provided Table instance.""" for value in cls._decl_class_registry.values(): if getattr(value, '__table__', None) is table: return value Base = declarative_base(bind=engine, cls=_Base) class Tile(Base): """A tile on the map.""" __tablename__ = 'tiles' x = Column(Integer, nullable=False) y = Column(Integer, nullable=False) type = Column(Enum(TileTypes), nullable=False) map_id = Column(Integer, ForeignKey('maps.id'), nullable=False) map = relationship( 'Map', backref='tiles', single_parent=True, cascade='all, delete-orphan' ) class Map(Base): """A map which can contain lots of tiles.""" __tablename__ = 'maps' size_x = Column(Integer, nullable=False, default=100) size_y = Column(Integer, nullable=False, default=100) default_type = Column( Enum(TileTypes), nullable=False, default=TileTypes.sand ) @property def size(self): return self.size_x, self.size_y @size.setter def size(self, value): self.size_x, self.size_y = value def tile_at(self, x, y): """Return the type of tile at the given coordinates.""" tile = Tile.first(map=self, x=x, y=y) if tile is None: return self.default_type return tile.type def add_tile(self, x, y, type): """Create and return a tile of the given type at the given coordinates.""" return Tile(map=self, x=x, y=y, type=type) if __name__ == '__main__': Base.metadata.create_all() m = Map() m.save() m.add_tile(1, 1, TileTypes.wall).save() assert m.tile_at(0, 0) is TileTypes.sand assert m.tile_at(1, 1) is TileTypes.wall
-- Audiogames-reflector mailing list Audiogames-reflector@sabahattin-gucukoglu.com https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector