Skip to content

Commit 1c8a86f

Browse files
committed
Switch to a bitmap font
Includes a workaround for adafruit/Adafruit_CircuitPython_Display_Text#183
1 parent 25953d6 commit 1c8a86f

File tree

2 files changed

+24
-35
lines changed

2 files changed

+24
-35
lines changed

CircuitPython_Zorque_Text_Game_openai/code.py

Lines changed: 24 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
77
import adafruit_requests as requests
88
import adafruit_touchscreen
9+
from adafruit_bitmap_font.bitmap_font import load_font
10+
from adafruit_display_text.bitmap_label import Label
11+
from adafruit_display_text import wrap_text_to_pixels
912
import board
1013
import displayio
1114
import supervisor
@@ -26,6 +29,9 @@
2629
# Place the key in your settings.toml file
2730
openai_api_key = os.getenv("OPENAI_API_KEY")
2831

32+
nice_font = load_font("helvR10.pcf")
33+
line_spacing = 0.75
34+
2935
# Customize this prompt as you see fit to create a different experience
3036
base_prompt = """
3137
You are an AI helping the player play an endless text adventure game. You will stay in character as the GM.
@@ -99,23 +105,13 @@ def terminal_palette(fg=0xffffff, bg=0):
99105
return p
100106

101107
def print_wrapped(text):
102-
print(text)
103-
maxwidth = main_text.width
104-
for line in text.split("\n"):
105-
col = 0
106-
sp = ''
107-
for word in line.split():
108-
newcol = col + len(sp) + len(word)
109-
if newcol < maxwidth:
110-
terminal.write(sp + word)
111-
col = newcol
112-
else:
113-
terminal.write('\r\n')
114-
terminal.write(word)
115-
col = len(word)
116-
sp = ' '
117-
if sp or not line:
118-
terminal.write('\r\n')
108+
lines = wrap_text_to_pixels(text, use_width, nice_font)
109+
del lines[max_lines:]
110+
#del lines[:-max_lines]
111+
text = '\n'.join(lines)
112+
while '\n\n' in text:
113+
text = text.replace('\n\n', '\n \n')
114+
terminal.text = text
119115
board.DISPLAY.refresh()
120116

121117
def make_full_prompt(action):
@@ -131,8 +127,8 @@ def record_game_step(action, response):
131127

132128
def get_one_completion(full_prompt):
133129
if not use_openai:
134-
return f"""This is a canned response in offline mode. The player's last
135-
choice was as follows: {full_prompt[-1]['content']}""".strip()
130+
return f"""This is a canned response in offline mode. The player's last choice was as follows:
131+
{full_prompt[-1]['content']}""".strip()
136132
try:
137133
response = requests.post(
138134
"https://api.openai.com/v1/chat/completions",
@@ -181,7 +177,7 @@ def run_game_step(forced_choice=None):
181177
choice = forced_choice
182178
else:
183179
choice = get_touchscreen_choice()
184-
print_wrapped(f"\n\nPLAYER: {choice}")
180+
print_wrapped(f"PLAYER: {choice}")
185181
prompt = make_full_prompt(choice)
186182
for _ in range(3):
187183
result = get_one_completion(prompt)
@@ -190,7 +186,6 @@ def run_game_step(forced_choice=None):
190186
else:
191187
raise ValueError("Error getting completion from OpenAI")
192188
print(result)
193-
terminal.write(clear)
194189
print_wrapped(result)
195190

196191
record_game_step(choice, result)
@@ -218,29 +213,23 @@ def run_game_step(forced_choice=None):
218213

219214
# Determine the size of everything
220215
glyph_width, glyph_height = terminalio.FONT.get_bounding_box()
221-
use_height = board.DISPLAY.height - 8
222-
use_width = board.DISPLAY.width - 8
223-
terminal_width = use_width // glyph_width
224-
terminal_height = use_height // glyph_height - 4
216+
use_height = board.DISPLAY.height - 4
217+
use_width = board.DISPLAY.width - 4
225218

226219
# Game text is displayed on this wdget
227-
main_text = displayio.TileGrid(terminalio.FONT.bitmap, pixel_shader=terminal_palette(),
228-
width=terminal_width, height=terminal_height, tile_width=glyph_width,
229-
tile_height=glyph_height)
230-
main_text.x = 4
231-
main_text.y = 4 + glyph_height
232-
terminal = terminalio.Terminal(main_text, terminalio.FONT)
233-
main_group.append(main_text)
220+
terminal = Label(font=nice_font, color=0xffffff, background_color=0, line_spacing=line_spacing, anchor_point=(0,0), anchored_position=(0,glyph_height+1))
221+
max_lines = (use_height - 2 * glyph_height) // int(nice_font.get_bounding_box()[1] * terminal.line_spacing)
222+
main_group.append(terminal)
234223

235224
# Indicate what each quadrant of the screen does when tapped
236225
label_width = use_width // (glyph_width * 2)
237226
main_group.append(terminal_label('1', label_width, terminal_palette(0, 0xffff00), 0, 0))
238227
main_group.append(terminal_label('2', label_width, terminal_palette(0, 0x00ffff),
239228
use_width - label_width*glyph_width, 0))
240229
main_group.append(terminal_label('3', label_width, terminal_palette(0, 0xff00ff),
241-
0, use_height-2*glyph_height))
230+
0, use_height-glyph_height))
242231
main_group.append(terminal_label('4', label_width, terminal_palette(0, 0x00ff00),
243-
use_width - label_width*glyph_width, use_height-2*glyph_height))
232+
use_width - label_width*glyph_width, use_height-glyph_height))
244233

245234
# Show our stuff on the screen
246235
board.DISPLAY.auto_refresh = False
@@ -258,7 +247,7 @@ def run_game_step(forced_choice=None):
258247
run_game_step()
259248
except Exception as e: # pylint: disable=broad-except
260249
traceback.print_exception(e)
261-
terminal.write(f"{clear}An error occurred (more details on REPL).\r\nTouch the screen to re-load")
250+
print_wrapped(f"An error occurred (more details on REPL).\nTouch the screen to re-load")
262251
board.DISPLAY.refresh()
263252
get_touchscreen_choice()
264253
supervisor.reload()
Binary file not shown.

0 commit comments

Comments
 (0)