示例#1
0
def trim_and_report(pboard, things_to_trim, real_corners, x_length, key):
    x_length_lookup = {3: "triplicate", 4: "quadruplicate"}
    #log(0, things_to_trim)
    display = []
    #log(0, real_corners)
    for coord in real_corners:
        if coord != key:
            for poss in pboard[coord[0]][coord[1]]:
                display.append((coord, poss, "set1"))
    for poss in pboard[key[0]][key[1]]:
        display.append((key, poss, "set2"))
    first_entry = True
    for number_info in things_to_trim:
        for coord in number_info[1]:
            y, x = coord[0], coord[1]
            pboard[y][x].remove(number_info[0])
            if first_entry:
                first_entry = False
                GAMESTEPS[0] += 1
                display.append((coord, number_info[0], "remove"))
            else:
                display = [(coord, number_info[0], "remove")]
            msg = " because its seen by all members of the hinged " + x_length_lookup[
                x_length]
            display_msg = "Removed " + str(number_info[0]) + msg
            support.update_gamestepslog('pboard', 'remove', coord,
                                        number_info[0], display_msg, False,
                                        display)
示例#2
0
def trim_and_report(pboard, things_to_trim, real_corners, x_length, key):
    x_length_lookup = {3:"triplicate", 4:"quadruplicate"}
    #log(0, things_to_trim)
    display = []
    #log(0, real_corners)
    for coord in real_corners:
        if coord != key:
            for poss in pboard[coord[0]][coord[1]]:
                display.append((coord, poss, "set1"))
    for poss in pboard[key[0]][key[1]]:
        display.append((key, poss, "set2"))
    first_entry = True
    for number_info in things_to_trim:
        for coord in number_info[1]:
            y, x = coord[0], coord[1]
            pboard[y][x].remove(number_info[0])
            if first_entry:
                first_entry = False
                GAMESTEPS[0] += 1
                display.append((coord, number_info[0], "remove"))
            else:
                display = [(coord, number_info[0], "remove")]
            msg = " because its seen by all members of the hinged " + x_length_lookup[x_length]
            display_msg = "Removed " + str(number_info[0]) + msg
            support.update_gamestepslog('pboard', 'remove', coord, number_info[0], display_msg, False, display)
示例#3
0
def locked_pairs(board, pboard):
    for number in NUMBERS:
        for xtype in range(2):
            # look for 2 binary pairs
            pairs = []
            for line in LINES[xtype]:
                pair = find_binary_pair(pboard, line, xtype, number)
                if pair:
                    pairs.append(pair)
            # enumerate every possible combination of 2 pairs (if you find 3 binary pairs there are 3 possible squares)
            combopairs = return_pair_combos(pairs)
            if combopairs:
                for combo in combopairs:
                    #log(0, "checking combo" + str(combo))
                    altpairs, alt_xtype = rotate(combo, xtype)
                    if check_if_square(pboard, altpairs, alt_xtype):
                        trimmed = []
                        for altpair in altpairs:
                            trimmed += trim_alt_line_in_square(pboard, altpair, alt_xtype, number)
                        if trimmed:
                            GAMESTEPS[0] += 1
                            locked_pairs = [cflip(combo[0][0]), cflip(combo[0][1]), cflip(combo[1][0]), cflip(combo[1][1]),]
                            msg = "Removed " + str(number) + " because of the locked pairs at " + str(locked_pairs)[1:-1]
                            display = [(combo[0][0], number, "set1"), (combo[0][1], number, "set1"), (combo[1][0], number, "set1"), (combo[1][1], number, "set1")]
                            # fill in the rest of the reporting details laters
                            for coord in trimmed:
                                otl = list(display)
                                otl.append((coord, number, "remove"))
                                support.update_gamestepslog('pboard', 'remove', coord, number, msg, False, otl)
                            return True
    return False
示例#4
0
def solve_singles(board, pboard):
    lone = look_for_lone_ptable_entries(pboard)
    if lone[0]:
        for value in lone[1]:
            msg = "possibility table at " + str(cflip(value[0])) + " has only a single entry which is the number " + str(value[1])
            support.update_gamestepslog("board", "add", value[0], value[1], msg, True)
            support.oo_update_actions(value[0], value[1], board, pboard)
        return True
    return False
示例#5
0
def report(pboard, key, corner1, corner2, trimmed_list, alt):
    msg = "Removed " + str(alt) + " due to corner intersection at the corners " + str(cflip(corner1)) + ", " + str(cflip(corner2)) + " and the key " + str(cflip(key))
    GAMESTEPS[0] += 1
    y, x = key[0], key[1]
    num1, num2 = pboard[y][x][0], pboard[y][x][1]
    display = [(key, num1, 'set1'), (key, num2, 'set1'), (corner1, num1, 'set1'), (corner2, num2, 'set1'), (corner1, alt, 'set2'), (corner2, alt, 'set2'),]
    for coord in trimmed_list:
        otl = list(display)
        otl.append((coord, alt, "remove"))
        support.update_gamestepslog('pboard', 'remove', coord, alt, msg, False, otl)
示例#6
0
def trim_cleanup(list_of_trims, chain_display, msg, any_trim, y, x):
    if not any_trim:
        GAMESTEPS[0] += 1
        any_trim = True
    for removed_number in list_of_trims:
        trimme_msg = "trimmed " + str(removed_number) + msg
        onetimelist = chain_display[:]
        onetimelist.append(((y, x), removed_number, 'remove'))
        support.update_gamestepslog('pboard', 'remove', (y, x), removed_number, trimme_msg, False, onetimelist)
    return any_trim
示例#7
0
def trim_naked_matches(pboard, trim_type, x_length):
    trim_type_lookup = {
        0: "row",
        1: "column",
        2: "square",
    }
    x_lenth_lookup = {2: "pair", 3: "triplicate"}
    any_trim = False
    results = naked_matches(pboard, trim_type, x_length)
    if results[0]:
        for result in results[1]:
            dedup = False
            matched, line = result[0], result[1]
            matched_nums = []
            m_c = matched[0]
            for num in pboard[m_c[0]][m_c[1]]:
                matched_nums.append(num)
            coordinates = get_coord_list(line, trim_type)
            # replace with my extra check set of coords
            coordinates = extra_check(
                coordinates,
                matched,
                trim_type,
            )
            for number in matched_nums:
                for c in coordinates:
                    if c not in matched:
                        if number in pboard[c[0]][c[1]]:
                            any_trim = True
                            pboard[c[0]][c[1]].remove(number)
                            #print "removed", number, "from", c
                            c_list = ''
                            for e in matched:
                                c_list += str(cflip(e)) + ' '
                            msg = "Trimmed " + str(
                                number) + " due to naked " + x_lenth_lookup[
                                    x_length] + " at " + c_list
                            displaystuff = []
                            for numbers in matched_nums:
                                displaystuff.append(
                                    (matched[0], numbers, "set1"))
                                displaystuff.append(
                                    (matched[1], numbers, "set1"))
                            displaystuff.append((c, number, "remove"))
                            if dedup:
                                support.update_gamestepslog(
                                    'pboard', 'remove', c, number, msg, False,
                                    displaystuff)
                            else:
                                support.update_gamestepslog(
                                    'pboard', 'remove', c, number, msg, True,
                                    displaystuff)
                            dedup = True
    return any_trim
示例#8
0
def solve_single_possible(board, pboard):
    placed = False
    type_x_lookup = {0:"row", 1:"column", 2:"square"}
    possible = look_for_single_poss_numbers(pboard)
    if possible[0]:
        for value in possible[1]:
            msg = "the number " + str(value[1]) + " showed up only once in the possibility table for its " + str(type_x_lookup[value[2]])
            support.update_gamestepslog(b_type="board", func="add", coord=value[0], num=value[1], msg=msg, step_up=True)
            support.oo_update_actions(value[0], value[1], board, pboard)
        placed = True
    return placed
示例#9
0
def solve_singles(board, pboard):
    lone = look_for_lone_ptable_entries(pboard)
    if lone[0]:
        for value in lone[1]:
            msg = "possibility table at " + str(
                cflip(value[0])
            ) + " has only a single entry which is the number " + str(value[1])
            support.update_gamestepslog("board", "add", value[0], value[1],
                                        msg, True)
            support.oo_update_actions(value[0], value[1], board, pboard)
        return True
    return False
示例#10
0
def trim_ptable_from_chains(pboard, number, type):
    any_trim = False
    if type == "simple":
        chained = find_all_simple_chain(pboard, number)
    if type == "complex":
        chained = find_chain_board(pboard, number)
    if chained[0]:
        for chain in chained[1]:
            alist, blist = chain[0], chain[1]
            display = []
            for coord in alist:
                display.append((coord, number, 'set1'))
            for coord in blist:
                display.append((coord, number, 'set2'))
            invalid = invalid_chain_board(alist, blist)
            displayed = False
            if invalid[0]:
                any_trim = True
                GAMESTEPS[0] += 1
                msg = "Invalid binary chain"
                for c in invalid[1]:
                    onetimelist = [(c, number, 'remove')]
                    display.extend(onetimelist)
                    pboard[c[0]][c[1]].remove(number)
                    support.update_gamestepslog('pboard', 'remove', c, number,
                                                msg, False, display)
            excess = find_excess_chain_board(pboard, alist, blist, number)
            excess_trimmed = False
            if len(excess) > 0:
                for c in excess:
                    pboard[c[0]][c[1]].remove(number)
                    excess_trimmed = True
            if excess_trimmed:
                any_trim = True
                msg = "Trimmed excess " + str(
                    number) + " that isnt in the binary chains"
                GAMESTEPS[0] += 1
                for coord in excess:
                    onetimelist = display[:]
                    onetimelist.append((coord, number, 'remove'))
                    support.update_gamestepslog('pboard', 'remove', coord,
                                                number, msg, False,
                                                onetimelist)
            # If a trime was done stop looping and return true
            if any_trim:
                return any_trim
    # No chain found, no trim is possible
    else:
        return False
示例#11
0
def trim_cleanup(pboard, matched_coords, trimmed_list):
    first_entry = True
    display = []
    for coord in matched_coords:
        y, x = coord[0], coord[1]
        for num in pboard[y][x]:
            display.append((coord, num, "set1"))
    for entry in trimmed_list:
        if first_entry:
            first_entry = False
            GAMESTEPS[0] += 1
            display.append((entry[0], entry[1], "remove"))
        else:
            display = [(entry[0], entry[1], "remove")]
        msg = "Removed " + str(entry[1]) + " because its sees a naked triplicate"
        support.update_gamestepslog('pboard', 'remove', entry[0], entry[1], msg, False, display)
示例#12
0
def gridtacular(pboard, x_length):
    ''' Solves for variable size grids returns a boolean indicating work done '''
    for number in NUMBERS:
        for x_type in range(2):
            data_array = []
            # Each line should contain between 1 and x_length of my number to be considered
            for line in LINES[x_type]:
                potential_line = []
                coords = get_coord_list(line, x_type)
                for coord in coords:
                    y, x = coord[0], coord[1]
                    if number in pboard[y][x]:
                        potential_line.append(coord)
                if len(potential_line) > 0:
                    if len(potential_line) <= x_length:
                        data_array.append(list(potential_line))
            # I need at least my x_length worth of lines to attempt to make a grid
            if len(data_array) >= x_length:
                possible_combinations = create_set_iterable(
                    x_length, len(data_array))
                for combination in possible_combinations:
                    grid_info = is_a_grid(data_array, combination, x_type)
                    if grid_info:
                        trimmed = trim_grid(pboard, number, grid_info, x_type)
                        if trimmed:
                            GAMESTEPS[0] += 1
                            msg = "Removed " + str(
                                number
                            ) + " as its seen by the " + trim_type_lookup[
                                x_type] + " based grid"
                            display = []
                            for grid_coord in grid_info[0]:
                                display.append((grid_coord, number, "set1"))
                            for coord in trimmed:
                                otl = list(display)
                                otl.append((coord, number, "remove"))
                                support.update_gamestepslog(
                                    'pboard', 'remove', coord, number, msg,
                                    False, otl)
                            # Stop looping completely, because there was something to trim
                            return True
                    else:
                        continue
    # Nothing at all found, im done
    return False
示例#13
0
def trim_ptable_from_chains(pboard, number, type):
    any_trim = False
    if type == "simple":
        chained = find_all_simple_chain(pboard, number)
    if type == "complex":
        chained = find_chain_board(pboard, number)
    if chained[0]:
        for chain in chained[1]:
            alist, blist = chain[0], chain[1]
            display = []
            for coord in alist:
                display.append((coord, number, 'set1'))
            for coord in blist:
                display.append((coord, number, 'set2'))
            invalid = invalid_chain_board(alist, blist)
            displayed = False
            if invalid[0]:
                any_trim = True
                GAMESTEPS[0] += 1
                msg = "Invalid binary chain"
                for c in invalid[1]:
                    onetimelist = [(c, number, 'remove')]
                    display.extend(onetimelist)
                    pboard[c[0]][c[1]].remove(number)
                    support.update_gamestepslog('pboard', 'remove', c, number, msg, False, display)
            excess = find_excess_chain_board(pboard, alist, blist, number)
            excess_trimmed = False
            if len(excess) > 0:
                for c in excess:
                    pboard[c[0]][c[1]].remove(number)
                    excess_trimmed = True
            if excess_trimmed:
                any_trim = True
                msg = "Trimmed excess " + str(number) + " that isnt in the binary chains"
                GAMESTEPS[0] += 1
                for coord in excess:
                    onetimelist = display[:]
                    onetimelist.append((coord, number, 'remove'))
                    support.update_gamestepslog('pboard', 'remove', coord, number, msg, False, onetimelist)
            # If a trime was done stop looping and return true
            if any_trim:
                return any_trim
    # No chain found, no trim is possible
    else:
        return False
示例#14
0
def locked_pairs(board, pboard):
    for number in NUMBERS:
        for xtype in range(2):
            # look for 2 binary pairs
            pairs = []
            for line in LINES[xtype]:
                pair = find_binary_pair(pboard, line, xtype, number)
                if pair:
                    pairs.append(pair)
            # enumerate every possible combination of 2 pairs (if you find 3 binary pairs there are 3 possible squares)
            combopairs = return_pair_combos(pairs)
            if combopairs:
                for combo in combopairs:
                    #log(0, "checking combo" + str(combo))
                    altpairs, alt_xtype = rotate(combo, xtype)
                    if check_if_square(pboard, altpairs, alt_xtype):
                        trimmed = []
                        for altpair in altpairs:
                            trimmed += trim_alt_line_in_square(
                                pboard, altpair, alt_xtype, number)
                        if trimmed:
                            GAMESTEPS[0] += 1
                            locked_pairs = [
                                cflip(combo[0][0]),
                                cflip(combo[0][1]),
                                cflip(combo[1][0]),
                                cflip(combo[1][1]),
                            ]
                            msg = "Removed " + str(
                                number
                            ) + " because of the locked pairs at " + str(
                                locked_pairs)[1:-1]
                            display = [(combo[0][0], number, "set1"),
                                       (combo[0][1], number, "set1"),
                                       (combo[1][0], number, "set1"),
                                       (combo[1][1], number, "set1")]
                            # fill in the rest of the reporting details laters
                            for coord in trimmed:
                                otl = list(display)
                                otl.append((coord, number, "remove"))
                                support.update_gamestepslog(
                                    'pboard', 'remove', coord, number, msg,
                                    False, otl)
                            return True
    return False
示例#15
0
def trim_cleanup(pboard, matched_coords, match_nums, trimmed_list, msg):
    first_entry = True
    display = []
    for coord in matched_coords:
        y, x = coord[0], coord[1]
        for num in pboard[y][x]:
            if num in match_nums:
                display.append((coord, num, "set1"))
    for entry in trimmed_list:
        if first_entry:
            first_entry = False
            GAMESTEPS[0] += 1
            display.append((entry[0], entry[1], "remove"))
        else:
            display = [(entry[0], entry[1], "remove")]
        display_msg = "Removed " + str(entry[1]) + msg
        support.update_gamestepslog('pboard', 'remove', entry[0], entry[1],
                                    display_msg, False, display)
示例#16
0
def trim_cleanup(pboard, key, corners, match_nums, trimmed_list, msg):
    first_entry = True
    display = []
    for num in match_nums:
        display.append((key, num, "set1"))
    for corner in corners:
        y, x = corner[0], corner[1]
        for num in pboard[y][x]:
            if num in match_nums:
                display.append((corner, num, "set1"))
    for entry in trimmed_list:
        if first_entry:
            first_entry = False
            GAMESTEPS[0] += 1
            display.append((entry[0], entry[1], "remove"))
        else:
            display = [(entry[0], entry[1], "remove")]
        display_msg = "Removed " + str(entry[1]) + msg
        support.update_gamestepslog('pboard', 'remove', entry[0], entry[1], display_msg, False, display)
示例#17
0
def report(pboard, key, corner1, corner2, trimmed_list, alt):
    msg = "Removed " + str(
        alt) + " due to corner intersection at the corners " + str(
            cflip(corner1)) + ", " + str(
                cflip(corner2)) + " and the key " + str(cflip(key))
    GAMESTEPS[0] += 1
    y, x = key[0], key[1]
    num1, num2 = pboard[y][x][0], pboard[y][x][1]
    display = [
        (key, num1, 'set1'),
        (key, num2, 'set1'),
        (corner1, num1, 'set1'),
        (corner2, num2, 'set1'),
        (corner1, alt, 'set2'),
        (corner2, alt, 'set2'),
    ]
    for coord in trimmed_list:
        otl = list(display)
        otl.append((coord, alt, "remove"))
        support.update_gamestepslog('pboard', 'remove', coord, alt, msg, False,
                                    otl)
示例#18
0
def gridtacular(pboard, x_length):
    ''' Solves for variable size grids returns a boolean indicating work done '''
    for number in NUMBERS:
        for x_type in range(2):
            data_array = []
            # Each line should contain between 1 and x_length of my number to be considered
            for line in LINES[x_type]:
                potential_line = []
                coords = get_coord_list(line, x_type)
                for coord in coords:
                    y, x = coord[0], coord[1]
                    if number in pboard[y][x]:
                        potential_line.append(coord)
                if len(potential_line) > 0:
                    if len(potential_line) <= x_length:
                        data_array.append(list(potential_line))
            # I need at least my x_length worth of lines to attempt to make a grid
            if len(data_array) >= x_length:
                possible_combinations = create_set_iterable(x_length, len(data_array))
                for combination in possible_combinations:
                    grid_info = is_a_grid(data_array, combination, x_type)
                    if grid_info:
                        trimmed = trim_grid(pboard, number, grid_info, x_type)
                        if trimmed:
                            GAMESTEPS[0] += 1
                            msg = "Removed " + str(number) + " as its seen by the " + trim_type_lookup[x_type] + " based grid"
                            display = []
                            for grid_coord in grid_info[0]:
                                display.append((grid_coord, number, "set1"))
                            for coord in trimmed:
                                otl = list(display)
                                otl.append((coord, number, "remove"))
                                support.update_gamestepslog('pboard', 'remove', coord, number, msg, False, otl)
                            # Stop looping completely, because there was something to trim
                            return True
                    else:
                        continue
    # Nothing at all found, im done
    return False
示例#19
0
def trim_naked_matches(pboard, trim_type, x_length):
    trim_type_lookup = {0:"row", 1:"column", 2:"square",}
    x_lenth_lookup = { 2:"pair", 3:"triplicate"}
    any_trim = False
    results = naked_matches(pboard, trim_type, x_length)
    if results[0]:
        for result in results[1]:
            dedup = False
            matched, line = result[0], result[1]
            matched_nums = []
            m_c = matched[0]
            for num in pboard[m_c[0]][m_c[1]]:
                matched_nums.append(num)
            coordinates = get_coord_list(line, trim_type)
            # replace with my extra check set of coords
            coordinates = extra_check(coordinates, matched, trim_type,)
            for number in matched_nums:
                for c in coordinates:
                    if c not in matched:
                        if number in pboard[c[0]][c[1]]:
                            any_trim = True
                            pboard[c[0]][c[1]].remove(number)
                            #print "removed", number, "from", c
                            c_list = ''
                            for e in matched:
                                c_list += str(cflip(e)) + ' '
                            msg = "Trimmed " + str(number) + " due to naked " + x_lenth_lookup[x_length] + " at " + c_list
                            displaystuff = []
                            for numbers in matched_nums:
                                displaystuff.append((matched[0], numbers, "set1"))
                                displaystuff.append((matched[1], numbers, "set1"))
                            displaystuff.append((c, number, "remove"))
                            if dedup:
                                support.update_gamestepslog('pboard', 'remove', c, number, msg, False, displaystuff)
                            else:
                                support.update_gamestepslog('pboard', 'remove', c, number, msg, True, displaystuff)
                            dedup = True
    return any_trim
示例#20
0
def trim_ptable_for_num_in_line(pboard, trim_type):
    ''' Looks for a number appearing only in a line in a single square '''
    trim_type_lookup = { 0:"row", 1:"column"}
    any_trim = False
    for square in SQUARES:
        coords = get_coord_list(square, 2)
        if trim_type == 0:
            # take first (upper left cell) coord and iterate off Y
            iterate_base = coords[0][0]
        if trim_type == 1:
            # take first (upper left cell) coord and iterate off X
            iterate_base = coords[0][1]
        # look through all three rows/columns, no more no less
        for i in range(3):
            # iterate_base is the current row/column number
            iterate_now = i + iterate_base
            current_set = set()
            rest_of_line_set = set()
            rest_of_square_set = set()
            current_line = []
            rest_of_line = []
            rest_of_square = []
            for coord in coords:
                if trim_type == 0:
                    comparison = coord[0]
                if trim_type == 1:
                    comparison = coord[1]
                if comparison == iterate_now:
                    # can update whole line except if in my square... ie current_line
                    current_line.append(coord)
                    for element in pboard[coord[0]][coord[1]]:
                        current_set.add(element)
                else:
                    rest_of_square.append(coord)
                    for element in pboard[coord[0]][coord[1]]:
                        rest_of_square_set.add(element)
            # check for a number existing only in the currentset
            uniqueset = current_set - rest_of_square_set
            
            # get row/column coord list
            line_list = get_coord_list(current_line[0], trim_type)
            for coord in line_list:
                if coord not in current_line:
                    rest_of_line.append(coord)
                    for element in pboard[coord[0]][coord[1]]:
                        rest_of_line_set.add(element)
            if len(uniqueset) >= 1:
                for u_num in uniqueset:
                    #log(0,uniqueset)
                    #log(0, str(square) + " square")
                    # clear the number from the rest of the line
                    uniquenum = u_num
                    # clean the rest of the line
                    first_trim = True
                    for coord in line_list:
                        if coord not in current_line:
                            if uniquenum in pboard[coord[0]][coord[1]]:
                                msg = "trimmed " + str(uniquenum) + " because it has to be in " + trim_type_lookup[trim_type] + " " + str(iterate_now + 1) + " in square " + str(square + 1)
                                display = [(coord, uniquenum, 'remove'), ]
                                for entry in current_line:
                                    display.append((entry, uniquenum, 'set1'))
                                if first_trim:
                                    any_trim = True
                                    support.update_gamestepslog('pboard', 'remove', coord, uniquenum, msg, True, display)
                                    first_trim = False
                                else:
                                    support.update_gamestepslog('pboard', 'remove', coord, uniquenum, msg, False, display)
                                pboard[coord[0]][coord[1]].remove(uniquenum)
                    # only update 1 number
                    if any_trim:
                        return True
            # checking for requirement to "only" be in a certain row/column
            for i in range(len(current_set)):
                numtoeval = current_set.pop()
                if numtoeval not in rest_of_line_set:
                    if numtoeval in rest_of_square_set:
                        first_trim = True
                        for coord in rest_of_square:
                            if numtoeval in pboard[coord[0]][coord[1]]:
                                msg = "trimmed " + str(numtoeval) + " because in square " + str(square + 1) + " the number can only be in " + trim_type_lookup[trim_type] + " " + str(iterate_now + 1) 
                                display = [(coord, numtoeval, 'remove')]
                                for entry in current_line:
                                    display.append((entry, numtoeval, 'set1'))
                                if first_trim:
                                    any_trim = True
                                    support.update_gamestepslog('pboard', 'remove', coord, numtoeval, msg, True, display)
                                    first_trim = False
                                else:
                                    support.update_gamestepslog('pboard', 'remove', coord, numtoeval, msg, False, display)
                                pboard[coord[0]][coord[1]].remove(numtoeval)
    return any_trim