Use depth-first search DFS solving star battle game

  Here the star battle game does not mean anything else (like war frame), is a puzzle team club out of the game, in https://www.puzzle-star-battle.com/ can be found inside.

  Here to solving the case, can not be like last time, as with table dancing (dancing link), because the rules of the game determines the position occupied by the box is not to be used for all, a box may be adjacent one or two stars, not as before, the practice of using accurate coverage. However, there is still very simple to solve problems, a certain kind of constraints (in the line must be exactly n stars) you can use this to engage in DFS.

  star battle of the rules are as follows: placing a certain number of stars in the board so that all of the stars near 8 grid no stars, and each row, each column, each region exactly specified number of stars, as is the number to specify the number of stars ★ which number is left

  

 

 

 FIG 1.1 ★ represents per row and there must be exactly one of each star; 3 ★ is exactly 3

  Here it is necessary to initialize the number of stars per row and each occupied by a specified number (here, the depth-first search parameter is the number of lines, also based on one-way search operation, each row is omitted occupied by the number of stars)

def init():
    with open('starBattleChess1.txt','r') as f:
        chessStr = f.read()
    rowStrs = chessStr.split('\n')
    global rowsize, colsize
    rowsize = len (rowStrs)
    colsize = len(rowStrs[0].split(' '))
    maxnum = 0
    for rowStr in rowStrs:
        row = []
        validrow = []
        for j in range(2):
            Occupy [J] .append (limit) # 0 per column, each is 1 
        for J in Range (limit):
            answer.append([])
        for colStr in rowStr.split(' '):
            maxnum = maxnum if int(colStr) < maxnum else int(colStr)
            row.append(int(colStr))
            validrow.append(1)
        chess.append(row)
        valid.append(validrow)
View Code

  Depth first search section (search on lateral single line), part of the answer with a riddle length * limited to the size of the array storage length. Here occupy the other side of the grid to eliminate (remove) and restore (resume) operation using similar operating table dance

def dfs(depth, occ, start):
    #print('depth : ' + str(depth) + ' occ : ' + str(occ) + ' start : ' + str(start))
    if depth == rowsize:
        print(answer)
        printAnswer()
        return
    for i in range(start, colsize-limit+occ+1):
        if occupy[0][i] <= 0 or occupy[1][chess[depth][i]] <= 0 or valid[depth][i] == 0:
            continue
        resumePos = []
        occupy[0][i] -= 1
        occupy[1][chess[depth][i]] -= 1
        for j in range(depth-1, depth+2):
            for k in range(i-1, i+2):
                if j < 0 or j > rowsize - 1:continue
                if k < 0 or k > rowsize - 1:continue
                if valid[j][k] != 0:
                    valid[j][k] = 0
                    resumePos.append([j, k])
        answer[depth * limit + occ] = [depth, i]
        if occ >= limit - 1:
            dfs(depth+1, 0, 0)
        else:
            dfs(depth, occ+1, i+1)
        for resume in resumePos:
            valid[resume[0]][resume[1]] = 1
        occupy[0][i] += 1
        occupy[1][chess[depth][i]] += 1
View Code

  Output answer:

def printAnswer():
    defaultImg = ['+','|']
    for _ in range(rowsize):
        defaultImg[0] += '-+'
        defaultImg[1] += ' |'
    imgs = [defaultImg[0]]
    for i in range(rowsize):
        imgs.append(defaultImg[1])
        imgs.append(defaultImg[0])
    for ans in answer:
        a = years [0]
        b = years [1 ]
        imgs[2*a+1] = imgs[2*a+1][:2*b+1] + '*' + imgs[2*a+1][2*b+2:]
    print(reduce(lambda a,b:a+'\n'+b,imgs))
View Code

  Total code:

from functools import reduce
import time
chess = []
rowsize = 0
colsize = 0
limit = 2 # stars ★ what is left to fill in which digital 
! Valid = []
occupy = [[],[]]# 0 is vertical; 1 is block
answer = []
#
def printAnswer():
    defaultImg = ['+','|']
    for _ in range(rowsize):
        defaultImg[0] += '-+'
        defaultImg[1] += ' |'
    imgs = [defaultImg[0]]
    for i in range(rowsize):
        imgs.append(defaultImg[1])
        imgs.append(defaultImg[0])
    for ans in answer:
        a = years [0]
        b = years [1 ]
        imgs[2*a+1] = imgs[2*a+1][:2*b+1] + '*' + imgs[2*a+1][2*b+2:]
    print(reduce(lambda a,b:a+'\n'+b,imgs))
#
def dfs(depth, occ, start):
    #print('depth : ' + str(depth) + ' occ : ' + str(occ) + ' start : ' + str(start))
    if depth == rowsize:
        print(answer)
        printAnswer()
        return
    for i in range(start, colsize-limit+occ+1):
        if occupy[0][i] <= 0 or occupy[1][chess[depth][i]] <= 0 or valid[depth][i] == 0:
            continue
        resumePos = []
        occupy[0][i] -= 1
        occupy[1][chess[depth][i]] -= 1
        for j in range(depth-1, depth+2):
            for k in range(i-1, i+2):
                if j < 0 or j > rowsize - 1:continue
                if k < 0 or k > rowsize - 1:continue
                if valid[j][k] != 0:
                    valid[j][k] = 0
                    resumePos.append([j, k])
        answer[depth * limit + occ] = [depth, i]
        if occ >= limit - 1:
            dfs(depth+1, 0, 0)
        else:
            dfs(depth, occ+1, i+1)
        for resume in resumePos:
            valid[resume[0]][resume[1]] = 1
        occupy[0][i] += 1
        occupy[1][chess[depth][i]] += 1
#
def init():
    with open('starBattleChess1.txt','r') as f:
        chessStr = f.read()
    rowStrs = chessStr.split('\n')
    global rowsize, colsize
    rowsize = len (rowStrs)
    colsize = len(rowStrs[0].split(' '))
    maxnum = 0
    for rowStr in rowStrs:
        row = []
        validrow = []
        for j in range(2):
            occupy[j].append(limit)
        for j in range(limit):
            answer.append([])
        for colStr in rowStr.split(' '):
            maxnum = maxnum if int(colStr) < maxnum else int(colStr)
            row.append(int(colStr))
            validrow.append(1)
        chess.append(row)
        valid.append(validrow)

if __name__ == "__main__":
    init()
    start = time.time()
    dfs(0, 0, 0)
    end = time.time()
    print('search time : ' + str(end-start) + 's')
View Code

  We create starBattleChess1.txt file in the same directory, and enter the board:

0 1 1 1 1 1 2 2 2 2
0 0 0 3 3 1 4 4 2 2
0 0 0 3 3 3 4 4 2 2
0 5 4 4 4 4 4 4 2 2
0 5 4 6 6 6 6 6 2 2
5 5 5 6 6 6 6 6 6 2
5 5 5 5 5 5 7 7 7 7
5 5 5 5 8 5 7 7 7 7
5 9 9 8 8 8 8 7 7 7
9 9 8 8 8 8 8 7 7 7
View Code

  Results of the:

[[0, 3], [0, 5], [1, 1], [1, 8], [2, 3], [2, 5], [3, 7], [3, 9], [4, 0], [4, 2],
 [5, 6], [5, 8], [6, 1], [6, 4], [7, 7], [7, 9], [8, 2], [8, 4], [9, 0], [9, 6]]

+-+-+-+-+-+-+-+-+-+-+
| | | |*| |*| | | | |
+-+-+-+-+-+-+-+-+-+-+
| |*| | | | | | |*| |
+-+-+-+-+-+-+-+-+-+-+
| | | |*| |*| | | | |
+-+-+-+-+-+-+-+-+-+-+
| | | | | | | |*| |*|
+-+-+-+-+-+-+-+-+-+-+
|*| |*| | | | | | | |
+-+-+-+-+-+-+-+-+-+-+
| | | | | | |*| |*| |
+-+-+-+-+-+-+-+-+-+-+
| |*| | |*| | | | | |
+-+-+-+-+-+-+-+-+-+-+
| | | | | | | |*| |*|
+-+-+-+-+-+-+-+-+-+-+
| | |*| |*| | | | | |
+-+-+-+-+-+-+-+-+-+-+
|*| | | | | |*| | | |
+-+-+-+-+-+-+-+-+-+-+
search time : 0.9020516872406006s

  This algorithm is still room for optimization. Since the board of this site is the only solution, it is certainly the only way you can find out the found solution. Talk about this later.

  The answer to this entry page:

 

Figure 2. Do not Tucao Why such a long time, three days before it opened and pulled out

  Hey, you're done!

  When the solution of this question, please discard the conventional solution of 1 star of the board, more consideration from the perspective of many stars. Before I write the code to put the final answer written in the habit of storing 1 star, the answer is only half the results. . .

Guess you like

Origin www.cnblogs.com/dgutfly/p/11961079.html