如何实现宾果卡片随机生成器的重复输出重roll功能?
解决宾果卡片随机生成器的重复内容问题
我正在制作一款游戏用宾果卡片随机生成器,当前代码可正常运行,但生成的卡片中会出现重复选项,尝试多种方法都无法解决。现有代码如下:
import PySimpleGUI as sg import random, string items = [str(a), str(b), str(c), str(d), str(e), str(f), str(g), str(h), str(i), str(j), str(k), str(l), str(m), str(n), str(o), str(p), str(q), str(r), str(s), str(t), str(u), str(v), str(w), str(x), str(y), str(z), str(A), str(B), str(C), str(D), str(E), str(F), str(G), str(H), str(I), str(J), str(K), str(L), str(M), str(N), str(O), str(P), str(Q), str(R), str(S), str(T), str(U), str(V), str(W), str(X), str(Y), str(Z)] # ------ Some functions to help generate data for the table ------ def word(): return ''.join(random.choice(items) for ip in range(1)) def make_table(num_rows, num_cols): data = [[ji for ji in range(num_cols)] for ip in range(num_rows)] data[0] = [word() for _ in range(num_cols)] data[1] = [word() for _ in range(num_rows)] data[2] = [word() for _ in range(num_rows)] data[3] = [word() for _ in range(num_rows)] data[4] = [word() for _ in range(num_rows)] return data def edit_cell(window, key, row, col, justify='left'): global textvariable, edit def callback(event, row, col, text, key): global edit widget = event.widget if key == 'Return': text = widget.get() print(text) widget.destroy() widget.master.destroy() values = list(table.item(row, 'values')) values[col] = text table.item(row, values=values) edit = False if edit or row <= 0: return edit = True root = window.TKroot table = window[key].Widget text = table.item(row, "values")[col] x, y, width, height = table.bbox(row, col) frame = sg.tk.Frame(root) frame.place(x=x, y=y, anchor="nw", width=width, height=height) textvariable = sg.tk.StringVar() textvariable.set(text) entry = sg.tk.Entry(frame, textvariable=textvariable, justify=justify) entry.pack() entry.select_range(0, sg.tk.END) entry.icursor(sg.tk.END) entry.focus_force() entry.bind("<Return>", lambda e, r=row, c=col, t=text, k='Return':callback(e, r, c, t, k)) entry.bind("<Escape>", lambda e, r=row, c=col, t=text, k='Escape':callback(e, r, c, t, k)) def main_example1(): global edit edit = False # ------ Make the Table Data ------ # sg.Print('Creating table...') data = make_table(num_rows=5, num_cols=5) # headings = [str(data[0][x])+' ..' for x in range(len(data[0]))] headings = ["B", "I", "N", "C", "O"] # sg.Print('Done creating table. Creating GUI...') sg.set_options(dpi_awareness=True) layout = [[sg.Table(values=data, headings=headings, max_col_width=25, auto_size_columns=True, # display_row_numbers=True, justification='right', num_rows=5, alternating_row_color=sg.theme_button_color()[1], key='-TABLE-', # selected_row_colors='red on yellow', # enable_events=True, # select_mode=sg.TABLE_SELECT_MODE_BROWSE, expand_x=True, expand_y=True, enable_click_events=True, # Comment out to not enable header and other clicks )], [sg.Text('Cell clicked:'), sg.T(k='-CLICKED-')]] window = sg.Window('Table Element - Example 1', layout, resizable=True, finalize=True) while True: event, values = window.read() if event in (sg.WIN_CLOSED, 'Exit'): break elif isinstance(event, tuple): cell = row, col = event[2] window['-CLICKED-'].update(cell) edit_cell(window, '-TABLE-', row+1, col, justify='right') window.close() main_example1()
修改方案
核心思路是用无放回抽样确保所有元素唯一,具体修改如下:
- 移除原有的
word()函数,改用random.sample()从items中一次性抽取25个不重复的元素(刚好填满5x5的宾果表格)。 - 重构
make_table函数,将抽取的元素按5行5列的格式拆分,直接生成无重复的表格数据。
修改后的完整代码:
import PySimpleGUI as sg import random, string items = [str(a), str(b), str(c), str(d), str(e), str(f), str(g), str(h), str(i), str(j), str(k), str(l), str(m), str(n), str(o), str(p), str(q), str(r), str(s), str(t), str(u), str(v), str(w), str(x), str(y), str(z), str(A), str(B), str(C), str(D), str(E), str(F), str(G), str(H), str(I), str(J), str(K), str(L), str(M), str(N), str(O), str(P), str(Q), str(R), str(S), str(T), str(U), str(V), str(W), str(X), str(Y), str(Z)] # ------ Some functions to help generate data for the table ------ def make_table(num_rows, num_cols): # 抽取num_rows*num_cols个不重复的元素 unique_items = random.sample(items, num_rows * num_cols) # 将列表拆分为num_rows行,每行num_cols个元素 data = [unique_items[i*num_cols : (i+1)*num_cols] for i in range(num_rows)] return data def edit_cell(window, key, row, col, justify='left'): global textvariable, edit def callback(event, row, col, text, key): global edit widget = event.widget if key == 'Return': text = widget.get() print(text) widget.destroy() widget.master.destroy() values = list(table.item(row, 'values')) values[col] = text table.item(row, values=values) edit = False if edit or row <= 0: return edit = True root = window.TKroot table = window[key].Widget text = table.item(row, "values")[col] x, y, width, height = table.bbox(row, col) frame = sg.tk.Frame(root) frame.place(x=x, y=y, anchor="nw", width=width, height=height) textvariable = sg.tk.StringVar() textvariable.set(text) entry = sg.tk.Entry(frame, textvariable=textvariable, justify=justify) entry.pack() entry.select_range(0, sg.tk.END) entry.icursor(sg.tk.END) entry.focus_force() entry.bind("<Return>", lambda e, r=row, c=col, t=text, k='Return':callback(e, r, c, t, k)) entry.bind("<Escape>", lambda e, r=row, c=col, t=text, k='Escape':callback(e, r, c, t, k)) def main_example1(): global edit edit = False # ------ Make the Table Data ------ data = make_table(num_rows=5, num_cols=5) headings = ["B", "I", "N", "C", "O"] sg.set_options(dpi_awareness=True) layout = [[sg.Table(values=data, headings=headings, max_col_width=25, auto_size_columns=True, justification='right', num_rows=5, alternating_row_color=sg.theme_button_color()[1], key='-TABLE-', expand_x=True, expand_y=True, enable_click_events=True, )], [sg.Text('Cell clicked:'), sg.T(k='-CLICKED-')]] window = sg.Window('Table Element - Example 1', layout, resizable=True, finalize=True) while True: event, values = window.read() if event in (sg.WIN_CLOSED, 'Exit'): break elif isinstance(event, tuple): cell = row, col = event[2] window['-CLICKED-'].update(cell) edit_cell(window, '-TABLE-', row+1, col, justify='right') window.close() main_example1()
关键说明
random.sample(items, count)会从items列表中随机选出count个不重复的元素,完美解决重复问题。- 拆分列表时用切片
unique_items[i*num_cols : (i+1)*num_cols],确保每行刚好有num_cols个元素,直接生成符合表格要求的二维列表。
内容的提问来源于stack exchange,提问作者Sethsters Bench
相关产品推荐
相关产品推荐

