import sqlite3
import json
from pathlib import Path
from typing import Optional, Dict, List
class Database:
"""Handles all database operations"""
def __init__(self, db_path: str = "data/game.db"):
self.db_path = db_path
Path("data").mkdir(exist_ok=True)
def _get_connection(self):
"""Get database connection"""
conn = sqlite3.connect(self.db_path)
conn.row_factory = sqlite3.Row
return conn
def init_db(self):
"""Initialize database tables"""
with self._get_connection() as conn:
# Players table
conn.execute('''
CREATE TABLE IF NOT EXISTS players (
player_id TEXT PRIMARY KEY,
nickname TEXT UNIQUE NOT NULL,
money INTEGER NOT NULL,
population INTEGER NOT NULL,
color TEXT NOT NULL,
last_online REAL NOT NULL
)
''')
# Buildings table
conn.execute('''
CREATE TABLE IF NOT EXISTS buildings (
x INTEGER NOT NULL,
y INTEGER NOT NULL,
type TEXT NOT NULL,
owner_id TEXT NOT NULL,
name TEXT,
placed_at REAL NOT NULL,
PRIMARY KEY (x, y),
FOREIGN KEY (owner_id) REFERENCES players (player_id)
)
''')
conn.commit()
def save_game_state(self, game_state):
"""Save complete game state to database"""
with self._get_connection() as conn:
# Save players using INSERT OR REPLACE to handle existing nicknames
for player in game_state.players.values():
conn.execute('''
INSERT OR REPLACE INTO players (player_id, nickname, money, population, color, last_online)
VALUES (?, ?, ?, ?, ?, ?)
''', (
player.player_id,
player.nickname,
player.money,
player.population,
player.color,
player.last_online
))
# Save buildings
conn.execute('DELETE FROM buildings')
for building in game_state.buildings.values():
conn.execute('''
INSERT INTO buildings (x, y, type, owner_id, name, placed_at)
VALUES (?, ?, ?, ?, ?, ?)
''', (
building.x,
building.y,
building.building_type.value,
building.owner_id,
building.name,
building.placed_at
))
conn.commit()
def load_game_state(self) -> dict:
"""Load complete game state from database"""
try:
with self._get_connection() as conn:
# Load players
players = []
cursor = conn.execute('SELECT * FROM players')
for row in cursor:
players.append({
"player_id": row["player_id"],
"nickname": row["nickname"],
"money": row["money"],
"population": row["population"],
"color": row["color"],
"last_online": row["last_online"]
})
# Load buildings
buildings = []
cursor = conn.execute('SELECT * FROM buildings')
for row in cursor:
buildings.append({
"x": row["x"],
"y": row["y"],
"type": row["type"],
"owner_id": row["owner_id"],
"name": row["name"],
"placed_at": row["placed_at"]
})
return {
"players": players,
"buildings": buildings
}
except Exception as e:
print(f"Error loading game state: {e}")
return {"players": [], "buildings": []}