|
54 | 54 |
|
55 | 55 | <body>
|
56 | 56 | <header>
|
57 |
| - <aside>January 6, 2022</aside> |
| 57 | + <aside>January 19, 2022</aside> |
58 | 58 | <a href="https://gto76.github.io" rel="author">Jure Šorn</a>
|
59 | 59 | </header>
|
60 | 60 |
|
|
1761 | 1761 | <el> = <Queue>.get_nowait() <span class="hljs-comment"># Raises queue.Empty exception if empty.</span>
|
1762 | 1762 | </code></pre>
|
1763 | 1763 | <div><h2 id="operator"><a href="#operator" name="operator">#</a>Operator</h2><p><strong>Module of functions that provide the functionality of operators.</strong></p><pre><code class="python language-python hljs"><span class="hljs-keyword">import</span> operator <span class="hljs-keyword">as</span> op
|
1764 |
| -<el> = op.add/sub/mul/truediv/floordiv/mod(<el>, <el>) <span class="hljs-comment"># +, -, *, /, //, %</span> |
1765 |
| -<int/set> = op.and_/or_/xor(<int/set>, <int/set>) <span class="hljs-comment"># &, |, ^</span> |
1766 |
| -<bool> = op.eq/ne/lt/le/gt/ge(<sortable>, <sortable>) <span class="hljs-comment"># ==, !=, <, <=, >, >=</span> |
1767 |
| -<func> = op.itemgetter/attrgetter/methodcaller(<int/str>) <span class="hljs-comment"># [<int/str>], .<str>, .<str>()</span> |
| 1764 | +<el> = op.add/sub/mul/truediv/floordiv/mod(<el>, <el>) <span class="hljs-comment"># +, -, *, /, //, %</span> |
| 1765 | +<int/set> = op.and_/or_/xor(<int/set>, <int/set>) <span class="hljs-comment"># &, |, ^</span> |
| 1766 | +<bool> = op.eq/ne/lt/le/gt/ge(<sortable>, <sortable>) <span class="hljs-comment"># ==, !=, <, <=, >, >=</span> |
| 1767 | +<func> = op.itemgetter/attrgetter/methodcaller(<el>) <span class="hljs-comment"># [index/key], .<str>, .<str>()</span> |
1768 | 1768 | </code></pre></div>
|
1769 | 1769 |
|
1770 | 1770 |
|
|
1876 | 1876 | <li><strong><code class="python hljs"><span class="hljs-string">'asyncio.run(<coroutine>)'</span></code> is the main entry point for asynchronous programs.</strong></li>
|
1877 | 1877 | <li><strong>Functions wait(), gather() and as_completed() can be used when multiple coroutines need to be started at the same time.</strong></li>
|
1878 | 1878 | <li><strong>Asyncio module also provides its own <a href="#queue">Queue</a>, <a href="#semaphoreeventbarrier">Event</a>, <a href="#lock">Lock</a> and <a href="#semaphore-event-barrier">Semaphore</a> classes.</strong></li>
|
1879 |
| -</ul><div><h4 id="runsaterminalgamewhereyoucontrolanasteriskthatmustavoidnumbers">Runs a terminal game where you control an asterisk that must avoid numbers:</h4><pre><code class="python language-python hljs"><span class="hljs-keyword">import</span> asyncio, collections, curses, enum, random |
| 1879 | +</ul><div><h4 id="runsaterminalgamewhereyoucontrolanasteriskthatmustavoidnumbers">Runs a terminal game where you control an asterisk that must avoid numbers:</h4><pre><code class="python language-python hljs"><span class="hljs-keyword">import</span> asyncio, collections, curses, curses.textpad, enum, random |
1880 | 1880 |
|
1881 | 1881 | P = collections.namedtuple(<span class="hljs-string">'P'</span>, <span class="hljs-string">'x y'</span>) <span class="hljs-comment"># Position</span>
|
1882 | 1882 | D = enum.Enum(<span class="hljs-string">'D'</span>, <span class="hljs-string">'n e s w'</span>) <span class="hljs-comment"># Direction</span>
|
| 1883 | +W, H = <span class="hljs-number">15</span>, <span class="hljs-number">7</span> <span class="hljs-comment"># Width, Height</span> |
1883 | 1884 |
|
1884 | 1885 | <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main</span><span class="hljs-params">(screen)</span>:</span>
|
1885 | 1886 | curses.curs_set(<span class="hljs-number">0</span>) <span class="hljs-comment"># Makes cursor invisible.</span>
|
1886 | 1887 | screen.nodelay(<span class="hljs-keyword">True</span>) <span class="hljs-comment"># Makes getch() non-blocking.</span>
|
1887 | 1888 | asyncio.run(main_coroutine(screen)) <span class="hljs-comment"># Starts running asyncio code.</span>
|
1888 | 1889 |
|
1889 | 1890 | <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main_coroutine</span><span class="hljs-params">(screen)</span>:</span>
|
1890 |
| - state = {<span class="hljs-string">'*'</span>: P(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>), **{id_: P(<span class="hljs-number">30</span>, <span class="hljs-number">10</span>) <span class="hljs-keyword">for</span> id_ <span class="hljs-keyword">in</span> range(<span class="hljs-number">10</span>)}} |
| 1891 | + state = {<span class="hljs-string">'*'</span>: P(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>), **{id_: P(W//<span class="hljs-number">2</span>, H//<span class="hljs-number">2</span>) <span class="hljs-keyword">for</span> id_ <span class="hljs-keyword">in</span> range(<span class="hljs-number">10</span>)}} |
1891 | 1892 | moves = asyncio.Queue()
|
1892 | 1893 | coros = (*(random_controller(id_, moves) <span class="hljs-keyword">for</span> id_ <span class="hljs-keyword">in</span> range(<span class="hljs-number">10</span>)),
|
1893 |
| - human_controller(screen, moves), |
1894 |
| - model(moves, state, *screen.getmaxyx()), |
1895 |
| - view(state, screen)) |
| 1894 | + human_controller(screen, moves), model(moves, state), view(state, screen)) |
1896 | 1895 | <span class="hljs-keyword">await</span> asyncio.wait(coros, return_when=asyncio.FIRST_COMPLETED)
|
1897 | 1896 |
|
1898 | 1897 | <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">random_controller</span><span class="hljs-params">(id_, moves)</span>:</span>
|
1899 | 1898 | <span class="hljs-keyword">while</span> <span class="hljs-keyword">True</span>:
|
1900 | 1899 | d = random.choice(list(D))
|
1901 | 1900 | moves.put_nowait((id_, d))
|
1902 |
| - <span class="hljs-keyword">await</span> asyncio.sleep(random.random() / <span class="hljs-number">2</span>) |
| 1901 | + <span class="hljs-keyword">await</span> asyncio.sleep(random.triangular(<span class="hljs-number">0.01</span>, <span class="hljs-number">0.65</span>)) |
1903 | 1902 |
|
1904 | 1903 | <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">human_controller</span><span class="hljs-params">(screen, moves)</span>:</span>
|
1905 | 1904 | <span class="hljs-keyword">while</span> <span class="hljs-keyword">True</span>:
|
1906 | 1905 | ch = screen.getch()
|
1907 | 1906 | key_mappings = {<span class="hljs-number">259</span>: D.n, <span class="hljs-number">261</span>: D.e, <span class="hljs-number">258</span>: D.s, <span class="hljs-number">260</span>: D.w}
|
1908 | 1907 | <span class="hljs-keyword">if</span> ch <span class="hljs-keyword">in</span> key_mappings:
|
1909 | 1908 | moves.put_nowait((<span class="hljs-string">'*'</span>, key_mappings[ch]))
|
1910 |
| - <span class="hljs-keyword">await</span> asyncio.sleep(<span class="hljs-number">0.01</span>) |
| 1909 | + <span class="hljs-keyword">await</span> asyncio.sleep(<span class="hljs-number">0.005</span>) |
1911 | 1910 |
|
1912 |
| -<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">model</span><span class="hljs-params">(moves, state, height, width)</span>:</span> |
| 1911 | +<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">model</span><span class="hljs-params">(moves, state)</span>:</span> |
1913 | 1912 | <span class="hljs-keyword">while</span> state[<span class="hljs-string">'*'</span>] <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> {p <span class="hljs-keyword">for</span> id_, p <span class="hljs-keyword">in</span> state.items() <span class="hljs-keyword">if</span> id_ != <span class="hljs-string">'*'</span>}:
|
1914 | 1913 | id_, d = <span class="hljs-keyword">await</span> moves.get()
|
1915 |
| - p = state[id_] |
| 1914 | + x, y = state[id_] |
1916 | 1915 | deltas = {D.n: P(<span class="hljs-number">0</span>, <span class="hljs-number">-1</span>), D.e: P(<span class="hljs-number">1</span>, <span class="hljs-number">0</span>), D.s: P(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>), D.w: P(<span class="hljs-number">-1</span>, <span class="hljs-number">0</span>)}
|
1917 |
| - new_p = P(p.x + deltas[d].x, p.y + deltas[d].y) |
1918 |
| - <span class="hljs-keyword">if</span> <span class="hljs-number">0</span> <= new_p.x < width<span class="hljs-number">-1</span> <span class="hljs-keyword">and</span> <span class="hljs-number">0</span> <= new_p.y < height: |
1919 |
| - state[id_] = new_p |
| 1916 | + state[id_] = P((x + deltas[d].x) % W, (y + deltas[d].y) % H) |
1920 | 1917 |
|
1921 | 1918 | <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">view</span><span class="hljs-params">(state, screen)</span>:</span>
|
| 1919 | + offset = P(x=curses.COLS//<span class="hljs-number">2</span> - W//<span class="hljs-number">2</span>, y=curses.LINES//<span class="hljs-number">2</span> - H//<span class="hljs-number">2</span>) |
1922 | 1920 | <span class="hljs-keyword">while</span> <span class="hljs-keyword">True</span>:
|
1923 |
| - screen.clear() |
| 1921 | + screen.erase() |
| 1922 | + curses.textpad.rectangle(screen, offset.y<span class="hljs-number">-1</span>, offset.x<span class="hljs-number">-1</span>, offset.y+H, offset.x+W) |
1924 | 1923 | <span class="hljs-keyword">for</span> id_, p <span class="hljs-keyword">in</span> state.items():
|
1925 |
| - screen.addstr(p.y, p.x, str(id_)) |
1926 |
| - <span class="hljs-keyword">await</span> asyncio.sleep(<span class="hljs-number">0.01</span>) |
| 1924 | + screen.addstr(offset.y + (p.y - state[<span class="hljs-string">'*'</span>].y + H//<span class="hljs-number">2</span>) % H, |
| 1925 | + offset.x + (p.x - state[<span class="hljs-string">'*'</span>].x + W//<span class="hljs-number">2</span>) % W, str(id_)) |
| 1926 | + <span class="hljs-keyword">await</span> asyncio.sleep(<span class="hljs-number">0.005</span>) |
1927 | 1927 |
|
1928 | 1928 | <span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:
|
1929 | 1929 | curses.wrapper(main)
|
|
2881 | 2881 |
|
2882 | 2882 |
|
2883 | 2883 | <footer>
|
2884 |
| - <aside>January 6, 2022</aside> |
| 2884 | + <aside>January 19, 2022</aside> |
2885 | 2885 | <a href="https://gto76.github.io" rel="author">Jure Šorn</a>
|
2886 | 2886 | </footer>
|
2887 | 2887 |
|
|
0 commit comments