TETRIS - Dokumentace ke zdrojovmu kdu
=======================================

Program je napsn v jazyce C. Vlastn vpoetn st (Tetris.c) a interface
(Tetr_win.c) je od sebe oddleno. Tetris.c pouv pouze standardn ANSI C
funkce a exportuje funkce, kter interface vol. Tetr_win.c je interface pro
Windows, psno ve WinAPI. Lze jej zkompilovat v Dev-C++ (ve kterm jsem jej
vyvjel) i ve Visual Studiu. Me bt t zkompilovno v UNICODE, ale pak
nefunguje ve Windows 98.
Vedle interface pro Windows m program i interface pro DOS (Borland C).
Pouij se soubory Tetr_dos.c, Tetris.c a Tetris.h. To ale neobsahuje vechny
funkce, kter m interface pro Windows.

Pedpokldm, e ten je ji seznmen s uivatelskm manulem ke he.


Sousti kdu
-------------

Tetr_dos.c - Interface pro MS_DOS (Borland C), nem vechny funkce jako
             interface pro Windows
Tetr_win.c - Interface pro Windows (Dev-C++ nebo Visual Studio)
Tetr_win.h - Definice konstant pro resources
Tetr_win.rc - Resources pro Windows (dialogov okna, etzce)
Tetris.c - Vlastn "vpoetn" st (mazn ad, vbr kostek apod.), pouv
           jen standardn ANSI C funkce
Tetris.dat - Data o kostkch, nutn i pro zkompilovan program
Tetris.h - Hlaviky funkc z Tetris.c, definice struktur
Tetris.ico - Ikona programu (16x16 a 32x32)
WinTetris.dev - Projekt pro Dev-C++
WinTetris.dsp - Projekt pro Visual Studio 6.0


Popis programu
--------------

Interface nen nijak algoritmicky zajmav, k pochopen funkce zcela posta
komante. Pouze upesnm, e rychlost a zrychlovn hry je zcela v reii
interface, protoe ve verzi pro DOS a pro Windows mus bt udlno pln jinak
(v DOSu sta ekat pomoc funkce delay(), zatmco ve Windows je nutno pout
asova.)

Zajmavj je "jdro" programu, Tetris.c. Popu nkolik funkc, kter
interface pouv. Zmnm jen zkladn principy, detailnj popis je v
komentch k programu.

* find_pos - obsahuje algoritmus pro vbr pozice pro kostku, kter je popsn
  dle. Vrac hodnocen zvolen pozice, pouvan pro vbr kostek, kter se
  hri hod nebo naopak nehod.

* move_brick - funkce se pokus posunout kostku podle zadanho pkazu (kter
  odpovd stisknut klvese). Kontroluje, zda kostku lze posunout a zda ji
  nedopadla (podle toho vrac hodnotu)

* set_brick - poloen kostky. Vol se po move_brick, pokud kostka dopadla.
  Provede mazn ad a zkotroluje, zda kostka nezstala ve vchoz pozici (to by
  znamenalo zaplnn a konec hry)

* read_bricks - nat kostky ze vstupnho souboru (v textovm formtu)

* initialize - inicializace datov struktury hry (vytvo nap. rmeek okolo
  hernho pole)

* set_bricksel_mode - nastav zpsob vbru kostkek (zape jej do globln
  promnn a pedpot hodnoty pro zrychlen vpotu)

* new_brick - vybere novou kostku dle nastavenho mdu. Algoritmus je popsn
  dle.


Algoritmus na hledn pozice pro kostku
---------------------------------------

Zklad algoritmu je jednoduch: prost se projdou vechna otoen kostky a u
kadho vechny souadnice X (horizontln), kam lze kostku poloit. Pak se
spot, do jak vky kostka dopadne (pro zrychlen se prben potaj vky
jednotlivch sloupc v hernm poli).

Kad pozice se pak hodnot podle 4 kritri:

* Vka - kostku je dobr poloit co nejne
* Dry - poet przdnch polek, kter by zbyla pod kostkou je hlavn
  kritrium, protoe tm znemoujeme vymazn ady
* Vymazn ady - pozice je vhodnj, pokud se po poloen kostky vymae jedna
  ada nebo jet lpe nkolik ad
* "Sloupy" - Naposled pidvan kritrium, protoe algoritmus ml tendenci
  vytvet vysok "sloupy" a mezi nimi "jmy", do kterch bylo mon poloit
  jenom dlouhou kostku (####), kter pli asto nechod. Pot se rozdl
  vek dvou sloupc, je-li vy ne dva (a pak se od nj 2 odete). Hodnota
  ped dopadem kostky se odet, hodnota po dopadu pit.

Vsledn hodnocen pozice je souet kritri po vynsoben koeficienty. m
vy hodnota, tm je hodnocen lep. Koeficient u "sloup" a dr je tedy
zporn a u vymazanch ad a vky (horn ada m souadnici 0) kladn. Vsledn
hodnota tedy me bt zporn. Koeficient u vky je roven 1. Ostatn
koeficienty jsem uroval prochzenm stavovho prostoru a potnm prmrnho
potu kostek, kter pota doke umstit ne se mu pole zapln. Vpoet trval
asi 12 hodin. Kombinaci koeficient, kdy doshl nejvtho potu kostek, jsem
pak zadal do programu.


Algoritmus na vbr kostek podle hodnocen
------------------------------------------

Pomoc ve uvedenho algoritmu se nalezne pozice pro kadou kostku a ur se
jej hodnocen. Protoe toto hodnocen me bt i zporn, nepracuje se pmo
s hodnocenm, ale s poadm kostky dle hodnocen. Toto poad pak bude urovat
pravdpodobnost vbru kostky. Poad je slovno od 0.
                                        k
Kad kostce se piad interval dlky A , kde 'k' je poad kostky dle
hodnocen a 'A' je voliteln parametr, kter uruje, jak moc poad kostky
ovlivuje pravdpodobnost vbru. V programu je zadvn jako "Intenzita",
kter se pepot na A dle vzorce:

  A = intenzita / 10 + 1

Intervaly se naskldaj na selnou osu za sebe, take konec intervalu kostky K
bude:
         __n-1      n
         \     k   A - 1
  F(k) = /_   A  = -----
         k=0       A - 1

Kde 'n' je poet kostek, v naem ppad 7.

Vbr kostky se pak provede tak, e se ur nhodn slo a stanov se, do
kterho intervalu pat. K tomu je nutno stupnici normalizovat na rozsah
nhodnch sel:
                             k                          k
          X(k)              A - 1   A - 1              A - 1
  F'(k) = ---- * RAND_MAX = ----- * ----- * RAND_MAX = ----- = RAND_MAX
          X(n)              A - 1    n                  n
                                    A - 1              A - 1

Vraz       n
           A - 1
  scale = --------
          RAND_MAX

si meme pedpotat pro zrychlen vpotu.
Vychz tedy funkce:
           k
          A - 1
  F'(k) = -----
          scale

K n meme spotat inverzn funkci::

   -1     log(x * scale + 1)
  F (x) = ------------------
               log(A)

Nyn meme v konstantnm ase urit, do kterho intervalu pat nhodn slo:
sta potat doln celou st vrazu vpravo. Vme tedy, koliktou nejlep
(resp. nejhor) kostku podle poad mme vybrat. loha je tedy jen najt k-t
nejvt (resp. nejmen) slo v poli. Vzhledem k tomu, e pole m jen 7 prvk,
pouil jsem triviln algoritmus (najt nejvt slo, nahradit minimem, znovu
najt nejvt...).

Operace se bohuel mus provdt ve floating-point, do celch sel se mi je
pevst nepodailo.
