更新版本

需要用到的包

from selenium import webdriver
from selenium.webdriver.common.by import By
from shudu_count import *

对坐标的一些操作

class re_zuobiao:
    # 获取坐标 坐在 行的 坐标
    def re_heng(self, zb):
        return [f'{zb[0]}{i}' for i in range(1, 10)]
    # 获取坐标 所在列的坐标
    def re_shu(self, zb):
        return [f'{i}{zb[1]}' for i in range(1, 10)]
    # 获取坐标所在宫、横竖的宫 的坐标
    # lei=1 返回坐标所属宫
    # lei =2 返回 所在功 上下方向功
    # lei = 3 返回所在宫 左右宫
    # lei = 4 返回 上下左右宫(不包含所属宫)
    # lei = 5 返回 上下左右宫(包含所属宫)
    def re_gong(self, zb, lei):
        gong = []
        for i in dic_jiu['fang'].keys():
            if lei == 1 and (zb[0] in i[:3] and zb[1] in i[3:]):
                gong.append(i)
                break
            if lei == 5 and (zb[0] in i[:3] or zb[1] in i[3:]):
                gong.append(i)
            if lei == 2 and (zb[0] not in i[:3] and zb[1] in i[3:]):
                gong.append(i)
            if lei == 3 and (zb[0] in i[:3] and zb[1] not in i[3:]):
                gong.append(i)
            if lei == 4 and (zb[0] in i[:3] or zb[1] in i[3:]):
                gong.append(i)
                if zb[0] in i[:3] and zb[1] in i[3:]:
                    gong.remove(i)
        return gong
    # 获取 宫内所有坐标
    def re_zb_byf(self, zb, lei):
        list_zb = []
        gong = self.re_gong(zb, lei)
        for i in gong:
            for a in range(0, 3):
                for b in range(1, 4):
                    list_zb.append(f'{i[a]}{i[-b]}')
        return list_zb

    def re_qzb_by_QD(self, zb):
        list1 = self.re_heng(zb) + self.re_shu(zb) + self.re_zb_byf(zb, 1)
        list2 = sorted(list(set(list1)), key=list1.index)
        list2.remove(zb)
        return list2

    def re_zb_by_HS(self, zb11, zb21, zb33='00'):
        zb_lt = []
        zb1 = str(zb11)
        zb2 = str(zb21)
        zb3 = str(zb33)
        if (zb1[0] == zb2[0] and zb3 == '00') or (zb1[0] == zb2[0] == zb3[0]):
            fang = self.re_gong(zb1, 3)
            for i in fang:
                for j in range(1, 4):
                    zb_lt.append(f'{zb1[0]}{i[-j]}')
        elif (zb1[1] == zb2[1] and zb3 == '00') or (zb1[1] == zb2[1] == zb3[1]):
            fang = self.re_gong(zb1, 2)
            for a in fang:
                for b in range(0, 3):
                    zb_lt.append(f'{a[b]}{zb1[1]}')

        else:
            zb_lt = None
        return zb_lt

    # 返回没确定值坐标,可填的值字典
    def re_no_zb_num(self):
        list_zb = [i for i in dic_shu.keys() if dic_shu[i] == 0]
        dic_zb_num = {}
        for z in list_zb:
            dic_zb_num[z] = []
            for i in range(1, 10):
                gong = self.re_gong(z, 1)[0]
                if isinstance(dic_1_9[i][gong], list) and int(z) in dic_1_9[i][gong]:
                    dic_zb_num[z].append(i)
        return dic_zb_num

清除后选值的方法

class RemoveNum:
    def __init__(self):
        self.rb = re_zuobiao()

    # 显性 数组(找到符合显性数组的例子)
    def remove_by_gong_tong(self):
        dic_zb_n = self.rb.re_no_zb_num()
        # 宫内 显性数组
        for k in dic_jiu['fang'].keys():
            dic_f = {}
            list_s = [f'{k[i]}{k[-j]}' for i in range(0, 3) for j in range(1, 4)]
            for kk in dic_zb_n.keys():
                if kk in list_s:
                    dic_f[kk] = dic_zb_n[kk]
            self.do_remove_by_gong_tong(dic_f, list_s)
        # 行显性数组
        for i in range(1, 10):
            dic_h = {}
            dic_s = {}
            list_s = [ke for ke in dic_zb_n.keys() if i == int(ke[1])]
            list_h = [ke for ke in dic_zb_n.keys() if i == int(ke[0])]
            for ss in list_s: dic_s[ss] = dic_zb_n[ss]
            for hh in list_h: dic_h[hh] = dic_zb_n[hh]
            self.do_remove_by_gong_tong(dic_h, list_h)
            self.do_remove_by_gong_tong(dic_s, list_s)

    # 显性数组逻辑移除候选值
    def do_remove_by_gong_tong(self, dic_x, list_s):
        for a in dic_x.keys():
            for b in dic_x.keys():
                if a != b and dic_x[a] == dic_x[b] and len(dic_x[a]) == 2:
                    if a in list_s: list_s.remove(a)
                    if b in list_s: list_s.remove(b)
                    for ab in list_s:
                        for ji in dic_x[a]:
                            self.remove(ab, ji, f'宫内显性数组移除信息;{a}={dic_x[a]},{b}={dic_x[b]}')
                for c in dic_x.keys():
                    if a != b and b != c and a != c:
                        if len(set(dic_x[a] + dic_x[b] + dic_x[c])) == 3 and (
                                len(dic_x[a]) + len(dic_x[b]) + len(dic_x[c])) >= 7:
                            if a in list_s: list_s.remove(a)
                            if b in list_s: list_s.remove(b)
                            if c in list_s: list_s.remove(c)
                            for abc in list_s:
                                for jj in set(dic_x[a] + dic_x[b] + dic_x[c]):
                                    self.remove(abc, jj, f'f显性数组移除,{a}={dic_x[a]},{b}={dic_x[b]},{c}={dic_x[c]}')

    # x-wing排除
    def do_remove_by_x_wing(self):
        dic_zb_n = self.rb.re_no_zb_num()
        dicd = []
        for i in range(1, 10):
            for zs in range(1, 10):
                hang = []
                for zg in range(1, 10):
                    zb = str(zs) + str(zg)
                    if zb in dic_zb_n.keys():
                        if i in dic_zb_n[zb]:
                            hang.append(zb)
                hang.append(i)
                if len((hang)) == 3: dicd.append(hang)
        for i in range(0, len(dicd)):
            for j in range(i + 1, len(dicd)):
                if dicd[i][2] == dicd[j][2] and dicd[i][0][1] == dicd[j][0][1] and dicd[i][1][1] == dicd[j][1][1]:
                    list1 = self.rb.re_shu(dicd[i][0])
                    list2= self.rb.re_shu(dicd[i][1])
                    list3 = list2+list1
                    list3.remove(dicd[i][0])
                    list3.remove(dicd[i][1])
                    list3.remove(dicd[j][0])
                    list3.remove(dicd[j][1])
                    for n in list3:
                        self.remove(n,dicd[i][2])

    # XY-wing
    def remove_by_xy_wing(self):
        dic_zb_n = self.rb.re_no_zb_num()
        dic_x = {}
        for x in dic_zb_n.keys():
            if len(dic_zb_n[x]) == 2:
                dic_x[x] = dic_zb_n[x]
        for k in dic_x.keys():
            l1 = dic_x[k]
            for kk in dic_x.keys():
                l2 = dic_x[kk]
                if k[0] == kk[0] and len(set(dic_x[k] + dic_x[kk])) == 3:
                    num1= 0
                    num2=0
                    for i in l1:
                        if i not in l2:num1=i
                    for j in l2:
                        if j not in  l1:num2 = j
                    if num1!=0 and num2!=0:
                        for kkk in dic_x.keys():
                            if kkk[1]==kk[1] and len(dic_x[kkk])==2 and num1 in dic_x[kkk] and num2 in dic_x[kkk]:
                                for zb in dic_zb_n.keys():
                                    if kkk[0] ==zb[0]:
                                        self.remove(zb, num2, f'X——Y wing移除:{k}={dic_x[k]},{kk}={dic_x[kk]},{kkk}={dic_x[kkk]}')

    # 行列区块排除
    def remove_by_hl_qk(self):
        dic_zb_n = self.rb.re_no_zb_num()
        for i in range(1, 9):
            list_h = {}
            list_s = {}
            for x in dic_zb_n.keys():
                if int(x[0]) == i:
                    list_h[x] = dic_zb_n[x]
                if int(x[1]) == i:
                    list_s[x] = dic_zb_n[x]
            self.do_remove_by_hl_qk(list_h, 0)
            self.do_remove_by_hl_qk(list_s, 1)

    # 行列区块排除,找到可以移除的 待定值,行排除 h_s=0,列排除h_s=1
    def do_remove_by_hl_qk(self, dic, h_s):
        for a in dic.keys():
            for x in dic[a]:
                num = 0
                a_gong = self.rb.re_gong(a, 1)[0]
                for b in dic.keys():
                    if h_s == 0 and b[1] not in a_gong[-4:] and x in dic[b]:
                        num += 1
                    if h_s == 1 and b[0] not in a_gong[:3] and x in dic[b]:
                        num += 1
                if num == 0:
                    if h_s == 0:
                        list_rm = [f'{i}{j}' for i in a_gong[:3] for j in a_gong[-3:] if i != a[h_s]]
                    if h_s == 1:
                        list_rm = [f'{i}{j}' for i in a_gong[:3] for j in a_gong[-3:] if j != a[h_s]]
                    for i in list_rm: self.remove(i, x,'行列区块排除,找到可以移除的')

    # 确认一个值,移除宫内内其他格,行列其他格此值候选
    def remove_by_QD(self, zb, num):
        for i in self.rb.re_qzb_by_QD(zb):
            self.remove(i, num,f'确认一个值,移除功能内其他格,行列其他格此值候选:根据坐标={zb},移除坐标={i},数={num}')
        for l in range(1, 10):
            if l != num:
                listfg = dic_1_9[l][self.rb.re_gong(zb, 1)[0]]
                if isinstance(listfg, list) and len(listfg) > 1 and int(zb) in dic_1_9[l][self.rb.re_gong(zb, 1)[0]]:
                    dic_1_9[l][self.rb.re_gong(zb, 1)[0]].remove(int(zb))
                    if len(dic_1_9[l][self.rb.re_gong(zb, 1)[0]]) == 1:
                        self.set_value(str(dic_1_9[l][self.rb.re_gong(zb, 1)[0]][0]), l,'确认一个值,移除功能内其他格,行列其他格此值候选remove_by_QD')

    # 宫内 确定某值在 同行、列,移除行列上别的格子此值的候选
    def remove_by_two(self):
        for i in dic_1_9.keys():
            for ke in dic_1_9[i].keys():
                if isinstance(dic_1_9[i][ke], list) and 2 <= len(dic_1_9[i][ke]) <= 3:
                    list_t = self.rb.re_zb_by_HS(*dic_1_9[i][ke])
                    if list_t != None and len(list_t) > 1:
                        for jk in list_t:
                            self.remove(jk, i,'remove_by_two')

    # 移除操作
    def remove(self, zb, num, name=''):
        qr_g = self.rb.re_gong(zb, 1)[0]
        xx = dic_1_9[num][qr_g]

        if isinstance(xx, list) and len(xx) > 1 and int(zb) in xx:
            dic_1_9[num][qr_g].remove(int(zb))
            if 'X——Y wing移除' in name: print(f'移除:[{num}] = P[{zb}]————来自方法{name}')
            if len(dic_1_9[num][qr_g]) == 1:
                self.set_value(str(dic_1_9[num][qr_g][0]), num,f'{name}')
        # 更新每个方块,每行、每列数值已确定格子的数量

    # 很鸡肋的方法
    def hanglie_qukuai(self):
        list1 = [f'{i}{j}' for i in range(1, 10) for j in range(1, 10)]
        for i in list1:
            bj = 0
            for ke in dic_1_9.keys():
                for keke in dic_1_9[ke].keys():
                    remove_list = dic_1_9[ke][keke]
                    if isinstance(remove_list, list) and int(i) in remove_list:
                        bj += 1
                        if bj == 1: set_list = [i, ke]
            if bj == 1: self.set_value(set_list[0], set_list[1],'很鸡肋的方法' )

    # 修改宫、行、列已确定数字的个数
    def update_tianxieshu(self, x, value):
        fang = self.rb.re_gong(x, 1)[0]
        heng = x[0] + '_19'
        shu = '19_' + x[1]
        dic_jiu['fang'][fang] += 1
        dic_jiu['heng'][heng] += 1
        dic_jiu['shu'][shu] += 1
        # 方块、横、竖 数值已确定格子数量=8,可推导出第9个格子的数值
        if dic_jiu['fang'][fang] == 8:
            self.get_8_1('fang', fang)
        if dic_jiu['heng'][heng] == 8:
            self.get_8_1('heng', heng)
        if dic_jiu['shu'][shu] == 8:
            self.get_8_1('shu', shu)

    # 当前宫内,可能出现的数字
    def get_keneng(self, fang):
        list_19 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
        list_0 = []
        for i in range(0, 3):
            for j in range(1, 4):
                zb = f'{fang[i]}{fang[-j]}'
                if dic_shu[zb] != 0 and dic_shu[zb] in list_19:
                    list_19.remove(dic_shu[zb])
                else:
                    list_0.append(zb)
        return list_19, list_0

    def do_some(self, zb, lt_19):
        # 得到单元格所在 行的所有坐标,看看行内有没有 可能出现的数字 并移除
        for i in range(1, 10):
            if dic_shu[f'{zb[0]}{i}'] in lt_19:
                lt_19.remove(dic_shu[f'{zb[0]}{i}'])
        #  得到单元格所在 列的所有坐标,看看行内有没有 可能出现的数字 并移除
        for j in range(1, 10):
            if dic_shu[f'{j}{zb[1]}'] in lt_19:
                lt_19.remove(dic_shu[f'{j}{zb[1]}'])
        if len(lt_19) == 1:
            self.set_value(zb, lt_19[0],'得到宫内可能出现的值,可功能没有确认值的单元格,判断单元格内不能出现的数字')
        else:
            for i in range(1, 10):
                if i not in lt_19:
                    self.remove(zb, i, '打印remove_by_fhs')
        # 根据 已确定数值的8个格子,得到第9个格子的  数值

    # 得到宫内可能出现的值,可功能没有确认值的单元格,判断单元格内不能出现的数字
    def remove_by_fhs(self):
        # 循环得到所有功
        for k in dic_jiu['fang'].keys():
            # 判断功能内缺少的数字,以及没有确定值的单元格
            if dic_jiu['fang'][k] != 9:
                list_19, list_0 = self.get_keneng(k)
                # 循环 功能没有确定值的格子,
                for i in list_0:
                    lt_19 = list_19.copy()
                    self.do_some(i, lt_19)

    def get_8_1(self, fenlei, key):
        list_1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
        list_2 = []
        set_key = ''
        if fenlei == 'fang':
            for heng in key[:3]:
                for shu in key[4:]:
                    if dic_shu[heng + shu] != 0:
                        list_2.append(dic_shu[heng + shu])
                    else:
                        set_key = heng + shu

        if fenlei == 'heng':
            for i in range(1, 10):
                if dic_shu[key[0] + str(i)] != 0:
                    list_2.append(dic_shu[key[0] + str(i)])
                else:
                    set_key = key[0] + str(i)
        if fenlei == 'shu':
            for i in range(1, 10):
                if dic_shu[str(i) + key[-1]] != 0:
                    list_2.append(dic_shu[str(i) + key[-1]])
                else:
                    set_key = str(i) + key[-1]
        list3 = list(set(list_1) - set(list_2))
        self.set_value(set_key, list3[0],'唯余')

    # 确定格子值,赋值
    def set_value(self, zb, num,name = ''):
        if dic_shu[zb] != 0 and name !=0:
            print(f'出错了,dic_shu[{zb}]={dic_shu[zb]},不能再赋值:{num}\n来自方法{name}')
        else:
            dic_shu[zb] = num
            fang = self.rb.re_gong(zb, 1)
            dic_1_9[num][fang[0]] = int(zb)
            self.update_tianxieshu(zb, num)
            self.remove_by_QD(zb, num)

把结果写入对应单元格

def do_wirite(elename, driver, num):
    driver.find_element(By.ID,elename).click()
    driver.find_element(By.ID,elename).send_keys(num)

# 判断是否还有格子没确定数字
def do_do_do(cishu):
    m = True
    list = [f'{i}{j}' for i in range(1, 10) for j in range(1, 10)]
    for ke in list:
        if dic_shu[ke] == 0:
            break
        elif ke == list[-1] and dic_shu[ke] != 0:
            m = False
    if cishu == 15: m = False
    return m
# 遍历移除
def test_do_new(test_dic, driver):
    sd = RemoveNum()
    ssss = re_zuobiao()
    for key in test_dic.keys():
        sd.set_value(key, test_dic[key],'初始赋值')
    cishu = 0
    while do_do_do(cishu):
        sd.remove_by_fhs()
        sd.remove_by_two()
        sd.hanglie_qukuai()
        sd.remove_by_hl_qk()
        sd.remove_by_gong_tong()
        sd.do_remove_by_x_wing()
        # sd.remove_by_xy_wing()
        cishu += 1
    print(dic_1_9)
    print(dic_jiu)
    for i in range(1, 10):
        str_some = ''
        for j in range(1, 10):
            s = str(i) + str(j)
            if s not in test_dic.keys() and dic_shu[s] != 0:
                elename = f's{(i - 1) * 9 + j}'
                do_wirite(elename, driver, str(dic_shu[s]))
            str_some += (' ' + str(dic_shu[s]) + '-')
            if j % 3 == 0:
                str_some += '|'
        print('——————————————————————————————————————————————————————————————————————')
        print(f'第{i}行:{str_some}')
    print('***************************')
    print(ssss.re_no_zb_num())
    # time.sleep(3)
    # driver.find_element_by_id('btn-save').click()
def test_doDDD():
    for i in range(1, 10):
        for j in range(1, 10):
            print((i - 1) * 9 + j)
def test_get_num():
    #     https: // cn.sudokupuzzle.org /
    # chrome --remote-debugging-port=9222
    opt = webdriver.ChromeOptions()
    opt.debugger_address = '127.0.0.1:9222'
    driver = webdriver.Chrome(options=opt)
    # driver.maximize_window()
    driver.implicitly_wait(10)
    test_dic = {}
    driver.switch_to.frame('f1')
    for i in range(1, 82):
        if i % 9 == 0:
            h = int(i / 9)
            s = 9
        else:
            h = int(i / 9) + 1
            s = i % 9
        ele = driver.find_element(By.ID,f's{i}').get_attribute('value')
        if ele != '':
            test_dic[f'{h}{s}'] = int(ele)
    print(test_dic)
    test_do_new(test_dic, driver)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,816评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,729评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,300评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,780评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,890评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,084评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,151评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,912评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,355评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,666评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,809评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,504评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,150评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,121评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,628评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,724评论 2 351

推荐阅读更多精彩内容