Spaces:
Build error
Build error
| import streamlit as st | |
| from streamlit_drawable_canvas import st_canvas | |
| from PIL import Image, ImageDraw | |
| import matplotlib.colors | |
| import pandas as pd | |
| import numpy as np | |
| from flow_game_solver import ( | |
| validate_board_and_count_colors, | |
| initiate_model_with_param, | |
| solve_model, | |
| ) | |
| from enum import Enum | |
| class Language(Enum): | |
| English = 1 | |
| Japanese = 2 | |
| if 'language' not in st.session_state: | |
| st.session_state['language'] = Language.English | |
| _, col2 = st.columns([5,1]) | |
| with col2: | |
| language = st.selectbox("Language" if st.session_state['language'] == Language.English else "言語", ("English", "日本語")) | |
| st.session_state['language'] = Language.English if language == "English" else Language.Japanese | |
| # use canvas for user input, read the input, and connect those dots!! | |
| def position_to_index(x, y, width, height, rows, columns): | |
| return int(x / (width / columns)), int(y / (height / rows)) | |
| def convert_json_to_board( | |
| data: pd.DataFrame, width: int, height: int, rows: int, columns: int | |
| ): | |
| board = np.zeros((columns, rows)) | |
| circleIdList = {} | |
| for _, row in data.iterrows(): | |
| x, y = row["left"] + row["radius"], row["top"] | |
| idx, idy = position_to_index(int(x), int(y), width, height, rows, columns) | |
| circleId = row["stroke"] | |
| if circleId == "#ffffff": | |
| circleIdList[row["stroke"]] = -1 | |
| elif circleId not in circleIdList.keys(): | |
| circleIdList[row["stroke"]] = len(circleIdList) + 1 | |
| board[idx, idy] = circleIdList[row["stroke"]] | |
| return board.T.astype(int).tolist() | |
| def draw_grid(img: Image, columns: int, rows: int): | |
| width = img.width | |
| height = img.height | |
| draw = ImageDraw.Draw(img) | |
| for col in range(columns): | |
| x = (width / columns) * (col + 1) | |
| draw.line((x, 0, x, height), fill=128) | |
| for row in range(rows): | |
| y = (width / rows) * (row + 1) | |
| draw.line((0, y, width, y), fill=128) | |
| return img | |
| st.title("Connect the dots" if st.session_state['language'] == Language.English else "ドットを繋ごう") | |
| WIDTH = 300 | |
| HEIGHT = 300 | |
| col1, col2, col3 = st.columns(3) | |
| with col1: | |
| COLUMNS = st.number_input("Columns" if st.session_state['language'] == Language.English else "列数", min_value=1, max_value=100, value=3) | |
| with col2: | |
| ROWS = st.number_input("Rows" if st.session_state['language'] == Language.English else "行数", min_value=1, max_value=100, value=3) | |
| with col3: | |
| fill = st.slider("Minimum Fill" if st.session_state['language'] == Language.English else "最低埋める率", min_value=0.0, max_value=1.0, value=1.0) | |
| waitLimit = st.number_input( | |
| "Max wait time in seconds" if st.session_state['language'] == Language.English else "最大待つ秒数", value=1, min_value=1, max_value=100 | |
| ) | |
| bg_image = Image.fromarray((np.ones((HEIGHT, WIDTH, 3)) * 0).astype(np.uint8)) | |
| # draw = ImageDraw.Draw(bg_image) | |
| # draw grid | |
| bg_image = draw_grid(bg_image, COLUMNS, ROWS) | |
| # draw.line((0, 0, 100, 100), fill=128) | |
| stroke_color = st.color_picker("Point Color: " if st.session_state['language'] == Language.English else "色", "#eab") | |
| # Create a canvas component | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| canvas_result = st_canvas( | |
| # fill_color="rgba(255, 165, 0, 0.3)", # Fixed fill color with some opacity | |
| fill_color=stroke_color, # Fixed fill color with some opacity | |
| stroke_width=5, | |
| stroke_color=stroke_color, | |
| background_color="#fff", | |
| background_image=bg_image, | |
| update_streamlit=True, | |
| height=HEIGHT, | |
| width=WIDTH, | |
| drawing_mode="point", | |
| point_display_radius=min(WIDTH / COLUMNS, HEIGHT / ROWS) / 3, | |
| key="canvas", | |
| ) | |
| with col2: | |
| st.info(""" | |
| Click on the board to add pair of color source(s). | |
| Change color for different source(s). | |
| Use White color for unpassable path. | |
| Results is shown below. | |
| """ | |
| if st.session_state['language'] == Language.English else | |
| """ | |
| ボードをクリックして、カラー ソースのペアを追加します。 | |
| ソースごとに色を変更して、 | |
| 通行できないパスには白色を使用してお願いします。 | |
| 結果は下にあります。 | |
| """) | |
| clicked = st.button("Show result" if st.session_state['language'] == Language.English else "結果表示") | |
| if clicked: | |
| boardData = pd.json_normalize(canvas_result.json_data["objects"]) | |
| colors = [ | |
| matplotlib.colors.to_rgb(row["stroke"]) for _, row in boardData.iterrows() | |
| ] | |
| colors = list(set(colors)) | |
| colors.insert(0, matplotlib.colors.to_rgb("#222")) | |
| board = convert_json_to_board( | |
| boardData, | |
| WIDTH, | |
| HEIGHT, | |
| ROWS, | |
| COLUMNS, | |
| ) | |
| min_length = 0 | |
| max_length = 1000 | |
| num_colors, num_wall = validate_board_and_count_colors(board) | |
| # initiate model | |
| model, solution, edge = initiate_model_with_param( | |
| board, | |
| num_colors, | |
| num_wall, | |
| fill=fill, | |
| area_matrix=None, | |
| min_length=min_length, | |
| max_length=max_length, | |
| ) | |
| # solve | |
| ax = solve_model(model, board, solution, edge, waitLimit, None, colors=colors) | |
| if ax is not None: | |
| st.pyplot(ax.get_figure()) | |
| else: | |
| st.error("Solution does not exist" if st.session_state['language'] == Language.English else "解が見つからない") | |
| # connect dots using or tools | |