Exemple #1
0
def test_decide_next_step():
    cb = ChessBoard(WIDTH, HEIGHT, ROW_NUM)
    tiles = Tiles(cb)
    gm = GameManager(cb, tiles)
    y, x = gm.decide_next_step()

    assert y == 2 and x == 4
Exemple #2
0
    def __init__(self):
        QMainWindow.__init__(self)

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.graphicsView.setMouseTracking(True)
        self.filter = Filter()
        #self.ui.graphicsView.installEventFilter(self.filter)
        self.installEventFilter(self.filter)
        #### Black and White

        self.setCursor(Qt.PointingHandCursor)
        self.mouse_point = LaBel(self)  # 将鼠标图片改为棋子
        self.mouse_point.setScaledContents(True)
        self.mouse_point.setPixmap(
            self.ui.graphicsView.black)  # Black chess piece, human always hold
        self.mouse_point.setGeometry(270, 270, PIECE, PIECE)

        # settings for the mouse
        self.mouse_point.raise_()
        self.setMouseTracking(True)
        self.AI_down = True

        self.chess_board = ChessBoard()
        self.pieces = [LaBel(self) for i in range(361)
                       ]  # All the chess pieces , 19*19 chess board

        for piece in self.pieces:
            piece.setVisible(True)  # Set Picture Visible
            piece.setScaledContents(True)  #
    def order_moves_by_warnsdorff_tuples(self, board, move_tuples):
        """ Order moves by Warnsdorff algorithm (minimum neighbors) one level
        :board: current board
        :move_tuples: sorted list of 3-tuples
                        (number-of follow-on moves,
                        move,
                        list of this move's follow-on
                        )
        :returns: list with moves of decreasing number of follow-on's folow-on moves
                    of 3-tuples (number-of follow-on folow-on's moves,
                                 move,
                                 list of this move's follow-on's follow-ons
                                 )
        """
        ffon_tuples = [
        ]  # list of (follow-on's follow-on cnt, move, ffon_list)
        for move_tuple in move_tuples:
            follow_ons = move_tuple[2]
            follow_board = ChessBoard(board)
            follow_board.set_piece('N', move_tuple[1])
            follow_on_tuples = self.order_moves_by_warnsdorff_1(
                follow_board, follow_ons)
            ffon_moves = []
            for follow_on_tuple in follow_on_tuples:
                ffon_moves.extend(follow_on_tuple[2])
            ffon_tuples.append((len(ffon_moves), move_tuple[1], ffon_moves))

        ffon_tuples_sorted = sorted(ffon_tuples, key=by_first)
        return ffon_tuples_sorted
Exemple #4
0
def test_constructor():
    cb = ChessBoard(WIDTH, HEIGHT, ROW_NUM)
    tile = Tile(cb, 'black')
    assert tile.color == 'black'
    assert tile.CLEARANCE == 10
    assert tile.width == 90
    assert tile.height == 90
Exemple #5
0
def test_constructor():
    cb = ChessBoard(WIDTH, HEIGHT, ROW_NUM)
    tiles = Tiles(cb)
    gm = GameManager(cb, tiles)

    assert gm.black_turn == True
    assert gm.WIDTH == 800
    assert gm.HEIGHT == 800

    for y in range(ROW_NUM):
        for x in range(ROW_NUM):
            if y == 3 and x == 3:
                assert gm.tile_list[y][x].color == 'white'
            elif y == 4 and x == 4:
                assert gm.tile_list[y][x].color == 'white'
            elif y == 4 and x == 3:
                assert gm.tile_list[y][x].color == 'black'
            elif y == 3 and x == 4:
                assert gm.tile_list[y][x].color == 'black'
            else:
                assert gm.tile_list[y][x] == None

    assert gm.black_count == 2
    assert gm.white_count == 2
    assert gm.X_ADD == [0, 1, -1, 0, 1, -1, 1, -1]
    assert gm.Y_ADD == [1, 0, 0, -1, 1, -1, -1, 1]
    assert gm.has_input_name == False
    assert gm.TIME_DURATION == 1500
    assert gm.FILE_NAME == 'scores.txt'
 def __init__(self,
              locs=None,
              ncol=None,
              nrow=None,
              piece=None,
              closed_tours=True):
     """ Set up validation constraints on which validation is made
     :locs: squares for which possible tour default ncolxnrow
     :ncol: number of columns default: nrow if nrow is not None else 8
     :nrow: number of rows default: ncol if ncol is not None else 8
     :piece: Chess piece letter e.g. 'K' for black king default: 'N' - black knight
     :closed_tours: Check for closed tour (ending square is one piece move from start)
                     default: True
     """
     if ncol is None:
         ncol = 8 if nrow is None else nrow
     self.ncol = ncol
     if nrow is None:
         nrow = 8 if ncol is None else ncol
     self.nrow = nrow
     if locs is None:
         locs = []
         for ic in range(ncol):
             for ir in range(nrow):
                 locs.append((ic, ir))
     self.locs = locs
     if piece is None:
         piece = 'N'
     self.piece = piece
     self.closed_tours = closed_tours
     self.cb = ChessBoard(ncol=self.ncol,
                          nrow=self.nrow)  # For acces to basic fns
Exemple #7
0
 def __init__(self, path_starts=None, arrange=None,
              time_out=None,
              closed_tours=None,
              display_move=False,
              pW=None,
              move_time=.5,
              width=400,
              height=400,
              nrow = 8,
              ncol = 8,
              max_look_ahead=5):
     self.display_move = display_move
     self.pW = pW
     self.move_time = move_time
     self.width = width
     self.height = height
     self.nrow = nrow
     self.ncol = ncol
     self.board = ChessBoard(ncol=ncol, nrow=nrow)
     self.len_ckt = nrow*ncol
     if display_move:
         time_out = None             # Disable time_out if displaying moves
     self.time_out = time_out
     self.path_starts = path_starts
     self.closed_tours = closed_tours
     self.max_look_ahead = max_look_ahead
     self.arrange = arrange
     self.sqno = 0        # number within list
     self.displayed_paths = []   # Repository of displayed paths
     self.kpths = None           # Current path, if any
     self.ipstart = 0            # current start loc index
Exemple #8
0
def test_get_legal_move_list():
    cb = ChessBoard(WIDTH, HEIGHT, ROW_NUM)
    tiles = Tiles(cb)
    gm = GameManager(cb, tiles)

    white_move_list = gm.get_legal_move_list('black')

    assert white_move_list == {(2, 3): 1, (3, 2): 1, (4, 5): 1, (5, 4): 1}
Exemple #9
0
def test_black_make_move():
    cb = ChessBoard(WIDTH, HEIGHT, ROW_NUM)
    tiles = Tiles(cb)
    gm = GameManager(cb, tiles)

    gm.black_make_move(324, 234)
    assert gm.tile_list[2][3].color == 'black'
    assert gm.black_count == 4
Exemple #10
0
def test_white_make_move():
    cb = ChessBoard(WIDTH, HEIGHT, ROW_NUM)
    tiles = Tiles(cb)
    gm = GameManager(cb, tiles)

    gm.white_make_move()

    assert gm.tile_list[2][4].color == 'white'
Exemple #11
0
 def __init__(self,
             frame=None, wm=None,
             desc="",
             x=None, y=None,
             width=400, height=400,     # REQUIRED, if window not expanded
             board=None,
             move_time = .5,
             path=None,
             nrow=8,
             ncol=8,
             ):
     """ Set up board display
     :frame: if one
     :wm: if one
     :desc: description if one
     :x: board x position    default: tkinter default
     :y: board y position
     :width: board width default: 400 pixels
     :height: board height default: 400 pixels
     :board: ChessBoard default: created
     :path: path to display
     :nrow: number of rows default: 8
     :ncol: number of columns default: 8
     """
     self.label_number = 0               # Number for default square labeling
     self.desc = desc
     if board is None:
         board = ChessBoard(nrow=nrow, ncol=ncol)
     self.path = path                    # Path, if associated, may be placed here
     self.board = board    
     self.width = width
     self.height = height
     if board is not None:
         nrow = board.nrow
         ncol = board.ncol
     self.nrow = nrow
     self.ncol = ncol
     if wm is None:
         wm = Tk()
     self.wm = wm
     width = int(width)
     height = int(height)
     geo = f"{width}x{height}"
     if x is not None or y is not None:
         geo += f"+{x}+{y}"
     wm.geometry(geo)
     if frame is None:
         frame = Frame(master=wm, width=width, height=height, bg="", colormap="new")
         frame.pack(fill=BOTH, expand=YES)
     self.frame = frame
     select_dots = self.create_board(frame, wm, width=width, height=height,
                       nrow=nrow, ncol=ncol)
     self.select_dots = select_dots
     self.prev_loc = None                # previous move location for path viewing
     self.move_time = move_time
     self.display_move_stack = []        # (loc, line)
     self.display_move_no = 0
    def next_move(self):
        """ Execute the next (currenly set) move, updating the path stack
        and displaying move if appropriate
        :returns: True iff at end of path search
        """
        if self.closed_tours:
            self.prune_not_closed()
        stke = self.path_stack[-1]
        next_move = stke.loc
        board = stke.board
        best_moves = stke.best_moves
        SlTrace.lg(f"best_moves = {best_moves}", "stack_build")
        if best_moves is None:
            SlTrace.lg(f"best_moves tested is None", "stack_build")
            best_moves = self.get_best_moves(board, next_move)
            SlTrace.lg(f"best_moves = {best_moves}", "stack_build")
            SlTrace.lg(f"len(best_moves)={len(best_moves)}", "stack_build")
        if len(best_moves) == 0:
            SlTrace.lg("tested as 0", "stack_build")
            self.ntry += 1
            if SlTrace.trace("no_more_moves"):
                SlTrace.lg("{:d}: No more moves at {} len_stk={:d}".format(
                    self.ntry, loc2desc(next_move), len_stk))
            if self.max_try is not None and self.ntry > self.max_try:
                SlTrace.lg("Giving up this search")
                return True

            if SlTrace.trace("no_more_moves"):
                self.display_stack_path("no_more_moves")
            if (self.last_complete_path is None
                    or len(self.path_stack) > len(self.last_complete_path)):
                self.last_complete_path = self.path_stack_path()
            if len(self.path_stack) <= self.track_level:
                self.track_level = len(self.path_stack)
                if SlTrace.trace("back_off_trace"):
                    if self.track_level > 0:
                        stke = self.path_stack[-1]
                        nxt_move, board, bst_moves = stke.loc, stke.board, stke.best_moves
                        self.board = board
                        SlTrace.lg(
                            "back_off_trace stk_len={:d} start={} at {} best_moves={}"
                            .format(self.track_level, loc2desc(self.loc_start),
                                    loc2desc(nxt_move), path_desc(bst_moves)))
                        self.display_stack_path("back_off_trace")
            self.widen_search()
            return False  # Backup
        else:
            SlTrace.lg(f"len(best_moves)={len(best_moves)} failed test for 0",
                       "stack_build")

        follow_move = best_moves.pop(0)
        stke = self.path_stack[-1]
        stke.best_moves = best_moves  # Update best moves
        new_board = ChessBoard(base_board=board)
        self.make_move(loc=follow_move, board=new_board)
        return False
Exemple #13
0
def test_in_bound():
    cb = ChessBoard(WIDTH, HEIGHT, ROW_NUM)
    tiles = Tiles(cb)
    gm = GameManager(cb, tiles)

    assert gm.in_bound(4, 4) == True
    assert gm.in_bound(1, 8) == False
    assert gm.in_bound(2, -1) == False
    assert gm.in_bound(-1, 7) == False
    assert gm.in_bound(9, 3) == False
Exemple #14
0
 def display_path(cls, path,
                  desc=None, nrow=8, ncol=8,
                  width=400, height=400):
     """ Display board with path squares labeled
     :desc: text description
     :path: list of squares in order
     returns ChssBoardDisplay of displayed board
     """
     if not hasattr(cls, 'wm'):
         cls.wm = Tk()
     wm_base = cls.wm
     wm = Toplevel(wm_base)
     wm_base.withdraw() 
     wm.geometry("%dx%d" % (width, height))
     frame = Frame(wm, width=width, height=height, bg="", colormap="new")
     frame.pack(fill=BOTH, expand=True)
     wm.title(desc) 
     
     #creation of an instance
     cb = ChessBoard(nrow=nrow, ncol=ncol)
     cbd = ChessBoardDisplay(wm=wm, frame=frame, board=cb, path=path,
                             desc=desc,
                             width=width, height=height, nrow=nrow, ncol=ncol)
     if path is None:
         SlTrace.lg("No path")
         return
         
     for loc in path:
         loc = cb.loc2tuple(loc)
         cbd.label_square(loc)
     cbd.display()
     wd = 7
     if len(path) == 0:
         return
     
     loc_start = path[0]
     sq1 = cbd.get_square(loc_start)
     cbd.draw_outline(sq1, color="green", width=wd)
     loc_end = path[-1]
     sq2 = cbd.get_square(loc_end)
     cbd.draw_outline(sq2, color="red", width=wd)
     if cb.is_neighbor(loc_end, loc_start):
         p1 = sq1.get_center()
         p2 = sq2.get_center()
         cbd.draw_line(p1,p2, color="blue", width=wd)
     prev_loc = None
     for loc in path:
         loc = cb.loc2tuple(loc)
         if prev_loc is not None:
             cbd.display_connected_moves(loc, prev_loc)
         prev_loc = loc
     wm.lift()
     cbd.update_display()
     return cbd
Exemple #15
0
def test_flip_color():
    # please comment the first line in flip_color
    # function. millis() is not a python statement that can
    # casue error in py test. it is basically a timer recording
    # time and will not effect the test result.
    cb = ChessBoard(WIDTH, HEIGHT, ROW_NUM)
    tiles = Tiles(cb)
    gm = GameManager(cb, tiles)

    gm.flip_color('white', 3, 2)
    assert gm.tile_list[3][3].color == 'black'
Exemple #16
0
 def __init__(self):
     self.board = ChessBoard(self)
     self.pieces = [Pawn(self, "white", item) for item in [i + "2" for i in "abcdefgh"]]
     self.pieces.extend([Pawn(self, "black", item) for item in [i + "7" for i in "abcdefgh"]])
     self.pieces.extend([Rook(self, "white", item) for item in ("a1", "h1")])
     self.pieces.extend([Rook(self, "black", item) for item in ("a8", "h8")])
     self.pieces.extend([Bishop(self, "white", item) for item in ("c1", "f1")])
     self.pieces.extend([Bishop(self, "black", item) for item in ("c8", "f8")])
     self.pieces.extend([Knight(self, "white", item) for item in ("b1", "g1")])
     self.pieces.extend([Knight(self, "black", item) for item in ("b8", "g8")])
     self.pieces.extend([King(self, "white", "e1"), King(self, "black", "e8"), Queen(self, "white", "d1"), Queen(self, "black", "d8")])
     self.players = []
Exemple #17
0
 def __init__(self, setup_pieces=False):
     self.board = ChessBoard()
     self.highness = None
     self.p1_king = None
     self.p2_king = None
     self.player_turn = 1
     self.other_player_turn = 2
     self.turn_counter = 0
     self.move_history = []
     self.player_1_color = "yellow"
     self.player_2_color = "magenta"
     if setup_pieces:
         self.setup_pieces()
Exemple #18
0
def solve_many_boards(seed_list, dim_each = 8, n_moves = 50,
    verbose = False, stop_each = None):
    '''Given a list of queen positioning seeds, a size for each board, and 
    a maximum number of moves to attempt before giving up, run your 
    columnwise CSP eight queens solver on each board configuration. 

    Don't hate the playa, hate the game'''
    bcount = len(seed_list)
    if bcount > 1:
        print(f"Working on {bcount} test cases...")
    for i, s in enumerate(seed_list):
        if bcount > 1:
            print(f"Case {i+1} of {bcount} (seed {s})")
        game = ChessBoard(dimension = dim_each, queen_seed = s)
        player = MinConflictColumnSolver(board_object = game, max_moves = n_moves)
        player.solve(verbose = verbose, stop_each = stop_each)
        print(player.solution_shortdoc())
        print("-" * bcount, "\n")
Exemple #19
0
def solve_puzzle():
    '''Accessing args with [] indicates a required param (we throw a 
    400-BAD REQUEST if it isn't included).

    TODO A: Should I made the Bad Request case more explicit?
    TODO B: CORS????

    example usage: "http://localhost:5000/solve?dimension=8&state_string=1525384358627583"
    '''
    board_dim = int(request.args["dimension"])
    board_state = request.args["state"]
    move_arg = request.args.get("max_moves")
    max_moves = 50 if move_arg is None else int(move_arg)
    cboard = ChessBoard(dimension = board_dim, state_string = board_state)
    solver = MinConflictColumnSolver(board_object = cboard, max_moves = max_moves)
    solver.solve()
    rsp_data = solver.get_solution()
    rsp_headers = {"Content-Type":"application/json"}
    return make_response(rsp_data, 200, rsp_headers)
Exemple #20
0
def test_constructor():
    row_num = 4
    cb = ChessBoard(WIDTH, HEIGHT, row_num)
    tiles = Tiles(cb)
    tile_list = []

    for x in range(row_num):
        tile_list.append([])
        for y in range(row_num):

            if tiles.tile_list[y][x] == None:
                tile_list[x].append(None)
            else:
                tile_list[x].append(tiles.tile_list[y][x].color)

    assert tile_list == [[None, None, None, None],
                         [None, 'white', 'black', None],
                         [None, 'black', 'white', None],
                         [None, None, None, None]]
Exemple #21
0
# coding: utf-8
 
from tkinter import Tk, PhotoImage
from chess_board import ChessBoard

window = Tk()
window.resizable(False, False)
window.title("Chess Exercises Organizer")
window.tk.call('wm', 'iconphoto', window._w, PhotoImage(file='knight.png'))

chess_board = ChessBoard(window)

chess_board.pack()

window.mainloop()
Exemple #22
0
from chess_board import ChessBoard

if __name__ == '__main__':
    ct = ChessBoard('Ke1,Qd1,Ra1,Rh1,Bc1,Bf1,Nb1,a2,c2,d2,f2,g2,h2,a3,e4',
                    'Ke8,Qd8,Ra8,Rh8,Bc8,Ng8,Nc6,a7,b7,c7,d7,e7,f7,h7,h6')
    print(ct)
    print()
    ct.show()
 def prepare_board(self):
     self.board = ChessBoard()
Exemple #24
0
from chess_board import ChessBoard
import logging.config

logging.config.fileConfig('logging.conf')

ChessBoard().launch()
Exemple #25
0
from chess_board import ChessBoard
from stochastic_hill_c import stochastic_hill_climbing as shc

b = ChessBoard()  # criação do tabuleiro
print("ORIGINAL: ", b.fitness)
print(b)
b.queens = shc(b)  # aplicação do hill climbing
b.update_board()
print("ALTERADO: ", b.fitness)
print(b)
Exemple #26
0
def chess_board():
    n = 3
    bishops = [(0, 1), (1, 0), (1, 2)]
    board = ChessBoard(n, bishops)
    print(board.number_of_bishops_killed())
Exemple #27
0
        rand_queen = random.choice([v for v in range(self.board.dim)])
        curr_col = self.board.q_locs[rand_queen][1]
        rand_col = random.choice(
            [v for v in range(self.board.dim) if v != curr_col])
        new_rand_pos = (self.board.q_locs[rand_queen][0], rand_col)
        resulting_state = self.board.get_state_string(rand_queen, new_rand_pos)
        if self.check_if_state_is_new(resulting_state):
            return rand_queen, new_rand_pos
        return None, None


if __name__ == "__main__":

    #TODO: Maybe move these to a tests folder?
    # Solution for a non row-conflicted board
    cb = ChessBoard(dimension=8, queen_seed=42)
    sv = MinConflictColumnSolver(board_object=cb, max_moves=50)
    sv.solve()
    pprint(sv.walk_solution_path()["text"])
    print(sv.solution_shortdoc())
    print("\n")

    # Solution for a row conflicted board
    cb = ChessBoard(dimension=8, state_string="1112131415161718")
    sv = MinConflictColumnSolver(board_object=cb, max_moves=50)
    sv.solve(verbose=True)
    pprint(sv.walk_solution_path()["text"])
    print(sv.solution_shortdoc())
    print("\n")

    # Harder row-conflicted cases, along with non-pruned step chain
def run_genetic_algorithm(population_size, number_of_children, reset):
    """Runs a genetic algorithm.

    Args:
        population_size (int): The size of the population to create.
        number_of_children (int): The number of children to breed each round.
        reset (int): The number of generations to reset after.
    """

    # Loop endlessly
    while True:
        # Create the initial population
        population = []
        for i in range(population_size):
            population.append(ChessBoard())

        generation_num = 1

        # Loop until the reset number is reached
        while generation_num <= reset:
            # Sort population by fitness, with most fit candidates first in the list
            population.sort(reverse=True)
            # Check the list to see if any of the population is a solution
            for board in population:
                # Checks to see if the board is a solution
                if bool(board):
                    add_solution(board.chromosome, generation_num)
                # Breaks if the current board was not a solution, as nothing after it in the sorted list will be
                else:
                    break
            # Pick the parents for the next generation
            parents = []
            for i in range(number_of_children * 2):
                # Select the portion of the population to grab a parent from
                portion = np.random.choice([0, 1, 2, 3, 4], p=breed_weights)
                # Select the parent from the designated portion
                parent_index = np.random.choice(
                    range(int(portion * len(population) / 5),
                          int((portion + 1) * len(population) / 5)))
                # Parents are removed so they cannot be selected again, and will be added back later
                parents.append(population.pop(parent_index))

            # Breed new children with the parents
            children = []
            for i in range(number_of_children):
                # Create the new child
                children.append(
                    ChessBoard(parent1=parents[i],
                               parent2=parents[0 - (i + 1)]))

            # Add the parents back into the population
            population += parents

            # Delete a number of boards from the population equal to the number of children to be added from the bottom
            # half
            for i in range(number_of_children):
                population.pop(np.random.randint(-int(len(population) / 2),
                                                 -1))

            # Add the children to the population to replace the killed population
            population += children

            # Increase generation number
            generation_num += 1
    def CnnVsMonteCarlo(self, nb_iter):
        """player 0 => play game using CNN
           player 1 => play game using random method

        """
        moves=[]
        winner=[]
        print('The number of iteration is %s' %(str(nb_iter)))
        for i in range(nb_iter):
            print(str(i) + " iterations is done")
            player=0
            board=ChessBoard(8).getChessBoard()
            list_best_move=[]
            while len(Playout().getPossibleMove(board, player))>0:
                # make sure which player
                # CNN player
                if player==0:
                    X=np.concatenate((board, 1-board, np.zeros((8,8), dtype=int)+player), axis=0).reshape(1,3,8,8)
                    y=self.cnn.predict(X).reshape(64)
                    # y=y_predict
                    is_finished=False
                                        
                    max_value=-1
                    counter=0
                    while is_finished==False & counter<64:
                        counter+=1
                        for i in range(64):
                            if y[i]>max_value:
                                max_value=y[i]
                                move=i
                        if move in Playout().getPossibleMove(board, player):
                            list_best_move.append(move)
                            board=Playout().play(board, move, player)
                            player=1-player
                            is_finished=True
                        else:
                            y[move]=0
                            max_value=-1
                elif player==1:
                    possible_moves=Playout().getPossibleMove(board, player)
                    
                    list_mean_playout=[]
                    list_move=[]
                    
                    for i in range(len(possible_moves)):
                        copy_board=np.copy(board)
                        copy_board=Playout().play(copy_board, possible_moves[i], player)
                        list_mean_playout.append(Playout().getMeanOfPlayout(copy_board, 1-player, 10))
                        list_move.append(possible_moves[i])
                    
                    best_playout=-1
                    for i in range(len(list_mean_playout)):
                        if list_mean_playout[i]>best_playout:
                            best_playout=list_mean_playout[i]
                            best_move=list_move[i]
                    
                    list_best_move.append(best_move)
                    board=Playout().play(board, best_move, player)
                    player=1-player

            moves.append(list_best_move)
            winner.append(1-player)
            
        return moves, winner
    def get_starts(self, locs=None, nrow=None, ncol=None, start_ri=None, end_ri=None,
                   start_ci=None, end_ci=None):
        """ Get list of starting squares
        :locs: base list of squares(loc or algebraic notation) default: nrowxncol squares
        :nrow: number of rows default: from gen_paths
        :ncol: number of cols default: from gen_paths
        :start_ri: beginning row index default: 0
        :end_ri: ending row index default: nrow-1
        :start_ci: beginning col index default: 0
        :end_ci: ending column index default: ncol-1
        :returns: pair: list of starting squares
        """
        if ncol is None:
            ncol = self.paths_gen.ncol
        if nrow is None:
            nrow = self.paths_gen.nrow
            
        cb = ChessBoard(nrow=nrow, ncol=ncol)
        if locs is None:
            path_starts = []
            if start_ri is None:
                start_ri = 0
            if end_ri is None:
                end_ri = nrow-1
            if start_ci is None:
                start_ci = 0
            if end_ci is None:
                end_ci = ncol-1
            for ri in range(start_ri, end_ri+1):
                for ci in range(start_ci, end_ci+1):
                    loc = (ci,ri)
                    path_starts.append(loc)
            locs = path_starts

        first = self.get_val("first", 0)
        lend = len(locs)
        if first == 0:
            first = 1
        wrap = self.get_val("wrap")
        last = self.get_val("last", 0)
        if last == 0:
            last = lend + 1
        square = self.get_val("square")
        if last == 0:
            last = lend
        loc_list = []
        for np in range(1, lend+1):
            if first == 0 or np < first:
                if wrap:
                    loc_list.append(locs[np-1])
            else:
                loc_list.append(locs[np-1])
        
        if square is not None and square != "":
            if "," in square:       # comma separates patterns
                pats = square.split(",")
                square = ""
                for pat in pats:
                    if square != "":
                        square += "|"
                    square += "("  + pat + ")"
            a_list = []
            for loc in loc_list:
                sq = cb.loc2desc(loc)
                if re.search(square, sq):
                    a_list.append(loc)
            loc_list = a_list
        
        return loc_list