Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -21,74 +21,112 @@ clientOpenAI = OpenAI(
|
|
21 |
)
|
22 |
|
23 |
ambientazioni = {
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
|
93 |
# Definizione dello schema Pydantic per un personaggio
|
94 |
class Character(BaseModel):
|
@@ -104,11 +142,12 @@ class Character(BaseModel):
|
|
104 |
class CharactersResponse(BaseModel):
|
105 |
personaggi: list[Character]
|
106 |
|
107 |
-
def generate_story(character: Character, nome_ambientazione):
|
108 |
response = clientOpenAI.chat.completions.create(
|
109 |
model='gemini-2.0-flash-thinking-exp-01-21',
|
110 |
n=1,
|
111 |
stream=True,
|
|
|
112 |
messages=[
|
113 |
{"role": "system", "content": f"Tu sei un creatore di giochi di ruolo a CARTE. Crea un regolamento per un gioco di ruolo sul {nome_ambientazione} sulla base dei personaggi che ti fornirò"},
|
114 |
{
|
@@ -128,7 +167,7 @@ def generate_story(character: Character, nome_ambientazione):
|
|
128 |
print(story)
|
129 |
return story
|
130 |
|
131 |
-
def generate_ai(num_personaggi, nome_ambientazione):
|
132 |
# Costruzione del prompt in italiano per generare i personaggi
|
133 |
prompt = (
|
134 |
f"Genera {num_personaggi} personaggi per un gioco di ruolo a carte ambientato nel {nome_ambientazione}. "
|
@@ -142,6 +181,7 @@ def generate_ai(num_personaggi, nome_ambientazione):
|
|
142 |
{"role": "system", "content": f"Sei un assistente utile per la generazione di personaggi per un gioco di RUOLO sul {nome_ambientazione}."},
|
143 |
{"role": "user", "content": prompt},
|
144 |
],
|
|
|
145 |
response_format=CharactersResponse,
|
146 |
)
|
147 |
characters_response = completion.choices[0].message.parsed
|
@@ -173,7 +213,7 @@ def generate_image(prompt, max_retries=5):
|
|
173 |
|
174 |
def generate_images(character: Character, stile_immagine, num_immagini):
|
175 |
# Lista per salvare le immagini generate come tuple (nome_file, bytes)
|
176 |
-
prompt = f"{character.english_description} {stile_immagine}"
|
177 |
images_bytes_list = []
|
178 |
if character.nome != "":
|
179 |
st.subheader(f"{character.nome} 🦸♂️")
|
@@ -205,11 +245,11 @@ def main():
|
|
205 |
stile_immagine = st.sidebar.text_area("Stile Immagine", stile_default, disabled=False)
|
206 |
auto = False
|
207 |
prompt_input = st.sidebar.text_input("Prompt Immagine (in inglese)", value="Soldier", disabled=auto)
|
208 |
-
auto = st.sidebar.toggle(label= 'Generazione automatica')
|
209 |
num_personaggi = st.sidebar.slider("Personaggi", min_value=1, max_value=30, value=5, disabled=not auto)
|
210 |
num_immagini = st.sidebar.slider("Variazioni Immagini", min_value=1, max_value=6, value=2)
|
|
|
211 |
submit_button = st.sidebar.button(label="Genera Immagine", type="primary", use_container_width=True)
|
212 |
-
|
213 |
st.write("Forgia il tuo **destino nell'Impero**: crea, combatti e domina con nel più grande gioco di ruolo a carte generato dall'AI")
|
214 |
|
215 |
if submit_button:
|
@@ -218,12 +258,12 @@ def main():
|
|
218 |
return
|
219 |
if auto:
|
220 |
with st.spinner('Generazione Personaggi'):
|
221 |
-
characters = generate_ai(num_personaggi, nome_ambientazione)
|
222 |
st.subheader('Personaggi 🎭')
|
223 |
df = pd.DataFrame([{k: v for k, v in character.model_dump().items() if k != "english_description"} for character in characters.personaggi])
|
224 |
st.dataframe(df, hide_index=True)
|
225 |
st.divider()
|
226 |
-
generate_story(characters, nome_ambientazione)
|
227 |
st.divider()
|
228 |
else:
|
229 |
characters = CharactersResponse(personaggi=[Character(nome="", classe="Guerriero", forza=10, destrezza=8, intelligenza=6, descrizione="Un forte guerriero", english_description=prompt_input)])
|
|
|
21 |
)
|
22 |
|
23 |
ambientazioni = {
|
24 |
+
"Sacro Romano Impero": {
|
25 |
+
"nome": "Sacro Romano Impero",
|
26 |
+
"stile_immagine": (
|
27 |
+
"Highly detailed, painterly style with a historical yet stylized aesthetic. "
|
28 |
+
"Rich textures, ornate patterns, and a color palette dominated by imperial gold, "
|
29 |
+
"deep red, and aged marble tones. Inspired by medieval European art, "
|
30 |
+
"gothic illuminations, and the grandeur of cathedrals. "
|
31 |
+
"Designed for a tabletop card game, ensuring clarity, readability, "
|
32 |
+
"and a visually immersive experience."
|
33 |
+
)
|
34 |
+
},
|
35 |
+
"Antico Egitto": {
|
36 |
+
"nome": "Antico Egitto",
|
37 |
+
"stile_immagine": (
|
38 |
+
"A stylized Egyptian art style, reminiscent of ancient tomb paintings. "
|
39 |
+
"Use sandy, ochre and turquoise color palette, with hieroglyphic details. "
|
40 |
+
"Geometric shapes and patterns evoke the grandeur of pharaohs and pyramids. "
|
41 |
+
"Designed for a tabletop card game with clarity and distinct thematic flourishes."
|
42 |
+
)
|
43 |
+
},
|
44 |
+
"Dinastia Han Cinese": {
|
45 |
+
"nome": "Dinastia Han Cinese",
|
46 |
+
"stile_immagine": (
|
47 |
+
"Traditional Chinese art style, with ink wash influences, ornate calligraphy, "
|
48 |
+
"and vibrant silk robe patterns. Use subtle brush strokes and bold reds/golds. "
|
49 |
+
"Designed for clarity in a card game with a distinctly ancient Asian aesthetic."
|
50 |
+
)
|
51 |
+
},
|
52 |
+
"Impero Persiano": {
|
53 |
+
"nome": "Impero Persiano",
|
54 |
+
"stile_immagine": (
|
55 |
+
"Intricate Persian miniature style, lavish details, floral ornaments, "
|
56 |
+
"and strong jewel tones like turquoise, gold, and purple. Stylized silhouettes "
|
57 |
+
"in a rich, decorative composition suited for card art."
|
58 |
+
)
|
59 |
+
},
|
60 |
+
"Impero Ottomano": {
|
61 |
+
"nome": "Impero Ottomano",
|
62 |
+
"stile_immagine": (
|
63 |
+
"Ottoman illuminated manuscript style, featuring ornate arabesque borders, "
|
64 |
+
"rich gold leaf, and deep sapphire or emerald backgrounds. "
|
65 |
+
"Figures with flowing robes and turbans, capturing courtly splendor."
|
66 |
+
)
|
67 |
+
},
|
68 |
+
"Maya": {
|
69 |
+
"nome": "Maya",
|
70 |
+
"stile_immagine": (
|
71 |
+
"Mesoamerican style with stylized glyphs, stepped pyramids, and bright colors. "
|
72 |
+
"Incorporate traditional motifs of jaguars and feathers in a decorative, yet readable card layout."
|
73 |
+
)
|
74 |
+
},
|
75 |
+
"Vichinghi": {
|
76 |
+
"nome": "Vichinghi",
|
77 |
+
"stile_immagine": (
|
78 |
+
"Norse-inspired style, with knotwork borders, runic inscriptions, and rugged, "
|
79 |
+
"weathered textures. Use earthy colors and references to Viking longships, "
|
80 |
+
"mythology, and wooden carvings. Balanced for a legible card game design."
|
81 |
+
)
|
82 |
+
},
|
83 |
+
"Pirati": {
|
84 |
+
"nome": "Pirati",
|
85 |
+
"stile_immagine": (
|
86 |
+
"A dynamic and adventurous style inspired by leggende dei mari e pirati romantici. "
|
87 |
+
"Immagini di navi in tempesta, mappe del tesoro, e personaggi con bandane e cappelli tricorni. "
|
88 |
+
"Toni marinari, textures consumate dal sale e dall'acqua, e un'atmosfera ribelle ma affascinante, "
|
89 |
+
"perfetta per un gioco di carte che evoca il brivido dell'avventura sul mare."
|
90 |
+
)
|
91 |
+
},
|
92 |
+
"Cowboy del Far West": {
|
93 |
+
"nome": "Cowboy del Far West",
|
94 |
+
"stile_immagine": (
|
95 |
+
"Uno stile che richiama i paesaggi desertici, le praterie sconfinate e i tramonti infuocati. "
|
96 |
+
"Elementi iconici come cappelli da cowboy, revolver e diligenze, uniti a colori terrosi e caldi. "
|
97 |
+
"Una composizione che unisce il romanticismo dell'Ovest selvaggio a un design chiaro e narrativo, "
|
98 |
+
"ideale per illustrare scene di duelli e viaggi avventurosi."
|
99 |
+
)
|
100 |
+
},
|
101 |
+
"Steampunk": {
|
102 |
+
"nome": "Steampunk",
|
103 |
+
"stile_immagine": (
|
104 |
+
"Un'estetica retrofuturistica che fonde l'epoca vittoriana con invenzioni meccaniche. "
|
105 |
+
"Abiti d'epoca, ingranaggi in ottone, macchinari complessi e ambientazioni industriali. "
|
106 |
+
"Colori caldi e metallici, texture invecchiate e dettagli elaborati che trasmettono un'atmosfera "
|
107 |
+
"di mistero e innovazione, perfetti per una carta di gioco che vuole raccontare storie fuori dal comune."
|
108 |
+
)
|
109 |
+
},
|
110 |
+
"Alieni": {
|
111 |
+
"nome": "Alieni",
|
112 |
+
"stile_immagine": (
|
113 |
+
"Un'estetica fantascientifica e surreale, con creature d'aspetto extraterrestre, "
|
114 |
+
"paesaggi cosmici e tecnologie aliene. Combina elementi di luce fluorescente, "
|
115 |
+
"forme organiche e architetture impossibili, creando un'atmosfera misteriosa e intrigante. "
|
116 |
+
"Ideale per un gioco di carte che trasporta i giocatori in un universo lontano e pieno di meraviglie."
|
117 |
+
)
|
118 |
+
},
|
119 |
+
"Homo Sapiens": {
|
120 |
+
"nome": "Homo Sapiens",
|
121 |
+
"stile_immagine": (
|
122 |
+
"Un'interpretazione moderna e riflessiva dell'evoluzione umana, con un mix di realismo e "
|
123 |
+
"elementi simbolici che rappresentano la storia e la cultura della nostra specie. "
|
124 |
+
"Utilizza toni naturali, texture ispirate alla materia organica e dettagli che richiamano "
|
125 |
+
"l'arte preistorica e contemporanea, per creare un'immagine che unisce il passato remoto al presente."
|
126 |
+
)
|
127 |
+
},
|
128 |
+
}
|
129 |
+
|
130 |
|
131 |
# Definizione dello schema Pydantic per un personaggio
|
132 |
class Character(BaseModel):
|
|
|
142 |
class CharactersResponse(BaseModel):
|
143 |
personaggi: list[Character]
|
144 |
|
145 |
+
def generate_story(character: Character, nome_ambientazione, creativita):
|
146 |
response = clientOpenAI.chat.completions.create(
|
147 |
model='gemini-2.0-flash-thinking-exp-01-21',
|
148 |
n=1,
|
149 |
stream=True,
|
150 |
+
temperature=creativita,
|
151 |
messages=[
|
152 |
{"role": "system", "content": f"Tu sei un creatore di giochi di ruolo a CARTE. Crea un regolamento per un gioco di ruolo sul {nome_ambientazione} sulla base dei personaggi che ti fornirò"},
|
153 |
{
|
|
|
167 |
print(story)
|
168 |
return story
|
169 |
|
170 |
+
def generate_ai(num_personaggi, nome_ambientazione, creativita):
|
171 |
# Costruzione del prompt in italiano per generare i personaggi
|
172 |
prompt = (
|
173 |
f"Genera {num_personaggi} personaggi per un gioco di ruolo a carte ambientato nel {nome_ambientazione}. "
|
|
|
181 |
{"role": "system", "content": f"Sei un assistente utile per la generazione di personaggi per un gioco di RUOLO sul {nome_ambientazione}."},
|
182 |
{"role": "user", "content": prompt},
|
183 |
],
|
184 |
+
temperature=creativita,
|
185 |
response_format=CharactersResponse,
|
186 |
)
|
187 |
characters_response = completion.choices[0].message.parsed
|
|
|
213 |
|
214 |
def generate_images(character: Character, stile_immagine, num_immagini):
|
215 |
# Lista per salvare le immagini generate come tuple (nome_file, bytes)
|
216 |
+
prompt = f"{character.english_description} {stile_immagine}. (INSERT TEXT NAME = {character.nome})"
|
217 |
images_bytes_list = []
|
218 |
if character.nome != "":
|
219 |
st.subheader(f"{character.nome} 🦸♂️")
|
|
|
245 |
stile_immagine = st.sidebar.text_area("Stile Immagine", stile_default, disabled=False)
|
246 |
auto = False
|
247 |
prompt_input = st.sidebar.text_input("Prompt Immagine (in inglese)", value="Soldier", disabled=auto)
|
248 |
+
auto = st.sidebar.toggle(label= 'Generazione automatica', value = True)
|
249 |
num_personaggi = st.sidebar.slider("Personaggi", min_value=1, max_value=30, value=5, disabled=not auto)
|
250 |
num_immagini = st.sidebar.slider("Variazioni Immagini", min_value=1, max_value=6, value=2)
|
251 |
+
creativita = st.sidebar.slider("Creativita", min_value=0.1, max_value=1.0, value=0.8, step=0.1)
|
252 |
submit_button = st.sidebar.button(label="Genera Immagine", type="primary", use_container_width=True)
|
|
|
253 |
st.write("Forgia il tuo **destino nell'Impero**: crea, combatti e domina con nel più grande gioco di ruolo a carte generato dall'AI")
|
254 |
|
255 |
if submit_button:
|
|
|
258 |
return
|
259 |
if auto:
|
260 |
with st.spinner('Generazione Personaggi'):
|
261 |
+
characters = generate_ai(num_personaggi, nome_ambientazione, creativita)
|
262 |
st.subheader('Personaggi 🎭')
|
263 |
df = pd.DataFrame([{k: v for k, v in character.model_dump().items() if k != "english_description"} for character in characters.personaggi])
|
264 |
st.dataframe(df, hide_index=True)
|
265 |
st.divider()
|
266 |
+
generate_story(characters, nome_ambientazione, creativita)
|
267 |
st.divider()
|
268 |
else:
|
269 |
characters = CharactersResponse(personaggi=[Character(nome="", classe="Guerriero", forza=10, destrezza=8, intelligenza=6, descrizione="Un forte guerriero", english_description=prompt_input)])
|