game/data.py

125 lines
3.3 KiB
Python

# -*- coding: utf-8 -*-
#
# Copyright © 2024 Simon Forman
#
# This file is part of game
#
# game is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# game is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with game. If not see <http://www.gnu.org/licenses/>.
#
from random import randint, expovariate, seed
import sqlite3
from poisson import poisson
import population, stars
FILENAME = './game.sqlite'
conn = None
TABLES = [
'''\
create table stars (
id INTEGER PRIMARY KEY AUTOINCREMENT,
x INTEGER,
y INTEGER,
radius INTEGER,
name TEXT UNIQUE
)''',
(
'''\
create table planets (
id INTEGER PRIMARY KEY,
ordo INTEGER,''' # The order from the star, counting from 1.
# I use "ordo" instead of "order" because "order" is a keyword
# in SQL (or at least it caused a syntax error in SQLite.)
# These capacities are fixed and reflect the conditions on the
# planet in a very abstract way. Bio and Industry should be
# low/high near and far from the star and high/low in the mid-
# range, but for now I'm just going to use random numbers.
'''bio_capacity INTEGER,
bio INTEGER DEFAULT 0,
industrial_capacity INTEGER,
industry INTEGER DEFAULT 0,
star INTEGER,
FOREIGN KEY(star) REFERENCES stars(id)
)'''
),
'''\
create table populations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
species TEXT,
home_star INTEGER,
pop INTEGER,
planet INTEGER,
vessel INTEGER,
station INTEGER,
FOREIGN KEY(home_star) REFERENCES stars(id),
FOREIGN KEY(planet) REFERENCES planets(id)
check (
( case when planet is null then 0 else 1 end
+ case when vessel is null then 0 else 1 end
+ case when station is null then 0 else 1 end
) = 1
)
)
''',
]
# Apparently this clause should constrain a pop to be
# in only one location at a time.
def initialize_db_tables(filename):
conn = open_db(filename)
c = conn.cursor()
for statement in TABLES:
c.execute(statement)
c.close()
conn.commit()
return conn
def close_db():
global conn
if conn:
conn.close()
conn = None
else:
raise RuntimeError('db connection already closed')
def open_db(filename=FILENAME):
global conn
if conn is not None:
raise RuntimeError('db connection already open')
conn = sqlite3.connect(filename)
return conn
def main(filename):
conn = initialize_db_tables(filename)
stars.init_db(conn)
population.init_db(conn)
if __name__ == '__main__':
import pathlib
if not pathlib.Path(FILENAME).exists():
print('Initializing db file', FILENAME)
main(FILENAME)
else:
print(FILENAME, 'already exists! Not overwriting.')