view gamelib/gamestate.py @ 45:1e8f7e694f0c

Refactor missions and sciences a bit to reduce duplication.
author Jeremy Thurgood <firxen@gmail.com>
date Mon, 07 May 2012 20:44:27 +0200
parents 47c7e96cf9c8
children 373c57ab4140
line wrap: on
line source

# -*- coding: utf-8 -*-
# vim:fileencoding=utf-8 ai ts=4 sts=4 et sw=4

"""The actual game state object"""

from gamelib import missions, lab
from gamelib.game_base import get_subclasses


class Game(object):

    def __init__(self, init_data=None):
        self.money = 1000
        # Will be updated on the next turn
        self.points = 0
        self.reputation = 0
        # Missions being attempted
        self.cur_missions = []
        # Science allocation for the current turn
        self.cur_allocation = []
        self.lab = None
        self.missions = []
        if init_data:
            self._load_data(init_data)
        else:
            self.lab = lab.Lab()
            # instantiate all the available missions
            for cls in get_subclasses(missions.Mission):
                self.missions.append(cls())

    def start_turn(self):
        # Make more flexible?
        self.points += 3
        self.cur_missions = []
        self.cur_allocation = []

    def get_available_equipment(self):
        """Return a list of equipment we can produce and afford"""
        available = [x for x in self.lab.science
                     if x.SCIENCE_TYPE == 'product' and x.COST <= self.money]
        return available

    def get_available_missions(self):
        """Return a list of missions we can feasibly attempt"""
        available = [x for x in self.missions if x.can_attempt(self)]
        return available

    def end_turn(self):
        # Attempt the missions
        mission_results = []
        for mission, equipment in self.cur_missions:
            mission_results.append(mission.attempt(equipment, self))
        # Do the science
        self.points -= len(self.cur_allocation)
        if self.points < 0:
            raise RuntimeError('Spent too many points')
        new_stuff = self.lab.spend_points(self.cur_allocation, self.points)
        self.points = 0
        # Process mission results
        for result in mission_results:
            result.apply(self)
        for science in new_stuff:
            # FIXME: Update UI better.
            print "You learned new stuff:", science.NAME

    def save_data(self):
        """Serialize the game state into a dict"""
        data = {}
        data['money'] = self.money
        data['reputation'] = self.reputation
        data['points'] = self.points
        data['lab'] = self.lab.serialize()
        # Save mission state
        data['missions'] = {}
        for mission in self.missions:
            miss_name = type(mission).__name__
            data['missions'][miss_name] = mission.save_data()
        return data

    def _load_data(self, data):
        """Restore the game state"""
        self.money = data['money']
        self.reputation = data['reputation']
        self.points = data['points']
        self.lab = lab.Lab(data['lab'])
        for mis_class in missions.Mission.__subclasses__():
            miss_name = mis_class.__name__
            if miss_name in data['missions']:
                self.missions.append(mis_class(data['missions'][miss_name]))