#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Mar  8 11:30:41 2021

@author: Heikki Välisuo
"""

import random
import paramsPandemia as pars
from Tilasto import tilasto
from Kartta import kartta
import Fantasmi


Pöpö fantasiamaailmassa

Fantasiamaailmaan — yhteen monista vaihtoehtoisista todellisuuksista — livahtaa ilkeä pöpö, jonka aikaansaannoksia seuraamme. Onneksi tämä fantasiamaailma on tietokoneeni muistissa ja siksi pöpökin on tosielämän elioille vaaraton.


Fantasmi on jossain seuraavista tiloista:


vaesto = [Fantasmi.Fantasmi() for i in range(pars.alku_vaesto)]


Pääohjelma, joka pitää fantasiamaailman oliot — fantasmit — liikkeessä


def simulate():

Pandemian etenemisessä on paljon satunnaisuutta. random.seed() antaa joka simulaatioon erilaiset satunnaisluvut — ei tule kahta samanlaista simulaatiota.

    random.seed()


Tämän tunkeilijan mukana lintukotoon pääsee hypähtämään pöpö.


    tunkeilija()

    # Yksi while-silmukan kierros vastaa yhtä fantasiamaailman päivää
    # Simuloidaan kunnes ei tapahdu mitään uuttaa jännää
    while not (kartta.loppu or Fantasmi.ohjaus.loppu):

        # Tarkistetaan, tuleeko uusia tartuntoja
        # poimitaan väestöstä tartunnalle alttiit fantasmit ...
        alttiit = [fantasmi for fantasmi in vaesto
                   if fantasmi.tila in ['altis', 'rokotettu']]

        # ... ja potentiaaliset tartuttajat
        tartuttajat = [fantasmi for fantasmi in vaesto if
                       fantasmi.tila in ['oireeton', 'sairas']]

        # Ovatko jotkut yllälöydetyistä vaarallisessa lähikontaktissa?
        altistukset(tartuttajat, alttiit)

        # Tarkistetaan fantasmi fantasmilta tapahtuuko kenenkään
        # terveydentilassa muutoksia
        for fantasmi in vaesto:
            fantasmi.taudin_kulku()
            # ja siirretään fantasmia eteenpäin
            fantasmi.liike()

        # Päivitetään fantasmien sijainti komentokeskuksen näytöllä
        kartta.sijainnit(vaesto)
        # Päivitetään fantasiamaailman terveystilastot
        tilasto.aika_kuluu(vaesto)

        # Jos komentokeskus on käynnistänyt rokotuskampanjan,
        # rokotetaan sen verran kuin kyetään.
        if Fantasmi.ohjaus.rokota:
            rokotukset(vaesto)

        # Tarkistetaan komentokeskuksen strategiasta,
        # mitä tehdä huomenna
        Fantasmi.ohjaus.uusi_vaihe()
        # <<<< Uusi päivä. while-silmukaan alkuun.

    # Simulointi on päättynyt.
    # Kunnioitetaan hetki pandemian uhreja.
    kartta.hautausmaa(vaesto)

    print('päivä: ', tilasto.paiva)
    kartta.lopeta()



Tarkistetaan, saako joku alttiista tartunnan joltakin sairaista


def altistukset(tartuttajat, alttiit):
    for tartuttaja in tartuttajat:
        for altis in alttiit:
            tartunta(tartuttaja, altis)


altis sairastuu, jos on joutunut liian lähelle viruksen kantajaa — tartuttajaa.

altis on tästä eteenpäin tilassa 'oireeton' kesto päivää. Rokotettu parantuu puolessa ajassa.


def tartunta(tartuttaja, altis):
    if lahella(tartuttaja, altis):
        altis.tila = 'oireeton'
        altis.uusiTartunta = 3
        (t0, t1) = pars.kestot['oireeton']
        kesto = random.uniform(t0, t1)
        if altis.tila == 'rokotettu':
            kesto = kesto/2.0
        altis.ohi = tilasto.paiva + kesto
        tilasto.N_tartunnat += 1


Tarkistetaan, ovatko tartuttaja ja altis tartuntaetäisyydellä. Sovelletaan Pythagoraan lausetta


def lahella(tartuttaja, altis):
    suoja_etaisyys_2 = pars.suoja_etaisyys
    if altis.tila == 'rokotettu':
        suoja_etaisyys_2 = pars.suoja_etaisyys_vac
    # else:
    #     print('mitä hittoa ', tartuttaja.tila, altis.tila)
    (ax, ay) = tartuttaja.paikka
    (bx, by) = altis.paikka
    return (ax-bx)**2 + (ay-by)**2 < suoja_etaisyys_2


Päivässä rokotetaan pars.rokotustahti verran fantasmeja.

Itsellenikin yllätykseksi ensin rokotetaan fantasmi-kansa A, sitten B, C ja viimeiseksi D. Selitys:

Rokotukset oli helpoin ohjelmoida alkaen fantasmien listan alusta. Kartalle piirtämistä varten fantasmien lista taas kannattaa laittaa kansojen mukaiseen järjestykseen.


def rokotukset(vaesto):
    i = 0
    for fantasmi in [x for x in vaesto if x.tila in ('altis', 'immuuni')]:
        fantasmi.tila = 'rokotettu'
        tilasto.N_rokotetut += 1
        i += 1
        if i > pars.rokotustahti:
            break


Tällainen on se alussa mainittu väestön sekaan pujahtava tunkeilija. Tunkeilijan tauti on oireettomassa itämisvaiheessa. Oireeton siirtyy tilaan 'sairas', kun on kulunut satunnainen aika väliltä (t0, t1)


def tunkeilija():
    # Luodaan yksi fantasmi
    tautinen = Fantasmi.Fantasmi()
    tautinen.koti = 'A'
    # Haluan pandemian alkavan kansan 'A' joukosta
    # Tämän voi kommentoida, jos haluaa satunnaisen alkukohdan
    tautinen.paikka = (0.3*pars.x_max, 0.7*pars.y_max)
    # Itämisvaiheessa 'lintukotoon tullessa
    tautinen.tila = 'oireeton'
    (t0, t1) = pars.kestot['oireeton']
    # Oireet tulevat esiin satunnaisen ajan kuluttua
    tautinen.ohi = tilasto.paiva + random.uniform(t0, t1)
    # Lisätään väestön sekaan
    vaesto.append(tautinen)
    # Tilastoluvut kasvavat yhdellä
    tilasto.N_alku += 1
    tilasto.N_vaesto += 1

# Tästä se lähtee käyntiin. Pidä hatustasi kiinni
simulate()