PlaceGame1

"""
3*3游戏盘,每个位置有0和1两种状态。
每次行动可以选择点击(?)一个位置,之后该位置与它相邻的4个位置(如果有)0/1状态变换
引入随机初始化功能、自定义初始化功能,引入行动可撤销一次机制,引入记录日志功能
"""
import random
import time

print("\nPlaceGame_进阶版1\n仍为3*3,引入随机初始化、自定义初始化功能,引入行动可撤销一次机制,引入记录日志功能(输入r撤销上次行动)")
main_dic = {(i, j): random.randint(0, 1) for i in range(1, 4) for j in range(1, 4)}  # 生成随机游戏盘

timer = 0  # 记录行动次数
xr = 0
yr = 0  # 这两个是用来记录上一次行动的坐标,用于单次撤销
flag1_undo = True  # 确保不会再同一个记录点多次撤销
flag3_save = False

file_journal = open("PlaceGame1_journal.txt", mode="a", encoding="utf-8")
file_journal.write("\n" + time.asctime() + "\n")
# file_save = open("PlaceGame1_save.txt", mode="w", encoding="utf-8")


def show_str():
    """把棋盘 main_dic 的数据以九宫格形式字符串返回。用来展示棋盘
    其实也可以每次都复制粘贴这个字符串,但是太长了不美观"""
    # global main_dic  # 这里只是读取main_dic所以不用global
    show_main_str = f"  1 2 3\n1 {main_dic[1, 1]} {main_dic[2, 1]} {main_dic[3, 1]}\n2 {main_dic[1, 2]} {main_dic[2, 2]} {main_dic[3, 2]}\n3 {main_dic[1, 3]} {main_dic[2, 3]} {main_dic[3, 3]}"
    return show_main_str


def choose_action():
    """将用户输入、行动(或撤销)写在一整个函数里"""
    global timer
    global flag1_undo
    global xr
    global yr  # 引入4个全局变量。这四个因为都涉及记录,不可以每次调用函数就重置一次,所以在全局定义然后引入局部
    x = 0
    y = 0
    change_lst = list()
    # 初始化完成。后面是输入/判断
    while not (0 < x < 4 and 0 < y < 4):
        index_lst = input(f"[Input][第{timer+1}次行动]请输入坐标(示例:2,3)>>>").split(",")
        if len(index_lst) == 2:  # 首先确保用户输入了两个数(我有过输了一个然后不小心按了回车的情况)
            if index_lst[0].isdigit() and index_lst[1].isdigit():  # 再确保这两个都是数!不是别的
                x = int(index_lst[0])
                y = int(index_lst[1])
                xr = x
                yr = y  # 把本次行动位置记录在xr,yr
                print(f"[Action]翻转 x={x}, y={y}")
                file_journal.write(f"/action(x={x}, y={y}), time={timer}\n")
                change_lst = [(x - 1, y), (x, y), (x + 1, y), (x, y - 1), (x, y + 1)]  # 这是(可能)要翻转的所有格子
                flag1_undo = True  # 本次已行动,获得撤销机会*1(bushi
        elif index_lst[0] == "r":
            if flag1_undo:
                print("[Undo]撤销成功")
                file_journal.write("/undo\n")
                timer -= 2  # 一次是抵消函数结尾的+=1,一个是抵消上次的+=1,回到上次行动的timer
                change_lst = [(xr - 1, yr), (xr, yr), (xr + 1, yr), (xr, yr - 1), (xr, yr + 1)]  # 按上次记录的位置再翻一次
                flag1_undo = False  # 撤销机会已使用
                break
            else:
                print("[Error]只能撤销一次。")
        # elif index_lst[0] == "s":
        #     flag3_save = True
        #     break
    for index1 in change_lst:
        if index1 in main_dic.keys():  # 如果坐标在游戏盘上(如果选择的位置在游戏盘边缘就不是翻转5个了)
            main_dic[index1] = 1 - main_dic[index1]  # 1-1=0,1-0=1,用1减一次相当于转换
    print(show_str())
    file_journal.write(f" {show_str()}\n")
    timer += 1


mode_rand = "Z"
while mode_rand.upper() != 'A' and mode_rand.upper() != 'B' and mode_rand.upper() != 'C':
    mode_rand = input("[Choice]请选择如何初始化游戏盘:A.随机 B.全为0 C.自定义\n>>>")
file_journal.write(f"mode_rand={mode_rand.upper()}\n")
if mode_rand.upper() == "B":
    main_dic = {(i, j): 0 for i in range(1, 4) for j in range(1, 4)}  # 用推导式产生全为0的游戏盘
elif mode_rand.upper() == "C":
    selfSet_lst = list()
    while True:  # 自定义游戏盘
        selfSet_lst = input("[Input]请输入从左至右、从上至下的数字初始值(0或1),以英文逗号分隔\n>>>").split(",")
        flag2_isint_len = True  # 用来检查用户有没有输入奇怪的(不是1/0的)东西或者输入个数不对
        # 注意,因为这个flag2必须要在每次重新输入之后重置为True,所以如果写在while True外面,就会发生只要输错一次就永远是False的问题
        if "" in selfSet_lst:
            selfSet_lst.remove("")
        for i in selfSet_lst:
            if i != "1" and i != "0":  # 是数字但是不是0或1,flag标记为False并跳出for循环
                flag2_isint_len = False
                print(f"[Error]输入了1、0以外的其他项。请重新输入。")
                break
        if len(selfSet_lst) != 9:
            flag2_isint_len = False
            print(f"[Error]输入数字个数错误,应输入 9 个,实际输入 {len(selfSet_lst)} 个。请重新输入。")
        if flag2_isint_len:
            break  # 只有3道检查都过关了才能跳出while True循环
    for i in range(9):
        selfSet_lst[i] = int(selfSet_lst[i])
    for j in range(1, 4):
        for i in range(1, 4):
            main_dic[i, j] = selfSet_lst[i - 1 + 3 * (j - 1)]
print(f"初始游戏盘如下。\n{show_str()}")
file_journal.write(f"initial=\n {show_str()}\n")

mode_end = 'Z'
while mode_end.upper() != 'A' and mode_end.upper() != 'B':
    mode_end = input("[Choice]请选择模式:A.全部翻转(全部变为1)即结束游戏 B.自由模式\n>>>")
file_journal.write(f"mode_end={mode_end.upper()}\n")
if mode_end.upper() == "A":
    while 0 in main_dic.values():
        choose_action()
    print(f"[End]已全部翻转。共进行了{timer}次行动。")
    file_journal.close()
else:
    while True:
        choose_action()

或许可以将不同功能(包括Choose_Action和输入判断部分)写进不同文件里然后import,现在的结构不够清晰

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值