Místo toho, aby byl všude stejný kousek hada, budeme chtít vybrat vždycky ten správný.
Jak na to? Podle čeho ho vybrat?
Obrázky s kousky hada jsou pojmenovány
odkud-kam.png
.
To není náhoda – ukazuje to, co potřebuješ vědět, abys mohla ten správný
kousek vybrat.
Když máš hada podle následujícího obrázku, na políčko (3, 2) patří
kousek, na kterém had „leze“ zleva nahoru – tedy left-top.png
Na koncích hada je ve jménech obrázků místo směru end
.
Pro každé z políček budeš potřebovat zjistit, odkud a kam na něm had leze – tedy směr k předchozí a následující souřadnici:
Souřadnice | Předchozí | Směr k předchozí | Následující | Směr k následující | |
---|---|---|---|---|---|
(1, 2) | není | end |
(2, 2) | right |
![]() |
(2, 2) | (1, 2) | left |
(3, 2) | right |
![]() |
(3, 2) | (2, 2) | left |
(3, 3) | top |
![]() |
(3, 3) | (3, 2) | bottom |
(3, 4) | top |
![]() |
(3, 4) | (3, 3) | bottom |
(3, 5) | top |
![]() |
(3, 5) | (3, 4) | bottom |
(4, 5) | right |
![]() |
(4, 5) | (3, 5) | left |
není | end |
![]() |
Toto je těžký úkol. I když všechny potřebné informace a nástroje k tomu teď teoreticky znáš, je potřeba je správným způsobem poskládat dohromady. Tohle skládání dohromady, návrh algoritmů, je nejsložitější programátorská disciplína.
Zkus nad tím ale přemýšlet, nech si to rozležet v hlavě třeba přes noc, vrať se k materiálům k předchozím lekcím (hlavně k úvodu do Pythonu), zkoušej a objevuj… A časem na to přijdeš.
Jestli nemáš čas, koukněme se na to, jak se dá zařídit.
Popisuju tady jedno možné řešení. Existuje spousta jiných správných způsobů, jak vybírat políčka hada. Možná ti dokonce jiné řešení přijde jednodušší – a možná to bude dokonce tvoje řešení!
Složité problémy programátoři většinou vhodně rozdělí na více jednodušších problémů. Každý pak vyřeší zvlášť a pak spojí dohromady.
Jaké jednodušší úkoly by se daly najít tady?
Řešením prvního z nich v tabulce výše „vyplníš“ sloupečky se souřadnicemi. Řešením druhého pak z těchto informací dostaneš směry, části jména obrázku.
Budeš potřebovat vyřešit oba dva problémy. Ten druhý je ale jednodušší, tak se pojďme zaměřit na něj.
Potřebuješ počítači říct, jak ze souřadnic dvou políček, které jsou vedle sebe, zjistit směr od jednoho ke druhému.
Například směr od (3, 2) k (2, 2) je doleva. Směr od (3, 2) k (3, 3) je nahoru. (Viz obrázek, nebo třetí řádek tabulky výše.)
V Pythonu to napíšeš jako funkci, která bere dva argumenty (souřadnice) a vrátí anglické jméno směru – řetězec, který se dá použít ve jméně souboru s obrázkem.
Až bude tahle funkce hotová, měla by se dát použít následovně:
>>> direction((3, 2), (2, 2))
'left'
>>> direction((3, 3), (3, 2))
'bottom'
>>> direction((3, 3), 'end')
'end'
Na koncích hada bude potřeba jako druhou souřadnici použít místo dvojice čísel
něco jiného.
Řetězec 'end'
funguje dobře, ale stejně tak by se dalo použít cokoli jiného,
co není souřadnice: False
, -1
, nebo třeba []
.
(Zkušený Pythonista by použil hodnotu None
.)
Jak takovou funkci napsat? Když si pořádně prohlédneš první tři sloupce tabulky výše, možná přijdeš na to, jak se od sebe liší souřadnice, které jsou nalevo od sebe. Nebo nahoru.
'end'
'left'
'right'
'bottom'
'top'
Zkušený programátor v tento moment zbystří a zeptá se: „ale co když neplatí
ani jedna z těch podmínek“?
Taková situace ve hře nemůže nastat (nebo ano?), ale přesto je dobré ji
podchytit a na konec postupu přidat třeba „Jinak je výsledek 'end'
”.
To je složitější část řešení našeho problému. Zbytek je jen téměř doslovný překlad z češtiny do Pythonu:
def direction(a, b):
if b == 'end':
return 'end'
# Rozložení souřadnic na čísla (x, y) – to je v češtině "samozřejmé"
x_a, y_a = a
x_b, y_b = b
# ... a logika pokračuje
if x_a == x_b + 1:
return 'left'
elif x_a == x_b - 1:
return 'right'
elif y_a == y_b + 1:
return 'bottom'
elif y_a == y_b - 1:
return 'top'
else:
return 'end'
# Vyzkoušení
print('tohle by mělo být "left":', direction((3, 2), (2, 2)))
print('tohle by mělo být "bottom":', direction((3, 3), (3, 2)))
print('tohle by mělo být "top":', direction((3, 2), (3, 3)))
print('tohle by mělo být "right":', direction((1, 1), (2, 1)))
print('tohle by mělo být "end":', direction((3, 3), 'end'))
print('tohle by mělo být "end":', direction((3, 3), (80, 80)))
Teď se vraťme k prvnímu problému: jak projít všechny políčka hada, a u každého vědět předchozí a následující?
Protože rozdíl mezi souřadnicemi jako (1, 2) a (2, 2) není na první pohled moc čitelný, kousky hada si označím písmenky. Budu psát A místo (1, 2); B místo (2, 2); atd.:
Takového hada nakreslím následovně:
K vykreslení | A | B | C | D | E | F | G |
---|---|---|---|---|---|---|---|
Předchozí | × | A | B | C | D | E | F |
Následující | B | C | D | E | F | G | × |
Jak na to?
První řádek tabulky, seznam [A, B, C, D, E, F, G] už máš – to jsou souřadnice
hada, snake
.
Kdyz se ti k tomu podaří připravit seznamy s druhým řádkem,
[×, A, B, C, D, E, F], a třetím, [B, C, D, E, F, G, ×], můžeš je pak spojit
pomocí funkce zip
.
Vzpomínáš na ni?
Prochází několik „opovídajících si“ seznamů a dá n-tici
prvních prvků, pak n-tici druhých prvků, pak třetích…
Náš příklad byl:
veci = ['tráva', 'slunce', 'mrkev', 'řeka']
barvy = ['zelená', 'žluté', 'oranžová', 'modrá']
mista = ['na zemi', 'nahoře', 'na talíři', 'za zídkou']
for vec, barva, misto in zip(veci, barvy, mista):
print(barva, vec, 'je', misto)
Ale stejně tak můžeš použít:
snake = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
prevs = ['x', 'A', 'B', 'C', 'D', 'E', 'F']
nexts = ['B', 'C', 'D', 'E', 'F', 'G', 'x']
for coords, prev, next in zip(snake, prevs, nexts):
print('na políčku', coords, 'had leze z', prev, 'do', next)
Ty dva další seznamy je ale potřeba „vyrobit“ z prvního: vybrat správný kousek a na správnou stranu doplnit „chybějící“ prvek:
snake = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
prevs = ['end'] + snake[:-1]
nexts = snake[1:] + ['end']
for coords, prev, next in zip(snake, prevs, nexts):
print('na políčku', coords, 'had leze z', prev, 'do', next)
Anebo, s „opravdovými“ souřadnicemi a funkcí direction
:
snake = [(1, 2), (2, 2), (3, 2), (3, 3), (3, 4), (3, 5), (4, 5)]
for coords, prev, next in zip(snake, ['end'] + snake[:-1], snake[1:] + ['end']):
before = direction(coords, prev) # směr z aktuálního políčka na předchozí
after = direction(coords, next) # směr z aktuálního políčka na následující
print('na', coords, 'vykreslit:', before + '-' + after)
Jestli jsi došla až sem, doufám, že nebudeš mít příliš velké problmy s „transplantací“ tohoto kódu do tvojí hry.
{ "data": { "sessionMaterial": { "id": "session-material:2019/brno-podzim-snake:extensions:2", "title": "Vybírání kousků hada", "html": "\n \n \n\n <h1>Vybírání kousků hada</h1>\n<p>Místo toho, aby byl všude stejný kousek hada,\nbudeme chtít vybrat vždycky ten správný.</p>\n<p>Jak na to?\nPodle čeho ho vybrat?</p>\n<p>Obrázky s kousky hada jsou pojmenovány\n<code><var>odkud</var>-kam.png</code>.\nTo není náhoda – ukazuje to, co potřebuješ vědět, abys mohla ten správný\nkousek vybrat.</p>\n<p>Když máš hada podle následujícího obrázku, na políčko (3, 2) patří\nkousek, na kterém had „leze“ zleva nahoru – tedy <code>left-top.png</code></p>\n<p><span class=\"figure\"><a href=\"/2019/brno-podzim-snake/snake/tile-selection/static/tile-selection.svg\"><img src=\"/2019/brno-podzim-snake/snake/tile-selection/static/tile-selection.svg\" alt=\"Had na „šachovnici“ se souřadnicemi. Políčko (3, 2) je zvýrazněné a vedou z něj šipky doleva a nahoru, kudy had pokračuje.\"></a></span></p>\n<p>Na koncích hada je ve jménech obrázků místo směru <code>end</code>.</p>\n<p>Pro každé z políček budeš potřebovat zjistit, odkud a kam na něm had leze –\ntedy směr k <em>předchozí</em> a <em>následující</em> souřadnici:</p>\n<table class=\"table\">\n <tbody><tr>\n <th>Souřadnice</th>\n <th>Předchozí</th>\n <th>Směr k předchozí</th>\n <th>Následující</th>\n <th>Směr k následující</th>\n <th></th>\n </tr>\n\n\n <tr>\n <td>(1, 2)</td>\n <td><em>není</em></td>\n <td><code>end</code></td>\n <td>\n (2, 2)\n </td>\n <td><code>right</code></td>\n <td>\n <img src=\"/2019/brno-podzim-snake/snake/tile-selection/static/snake-tiles/end-right.png\" style=\"width: 1em\" alt=\"end-right.png\">\n </td>\n </tr>\n\n <tr>\n <td>(2, 2)</td>\n <td>\n (1, 2)\n </td>\n <td><code>left</code></td>\n <td>\n (3, 2)\n </td>\n <td><code>right</code></td>\n <td>\n <img src=\"/2019/brno-podzim-snake/snake/tile-selection/static/snake-tiles/left-right.png\" style=\"width: 1em\" alt=\"left-right.png\">\n </td>\n </tr>\n\n <tr>\n <td>(3, 2)</td>\n <td>\n (2, 2)\n </td>\n <td><code>left</code></td>\n <td>\n (3, 3)\n </td>\n <td><code>top</code></td>\n <td>\n <img src=\"/2019/brno-podzim-snake/snake/tile-selection/static/snake-tiles/left-top.png\" style=\"width: 1em\" alt=\"left-top.png\">\n </td>\n </tr>\n\n <tr>\n <td>(3, 3)</td>\n <td>\n (3, 2)\n </td>\n <td><code>bottom</code></td>\n <td>\n (3, 4)\n </td>\n <td><code>top</code></td>\n <td>\n <img src=\"/2019/brno-podzim-snake/snake/tile-selection/static/snake-tiles/bottom-top.png\" style=\"width: 1em\" alt=\"bottom-top.png\">\n </td>\n </tr>\n\n <tr>\n <td>(3, 4)</td>\n <td>\n (3, 3)\n </td>\n <td><code>bottom</code></td>\n <td>\n (3, 5)\n </td>\n <td><code>top</code></td>\n <td>\n <img src=\"/2019/brno-podzim-snake/snake/tile-selection/static/snake-tiles/bottom-top.png\" style=\"width: 1em\" alt=\"bottom-top.png\">\n </td>\n </tr>\n\n <tr>\n <td>(3, 5)</td>\n <td>\n (3, 4)\n </td>\n <td><code>bottom</code></td>\n <td>\n (4, 5)\n </td>\n <td><code>right</code></td>\n <td>\n <img src=\"/2019/brno-podzim-snake/snake/tile-selection/static/snake-tiles/bottom-right.png\" style=\"width: 1em\" alt=\"bottom-right.png\">\n </td>\n </tr>\n\n <tr>\n <td>(4, 5)</td>\n <td>\n (3, 5)\n </td>\n <td><code>left</code></td>\n <td><em>není</em></td>\n <td><code>end</code></td>\n <td>\n <img src=\"/2019/brno-podzim-snake/snake/tile-selection/static/snake-tiles/left-end.png\" style=\"width: 1em\" alt=\"left-end.png\">\n </td>\n </tr>\n\n</tbody></table><p>Toto je <strong>těžký úkol</strong>.\nI když všechny potřebné informace a nástroje k tomu teď teoreticky znáš,\nje potřeba je správným způsobem poskládat dohromady.\nTohle skládání dohromady, <em>návrh algoritmů</em>, je nejsložitější programátorská \ndisciplína.</p>\n<p>Zkus nad tím ale přemýšlet, nech si to rozležet v hlavě třeba přes noc,\nvrať se k materiálům k předchozím lekcím (hlavně k úvodu do Pythonu),\nzkoušej a objevuj… A časem na to přijdeš.</p>\n<p>Jestli nemáš čas, koukněme se na to, jak se dá zařídit.</p>\n<h2>Tohle není evangelium</h2>\n<p>Popisuju tady jedno možné řešení.\nExistuje spousta jiných správných způsobů, jak vybírat políčka hada.\nMožná ti dokonce jiné řešení přijde jednodušší – a možná to bude dokonce\n<em>tvoje</em> řešení!</p>\n<h2>Jednodušší podproblémy</h2>\n<p>Složité problémy programátoři většinou vhodně rozdělí na více jednodušších\nproblémů.\nKaždý pak vyřeší zvlášť a pak spojí dohromady.</p>\n<p>Jaké jednodušší úkoly by se daly najít tady?</p>\n<ol>\n<li>Projít všechny souřadnice, a pro každou z nich políčko zjistit\npředchozí i následující souřadnici.</li>\n<li>Když mám dvě souřadnice, zjistit směr od jedné ke druhé.</li>\n</ol>\n<p>Řešením prvního z nich v tabulce výše „vyplníš“ sloupečky se souřadnicemi.\nŘešením druhého pak z těchto informací dostaneš <em>směry</em>, části jména obrázku.</p>\n<p>Budeš potřebovat vyřešit oba dva problémy.\nTen druhý je ale jednodušší, tak se pojďme zaměřit na něj.</p>\n<h2>Zjistit směr</h2>\n<p>Potřebuješ počítači říct, jak ze souřadnic dvou políček, které jsou vedle sebe,\nzjistit směr od jednoho ke druhému.</p>\n<p>Například směr od (3, 2) k (2, 2) je <em>doleva</em>.\nSměr od (3, 2) k (3, 3) je <em>nahoru</em>.\n(Viz obrázek, nebo třetí řádek tabulky výše.)</p>\n<p><span class=\"figure\"><a href=\"/2019/brno-podzim-snake/snake/tile-selection/static/tile-selection.svg\"><img src=\"/2019/brno-podzim-snake/snake/tile-selection/static/tile-selection.svg\" alt=\"Had na „šachovnici“ se souřadnicemi. Políčko (3, 2) je zvýrazněné a vedou z něj šipky doleva a nahoru, kudy had pokračuje.\"></a></span></p>\n<p>V Pythonu to napíšeš jako <em>funkci</em>, která bere dva argumenty (souřadnice)\na vrátí anglické jméno směru – řetězec, který se dá použít ve jméně souboru\ns obrázkem.</p>\n<p>Až bude tahle funkce hotová, měla by se dát použít následovně:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">>>> </span><span class=\"n\">direction</span><span class=\"p\">((</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">))</span>\n<span class=\"go\">'left'</span>\n<span class=\"gp\">>>> </span><span class=\"n\">direction</span><span class=\"p\">((</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">))</span>\n<span class=\"go\">'bottom'</span>\n<span class=\"gp\">>>> </span><span class=\"n\">direction</span><span class=\"p\">((</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">),</span> <span class=\"s1\">'end'</span><span class=\"p\">)</span>\n<span class=\"go\">'end'</span>\n</pre></div><p>Na koncích hada bude potřeba jako druhou souřadnici použít místo dvojice čísel\nněco jiného.\nŘetězec <code>'end'</code> funguje dobře, ale stejně tak by se dalo použít cokoli jiného,\nco není souřadnice: <code>False</code>, <code>-1</code>, nebo třeba <code>[]</code>.\n(Zkušený Pythonista by použil hodnotu <code>None</code>.)</p>\n<p>Jak takovou funkci napsat?\nKdyž si pořádně prohlédneš první tři sloupce tabulky výše, možná přijdeš na to,\njak se od sebe liší souřadnice, které jsou <em>nalevo</em> od sebe. Nebo <em>nahoru</em>.</p>\n<ul>\n<li>Jak zjistit směr mezi dvěma souřadnicemi:<ul>\n<li>Když ta druhá není souřadnice:<ul>\n<li>výsledek je <code>'end'</code></li>\n</ul>\n</li>\n<li>Když se <var>x</var> té první rovná <var>x</var>+1 druhé:<ul>\n<li>výsledek je <code>'left'</code></li>\n</ul>\n</li>\n<li>Když se <var>x</var> té první rovná <var>x</var>-1 druhé:<ul>\n<li>výsledek je <code>'right'</code></li>\n</ul>\n</li>\n<li>Když se <var>y</var> té první rovná <var>y</var>+1 druhé:<ul>\n<li>výsledek je <code>'bottom'</code></li>\n</ul>\n</li>\n<li>Když se <var>y</var> té první rovná <var>y</var>-1 druhé:<ul>\n<li>výsledek je <code>'top'</code></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n<p>Zkušený programátor v tento moment zbystří a zeptá se: „ale co když neplatí\nani jedna z těch podmínek“?\nTaková situace ve hře nemůže nastat (nebo ano?), ale přesto je dobré ji\npodchytit a na konec postupu přidat třeba „Jinak je výsledek <code>'end'</code>”.</p>\n<p>To je složitější část řešení našeho problému.\nZbytek je jen téměř doslovný překlad z češtiny do Pythonu:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">direction</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">):</span>\n <span class=\"k\">if</span> <span class=\"n\">b</span> <span class=\"o\">==</span> <span class=\"s1\">'end'</span><span class=\"p\">:</span>\n <span class=\"k\">return</span> <span class=\"s1\">'end'</span>\n\n <span class=\"c1\"># Rozložení souřadnic na čísla (x, y) – to je v češtině "samozřejmé"</span>\n <span class=\"n\">x_a</span><span class=\"p\">,</span> <span class=\"n\">y_a</span> <span class=\"o\">=</span> <span class=\"n\">a</span>\n <span class=\"n\">x_b</span><span class=\"p\">,</span> <span class=\"n\">y_b</span> <span class=\"o\">=</span> <span class=\"n\">b</span>\n\n <span class=\"c1\"># ... a logika pokračuje</span>\n <span class=\"k\">if</span> <span class=\"n\">x_a</span> <span class=\"o\">==</span> <span class=\"n\">x_b</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">:</span>\n <span class=\"k\">return</span> <span class=\"s1\">'left'</span>\n <span class=\"k\">elif</span> <span class=\"n\">x_a</span> <span class=\"o\">==</span> <span class=\"n\">x_b</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">:</span>\n <span class=\"k\">return</span> <span class=\"s1\">'right'</span>\n <span class=\"k\">elif</span> <span class=\"n\">y_a</span> <span class=\"o\">==</span> <span class=\"n\">y_b</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">:</span>\n <span class=\"k\">return</span> <span class=\"s1\">'bottom'</span>\n <span class=\"k\">elif</span> <span class=\"n\">y_a</span> <span class=\"o\">==</span> <span class=\"n\">y_b</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">:</span>\n <span class=\"k\">return</span> <span class=\"s1\">'top'</span>\n <span class=\"k\">else</span><span class=\"p\">:</span>\n <span class=\"k\">return</span> <span class=\"s1\">'end'</span>\n\n<span class=\"c1\"># Vyzkoušení</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">'tohle by mělo být "left":'</span><span class=\"p\">,</span> <span class=\"n\">direction</span><span class=\"p\">((</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">)))</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">'tohle by mělo být "bottom":'</span><span class=\"p\">,</span> <span class=\"n\">direction</span><span class=\"p\">((</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">)))</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">'tohle by mělo být "top":'</span><span class=\"p\">,</span> <span class=\"n\">direction</span><span class=\"p\">((</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">)))</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">'tohle by mělo být "right":'</span><span class=\"p\">,</span> <span class=\"n\">direction</span><span class=\"p\">((</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)))</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">'tohle by mělo být "end":'</span><span class=\"p\">,</span> <span class=\"n\">direction</span><span class=\"p\">((</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">),</span> <span class=\"s1\">'end'</span><span class=\"p\">))</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">'tohle by mělo být "end":'</span><span class=\"p\">,</span> <span class=\"n\">direction</span><span class=\"p\">((</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">80</span><span class=\"p\">,</span> <span class=\"mi\">80</span><span class=\"p\">)))</span>\n</pre></div><h2>Projít všechny souřadnice</h2>\n<p>Teď se vraťme k prvnímu problému: jak projít všechny políčka hada,\na u každého vědět předchozí a následující?</p>\n<p>Protože rozdíl mezi souřadnicemi jako (1, 2) a (2, 2) není na první pohled\nmoc čitelný, kousky hada si označím písmenky.\nBudu psát A místo (1, 2); B místo (2, 2); atd.:</p>\n<p><span class=\"figure\"><a href=\"/2019/brno-podzim-snake/snake/tile-selection/static/lettered.svg\"><img src=\"/2019/brno-podzim-snake/snake/tile-selection/static/lettered.svg\" alt=\"Had na „šachovnici“. Každý kousek hada má písmenko: A, B, C, ..., G\"></a></span></p>\n<p>Takového hada nakreslím následovně:</p>\n<ul>\n<li>Nakreslím políčko A (k čemuž potřebuju vědět, že je to začátek a po něm je B)</li>\n<li>Nakreslím políčko B (k čemuž potřebuju vědět, že před ním je A a po něm B)</li>\n<li>Nakreslím políčko C (k čemuž potřebuju vědět, že před ním je B a po něm D)</li>\n<li>… a tak dál:</li>\n</ul>\n<table class=\"table\">\n\n <tbody><tr>\n <th>K vykreslení</th>\n\n <td>A</td>\n\n <td>B</td>\n\n <td>C</td>\n\n <td>D</td>\n\n <td>E</td>\n\n <td>F</td>\n\n <td>G</td>\n\n </tr>\n <tr>\n <th>Předchozí</th>\n\n <td>\n ×\n </td>\n\n <td>\n\n A\n\n </td>\n\n <td>\n\n B\n\n </td>\n\n <td>\n\n C\n\n </td>\n\n <td>\n\n D\n\n </td>\n\n <td>\n\n E\n\n </td>\n\n <td>\n\n F\n\n </td>\n\n </tr>\n <tr>\n <th>Následující</th>\n\n <td>\n\n B\n\n </td>\n\n <td>\n\n C\n\n </td>\n\n <td>\n\n D\n\n </td>\n\n <td>\n\n E\n\n </td>\n\n <td>\n\n F\n\n </td>\n\n <td>\n\n G\n\n </td>\n\n <td>\n ×\n </td>\n\n </tr>\n</tbody></table><p>Jak na to?\nPrvní řádek tabulky, seznam [A, B, C, D, E, F, G] už máš – to jsou souřadnice\nhada, <code>snake</code>.\nKdyz se ti k tomu podaří připravit seznamy s druhým řádkem,\n[×, A, B, C, D, E, F], a třetím, [B, C, D, E, F, G, ×], můžeš je pak spojit\npomocí funkce <code>zip</code>.\nVzpomínáš na ni?\nProchází několik „opovídajících si“ seznamů a dá <var>n</var>-tici\nprvních prvků, pak <var>n</var>-tici druhých prvků, pak třetích…</p>\n<p>Náš příklad byl:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">veci</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s1\">'tráva'</span><span class=\"p\">,</span> <span class=\"s1\">'slunce'</span><span class=\"p\">,</span> <span class=\"s1\">'mrkev'</span><span class=\"p\">,</span> <span class=\"s1\">'řeka'</span><span class=\"p\">]</span>\n<span class=\"n\">barvy</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s1\">'zelená'</span><span class=\"p\">,</span> <span class=\"s1\">'žluté'</span><span class=\"p\">,</span> <span class=\"s1\">'oranžová'</span><span class=\"p\">,</span> <span class=\"s1\">'modrá'</span><span class=\"p\">]</span>\n<span class=\"n\">mista</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s1\">'na zemi'</span><span class=\"p\">,</span> <span class=\"s1\">'nahoře'</span><span class=\"p\">,</span> <span class=\"s1\">'na talíři'</span><span class=\"p\">,</span> <span class=\"s1\">'za zídkou'</span><span class=\"p\">]</span>\n\n<span class=\"k\">for</span> <span class=\"n\">vec</span><span class=\"p\">,</span> <span class=\"n\">barva</span><span class=\"p\">,</span> <span class=\"n\">misto</span> <span class=\"ow\">in</span> <span class=\"nb\">zip</span><span class=\"p\">(</span><span class=\"n\">veci</span><span class=\"p\">,</span> <span class=\"n\">barvy</span><span class=\"p\">,</span> <span class=\"n\">mista</span><span class=\"p\">):</span>\n <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">barva</span><span class=\"p\">,</span> <span class=\"n\">vec</span><span class=\"p\">,</span> <span class=\"s1\">'je'</span><span class=\"p\">,</span> <span class=\"n\">misto</span><span class=\"p\">)</span>\n</pre></div><p>Ale stejně tak můžeš použít:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">snake</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s1\">'A'</span><span class=\"p\">,</span> <span class=\"s1\">'B'</span><span class=\"p\">,</span> <span class=\"s1\">'C'</span><span class=\"p\">,</span> <span class=\"s1\">'D'</span><span class=\"p\">,</span> <span class=\"s1\">'E'</span><span class=\"p\">,</span> <span class=\"s1\">'F'</span><span class=\"p\">,</span> <span class=\"s1\">'G'</span><span class=\"p\">]</span>\n<span class=\"n\">prevs</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s1\">'x'</span><span class=\"p\">,</span> <span class=\"s1\">'A'</span><span class=\"p\">,</span> <span class=\"s1\">'B'</span><span class=\"p\">,</span> <span class=\"s1\">'C'</span><span class=\"p\">,</span> <span class=\"s1\">'D'</span><span class=\"p\">,</span> <span class=\"s1\">'E'</span><span class=\"p\">,</span> <span class=\"s1\">'F'</span><span class=\"p\">]</span>\n<span class=\"n\">nexts</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s1\">'B'</span><span class=\"p\">,</span> <span class=\"s1\">'C'</span><span class=\"p\">,</span> <span class=\"s1\">'D'</span><span class=\"p\">,</span> <span class=\"s1\">'E'</span><span class=\"p\">,</span> <span class=\"s1\">'F'</span><span class=\"p\">,</span> <span class=\"s1\">'G'</span><span class=\"p\">,</span> <span class=\"s1\">'x'</span><span class=\"p\">]</span>\n\n<span class=\"k\">for</span> <span class=\"n\">coords</span><span class=\"p\">,</span> <span class=\"n\">prev</span><span class=\"p\">,</span> <span class=\"nb\">next</span> <span class=\"ow\">in</span> <span class=\"nb\">zip</span><span class=\"p\">(</span><span class=\"n\">snake</span><span class=\"p\">,</span> <span class=\"n\">prevs</span><span class=\"p\">,</span> <span class=\"n\">nexts</span><span class=\"p\">):</span>\n <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">'na políčku'</span><span class=\"p\">,</span> <span class=\"n\">coords</span><span class=\"p\">,</span> <span class=\"s1\">'had leze z'</span><span class=\"p\">,</span> <span class=\"n\">prev</span><span class=\"p\">,</span> <span class=\"s1\">'do'</span><span class=\"p\">,</span> <span class=\"nb\">next</span><span class=\"p\">)</span>\n</pre></div><p>Ty dva další seznamy je ale potřeba „vyrobit“ z prvního:\nvybrat správný kousek a na správnou stranu doplnit „chybějící“ prvek:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">snake</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s1\">'A'</span><span class=\"p\">,</span> <span class=\"s1\">'B'</span><span class=\"p\">,</span> <span class=\"s1\">'C'</span><span class=\"p\">,</span> <span class=\"s1\">'D'</span><span class=\"p\">,</span> <span class=\"s1\">'E'</span><span class=\"p\">,</span> <span class=\"s1\">'F'</span><span class=\"p\">,</span> <span class=\"s1\">'G'</span><span class=\"p\">]</span>\n<span class=\"n\">prevs</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s1\">'end'</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"n\">snake</span><span class=\"p\">[:</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n<span class=\"n\">nexts</span> <span class=\"o\">=</span> <span class=\"n\">snake</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]</span> <span class=\"o\">+</span> <span class=\"p\">[</span><span class=\"s1\">'end'</span><span class=\"p\">]</span>\n\n<span class=\"k\">for</span> <span class=\"n\">coords</span><span class=\"p\">,</span> <span class=\"n\">prev</span><span class=\"p\">,</span> <span class=\"nb\">next</span> <span class=\"ow\">in</span> <span class=\"nb\">zip</span><span class=\"p\">(</span><span class=\"n\">snake</span><span class=\"p\">,</span> <span class=\"n\">prevs</span><span class=\"p\">,</span> <span class=\"n\">nexts</span><span class=\"p\">):</span>\n <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">'na políčku'</span><span class=\"p\">,</span> <span class=\"n\">coords</span><span class=\"p\">,</span> <span class=\"s1\">'had leze z'</span><span class=\"p\">,</span> <span class=\"n\">prev</span><span class=\"p\">,</span> <span class=\"s1\">'do'</span><span class=\"p\">,</span> <span class=\"nb\">next</span><span class=\"p\">)</span>\n</pre></div><p>Anebo, s „opravdovými“ souřadnicemi a funkcí <code>direction</code>:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">snake</span> <span class=\"o\">=</span> <span class=\"p\">[(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">)]</span>\n\n<span class=\"k\">for</span> <span class=\"n\">coords</span><span class=\"p\">,</span> <span class=\"n\">prev</span><span class=\"p\">,</span> <span class=\"nb\">next</span> <span class=\"ow\">in</span> <span class=\"nb\">zip</span><span class=\"p\">(</span><span class=\"n\">snake</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"s1\">'end'</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"n\">snake</span><span class=\"p\">[:</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">snake</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]</span> <span class=\"o\">+</span> <span class=\"p\">[</span><span class=\"s1\">'end'</span><span class=\"p\">]):</span>\n <span class=\"n\">before</span> <span class=\"o\">=</span> <span class=\"n\">direction</span><span class=\"p\">(</span><span class=\"n\">coords</span><span class=\"p\">,</span> <span class=\"n\">prev</span><span class=\"p\">)</span> <span class=\"c1\"># směr z aktuálního políčka na předchozí</span>\n <span class=\"n\">after</span> <span class=\"o\">=</span> <span class=\"n\">direction</span><span class=\"p\">(</span><span class=\"n\">coords</span><span class=\"p\">,</span> <span class=\"nb\">next</span><span class=\"p\">)</span> <span class=\"c1\"># směr z aktuálního políčka na následující</span>\n <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">'na'</span><span class=\"p\">,</span> <span class=\"n\">coords</span><span class=\"p\">,</span> <span class=\"s1\">'vykreslit:'</span><span class=\"p\">,</span> <span class=\"n\">before</span> <span class=\"o\">+</span> <span class=\"s1\">'-'</span> <span class=\"o\">+</span> <span class=\"n\">after</span><span class=\"p\">)</span>\n</pre></div><p>Jestli jsi došla až sem, doufám, že nebudeš mít příliš\nvelké problmy s „transplantací“ tohoto kódu do tvojí hry.</p>\n\n\n " } } }