Skip to content

Commit 2baed9d

Browse files
committed
add gomoku demo and doc update
1 parent 0b0d0cf commit 2baed9d

File tree

5 files changed

+114
-11
lines changed

5 files changed

+114
-11
lines changed

demos/__main__.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from demos.doc_demo import get_app as get_doc_demo_app
1010
from demos.set_env_demo import main as set_env_demo
1111
from demos.markdown_previewer import main as markdown_previewer
12+
from demos.gomoku_game import main as gomoku_game
1213

1314
from pywebio import STATIC_PATH
1415
from pywebio.output import put_markdown, put_row, put_html, style
@@ -19,10 +20,11 @@
1920
index_md = r"""### Basic demo
2021
2122
- [BMI calculation](./bmi): Calculating Body Mass Index based on height and weight
22-
- [Online chat room](./chat_room): Chat with everyone currently online
23-
- [Markdown live preview](./markdown_previewer): The online markdown editor with live preview
24-
- [Input demo](./input_usage): Demonstrate various input usage supported by PyWebIO
25-
- [Output demo](./output_usage): Demonstrate various output usage supported by PyWebIO
23+
- [Online chat room](./chat_room): Chat with everyone currently online (using less than 90 lines of code)
24+
- [Markdown live preview](./markdown_previewer): The online markdown editor with live preview (using less than 40 lines of code)
25+
- [Online Gomoku game](./gomoku_game): An online shared Gomoku game (using less than 100 lines of code)
26+
- [Input demo](./input_usage): Demonstrate the usage of PyWebIO input module
27+
- [Output demo](./output_usage): Demonstrate the usage of PyWebIO output module
2628
2729
### Data visualization demo
2830
PyWebIO supports for data visualization with the third-party libraries.
@@ -61,7 +63,9 @@
6163
index_md_zh = r"""### 基本demo
6264
6365
- [BMI计算](./bmi): 根据身高体重计算BMI指数
64-
- [聊天室](./chat_room): 和当前所有在线的人聊天
66+
- [聊天室](./chat_room): 和当前所有在线的人聊天 (不到90行代码实现)
67+
- [Markdown实时预览](./markdown_previewer): 可以实时预览的在线Markdown编辑器 (不到40行代码实现)
68+
- [在线五子棋游戏](./gomoku_game): 多人协作对战的五子棋游戏 (不到100行代码实现)
6569
- [输入演示](./input_usage): 演示PyWebIO输入模块的用法
6670
- [输出演示](./output_usage): 演示PyWebIO输出模块的用法
6771
- 更多Demo请见[文档](https://pywebio.readthedocs.io)中示例代码的在线Demo
@@ -95,7 +99,7 @@
9599
96100
### Links
97101
* PyWebIO Github [github.com/wang0618/PyWebIO](https://github.com/wang0618/PyWebIO)
98-
* 使用手册和实现文档见 [pywebio.readthedocs.io](https://pywebio.readthedocs.io)
102+
* 使用手册和实现文档见 [pywebio.readthedocs.io](https://pywebio.readthedocs.io/zh_CN/latest/)
99103
100104
""".format(charts_demo_host=charts_demo_host)
101105

@@ -130,6 +134,7 @@ def index():
130134
(r"/doc_demo", webio_handler(get_doc_demo_app(), cdn=False)),
131135
(r"/set_env_demo", webio_handler(set_env_demo, cdn=False)),
132136
(r"/markdown_previewer", webio_handler(markdown_previewer, cdn=False)),
137+
(r"/gomoku_game", webio_handler(gomoku_game, cdn=False)),
133138
(r"/(.*)", tornado.web.StaticFileHandler, {"path": STATIC_PATH, 'default_filename': 'index.html'})
134139
])
135140
application.listen(port=options.port)

demos/gomoku_game.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
"""
2+
Online Shared Gomoku Game
3+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4+
All online players are divided into two roles (black and white) and play same Gomoku game together.
5+
6+
:demo_host:`Demo </gomoku_game>`, `Source code <https://github.com/wang0618/PyWebIO/blob/dev/demos/gomoku_game.py>`_
7+
"""
8+
import pywebio, time
9+
from pywebio.output import *
10+
from pywebio.session import *
11+
12+
chessboard_size = 15
13+
# -1 -> none, 0 -> black, 1 -> white
14+
chessboard = [
15+
[-1] * chessboard_size
16+
for _ in range(chessboard_size)
17+
]
18+
19+
def winner(): # return winner piece, return None if no winner
20+
for x in range(2, chessboard_size - 2):
21+
for y in range(2, chessboard_size - 2):
22+
# check if (x,y) is the win center
23+
if chessboard[x][y] != -1 and any([
24+
all(chessboard[x][y] == chessboard[m][n] for m, n in [(x - 2, y), (x - 1, y), (x + 1, y), (x + 2, y)]),
25+
all(chessboard[x][y] == chessboard[m][n] for m, n in [(x, y - 2), (x, y - 1), (x, y + 1), (x, y + 2)]),
26+
all(chessboard[x][y] == chessboard[m][n] for m, n in [(x - 2, y - 2), (x - 1, y - 1), (x + 1, y + 1), (x + 2, y + 2)]),
27+
all(chessboard[x][y] == chessboard[m][n] for m, n in [(x - 2, y + 2), (x - 1, y + 1), (x + 1, y - 1), (x + 2, y - 2)]),
28+
]):
29+
return ['⚫', '⚪'][chessboard[x][y]]
30+
31+
session_id = 0 # auto incremented id for each session
32+
current_turn = 0 # 0 for black, 1 for white
33+
player_count = [0, 0] # count of player for two roles
34+
def main():
35+
"""Online Shared Gomoku Game
36+
37+
All online players are divided into two roles (black and white) and share this game."""
38+
global session_id, current_turn, chessboard
39+
if winner(): # The current game is over, reset game
40+
chessboard = [[-1] * chessboard_size for _ in range(chessboard_size)]
41+
current_turn = 0
42+
43+
my_turn = session_id % 2
44+
my_chess = ['⚫', '⚪'][my_turn]
45+
session_id += 1
46+
player_count[my_turn] += 1
47+
48+
@defer_call
49+
def player_exit():
50+
player_count[my_turn] -= 1
51+
52+
set_env(output_animation=False)
53+
put_html("""<style> table th, table td { padding: 0px !important;} button {padding: .75rem!important; margin:0!important} </style>""") # Custom styles to make the board more beautiful
54+
55+
put_markdown(f"""# Online Shared Gomoku Game
56+
All online players are divided into two roles (black and white) and share this game. You can open this page in multiple tabs of your browser to simulate multiple users.
57+
This application uses less than 100 lines of code, the source code is [here](https://github.com/wang0618/PyWebIO/blob/dev/demos/gomoku_game.py)
58+
Currently online player: {player_count[0]} for ⚫, {player_count[1]} for ⚪.
59+
Your role is {my_chess}.
60+
""", lstrip=True)
61+
62+
def set_chess(pos):
63+
global current_turn
64+
if current_turn != my_turn:
65+
toast("It's not your turn!!", color='error')
66+
return
67+
x, y = pos
68+
chessboard[x][y] = my_turn
69+
current_turn = (current_turn + 1) % 2
70+
71+
@use_scope('chessboard', clear=True)
72+
def show_chessboard():
73+
table = [
74+
[
75+
put_buttons([dict(label=' ', value=(x, y), color='light')], onclick=set_chess) if cell == -1 else [' ⚫', ' ⚪'][cell]
76+
for y, cell in enumerate(row)
77+
]
78+
for x, row in enumerate(chessboard)
79+
]
80+
put_table(table)
81+
82+
show_chessboard()
83+
while not winner():
84+
with use_scope('msg', clear=True):
85+
current_turn_copy = current_turn
86+
if current_turn_copy == my_turn:
87+
put_text("It's your turn!")
88+
else:
89+
put_row([put_text("Your opponent's turn, waiting... "), put_loading().style('width:1.5em; height:1.5em')], size='auto 1fr')
90+
while current_turn == current_turn_copy: # wait for next move
91+
time.sleep(0.2)
92+
show_chessboard()
93+
with use_scope('msg', clear=True):
94+
put_text('Game over. The winner is %s!\nRefresh page to start a new round.' % winner())
95+
96+
97+
if __name__ == '__main__':
98+
pywebio.start_server(main, debug=True, port=8080, cdn=False)

docs/locales/zh_CN/LC_MESSAGES/demos.po

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ msgstr ""
88
"Project-Id-Version: PyWebIO 1.1.0\n"
99
"Report-Msgid-Bugs-To: \n"
1010
"POT-Creation-Date: 2021-05-30 17:09+0800\n"
11-
"PO-Revision-Date: 2021-05-30 17:09+0800\n"
11+
"PO-Revision-Date: 2021-07-17 17:17+0800\n"
1212
"Last-Translator: WangWeimin <wang0.618@qq.com>\n"
1313
"Language: zh_CN\n"
1414
"Language-Team: \n"
@@ -17,7 +17,7 @@ msgstr ""
1717
"Content-Type: text/plain; charset=utf-8\n"
1818
"Content-Transfer-Encoding: 8bit\n"
1919
"Generated-By: Babel 2.8.0\n"
20-
"X-Generator: Poedit 2.4.2\n"
20+
"X-Generator: Poedit 3.0\n"
2121

2222
#: ../../demos.rst:2
2323
msgid "Demos"
@@ -119,7 +119,7 @@ msgid ""
119119
"wang0618/PyWebIO/blob/dev/demos/markdown_previewer.py>`_"
120120
msgstr ""
121121
":demo_host:`Demo地址 </markdown_previewer>`, `源码 <https://github.com/wang0618/"
122-
"PyWebIO/blob/dev/demos/bmi.py>`_"
122+
"PyWebIO/blob/dev/demos/markdown_previewer.py>`_"
123123

124124
#: ../../demos.rst:11
125125
msgid "Data visualization demos"

pywebio/output.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -912,7 +912,7 @@ def put_loading(shape='border', color='dark', scope=Scope.Current, position=Outp
912912
913913
## ----
914914
# using style() to set the size of the loading prompt
915-
style(put_loading(), 'width:4rem; height:4rem')
915+
put_loading().style('width:4rem; height:4rem')
916916
"""
917917
assert shape in ('border', 'grow'), "shape must in ('border', 'grow')"
918918
assert color in {'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'light', 'dark'}

pywebio/session/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ def set_env(**env_info):
487487
* ``input_panel_min_height`` (int): The minimum height of input panel (in pixel, default 300px), it should be larger than 75px. Available only when ``input_panel_fixed=True``
488488
* ``input_panel_init_height`` (int): The initial height of input panel (in pixel, default 300px), it should be larger than 175px. Available only when ``input_panel_fixed=True``
489489
* ``input_auto_focus`` (bool): Whether to focus on input automatically after showing input panel, default is ``True``
490-
* ``output_max_width`` (str): The max width of the page content area (in pixel or percentage, e.g. ``'1080px'``,``80%``. Default is 880px).
490+
* ``output_max_width`` (str): The max width of the page content area (in pixel or percentage, e.g. ``'1080px'``, ``'80%'``. Default is 880px).
491491
492492
Example::
493493

0 commit comments

Comments
 (0)