Search code examples
pythonstringpython-chess

How do you change a string to a list without separating all the characters?


I'm using the python-chess module to write a chess engine. Here's the code that I'm struggling with, for context:

def move_search():
    move_evals = []
    legal_moves = list(board.legal_moves)
    for move in range (len(legal_moves)):
        board.push(legal_moves[move - 1])
        board_eval()
        '''The above function is just an irrelevant 
        snippet that gets the advantage score. 
        I think it's very unlikely that's causing the problem.'''

        move_evals.append(score)
        board.pop()
    string_moves = list(str(legal_moves)) 
    print(str(legal_moves))   
    move_evals, string_moves = (list(t) for t in zip(*sorted(zip(move_evals, string_moves))))
    print(move_evals)     
    print(string_moves)

I had to add the string_moves because just using the legal_moves list returned this error:

line 123, in move_search
move_evals, legal_moves = (list(t) for t in zip(*sorted(zip(move_evals, legal_moves))))
TypeError: '<' not supported between instances of 'Move' and 'Move'

However, string_moves returns an overly long list with each character in the list legal_moves as one element of the list. How do I explicitly tell Python that I want it to be a list with the original elements, but just as a 'string' instance?

Expected vs. Actual Output (as kindly requested by Mark Tolonen:) Expected:

[Move.from_uci('g1h3'), Move.from_uci('g1f3'), 
Move.from_uci('b1c3'), Move.from_uci('b1a3'), 
Move.from_uci('h2h3'), Move.from_uci('g2g3'), 
Move.from_uci('f2f3'), Move.from_uci('e2e3'), 
Move.from_uci('d2d3'), Move.from_uci('c2c3'), 
Move.from_uci('b2b3'), Move.from_uci('a2a3'), 
Move.from_uci('h2h4'), Move.from_uci('g2g4'), 
Move.from_uci('f2f4'), Move.from_uci('e2e4'), 
Move.from_uci('d2d4'), Move.from_uci('c2c4'), 
Move.from_uci('b2b4'), Move.from_uci('a2a4')]

Actual:

['[', 'M', 'o', 'v', 'e', '.', 'f', 'r', 'o', 'm', 
'_', 'u', 'c', 'i', '(', "'", 'g', '1', 'h', '3', 
"'", ')', ',', ' ', 'M', 'o', 'v', 'e', '.', 'f', 
'r', 'o', 'm', '_', 'u', 'c', 'i', '(', "'", 'g', 
'1', 'f', '3', "'", ')', ',', ' ', 'M', 'o', 'v', 
'e', '.', 'f', 'r', 'o', 'm', '_', 'u', 'c', 'i', 
'(', "'", 'b', '1', 'c', '3', "'", ')', ',', ' ', 
'M', 'o', 'v', 'e', '.', 'f', 'r', 'o', 'm', '_', 
'u', 'c', 'i', '(', "'", 'b', '1', 'a', '3', "'", 
')', ',', ' ', 'M', 'o', 'v', 'e', '.', 'f', 'r', 
'o', 'm', '_', 'u', 'c', 'i', '(', "'", 'h', '2', 
'h', '3', "'", ')', ',', ' ', 'M', 'o', 'v', 'e', 
'.', 'f', 'r', 'o', 'm', '_', 'u', 'c', 'i', '(', 
"'", 'g', '2', 'g', '3', "'", ')', ',', ' ', 'M', 
'o', 'v', 'e', '.', 'f', 'r', 'o', 'm', '_', 'u', 
'c', 'i', '(', "'", 'f', '2', 'f', '3', "'", ')', 
',', ' ', 'M', 'o', 'v', 'e', '.', 'f', 'r', 'o', 
'm', '_', 'u', 'c', 'i', '(', "'", 'e', '2', 'e', 
'3', "'", ')', ',', ' ', 'M', 'o', 'v', 'e', '.', 
'f', 'r', 'o', 'm', '_', 'u', 'c', 'i', '(', "'", 
'd', '2', 'd', '3', "'", ')', ',', ' ', 'M', 'o', 
'v', 'e', '.', 'f', 'r', 'o', 'm', '_', 'u', 'c', 
'i', '(', "'", 'c', '2', 'c', '3', "'", ')', ',', ' 
', 'M', 'o', 'v', 'e', '.', 'f', 'r', 'o', 'm', 
'_', 'u', 'c', 'i', '(', "'", 'b', '2', 'b', '3', 
"'", ')', ',', ' ', 'M', 'o', 'v', 'e', '.', 'f', 
'r', 'o', 'm', '_', 'u', 'c', 'i', '(', "'", 'a', 
'2', 'a', '3', "'", ')', ',', ' ', 'M', 'o', 'v', 
'e', '.', 'f', 'r', 'o', 'm', '_', 'u', 'c', 'i', 
'(', "'", 'h', '2', 'h', '4', "'", ')', ',', ' ', 
'M', 'o', 'v', 'e', '.', 'f', 'r', 'o', 'm', '_', 
'u', 'c', 'i', '(', "'", 'g', '2', 'g', '4', "'", 
')', ',', ' ', 'M', 'o', 'v', 'e', '.', 'f', 'r', 
'o', 'm', '_', 'u', 'c', 'i', '(', "'", 'f', '2', 
'f', '4', "'", ')', ',', ' ', 'M', 'o', 'v', 'e', 
'.', 'f', 'r', 'o', 'm', '_', 'u', 'c', 'i', '(', 
"'", 'e', '2', 'e', '4', "'", ')', ',', ' ', 'M', 
'o', 'v', 'e', '.', 'f', 'r', 'o', 'm', '_', 'u', 
'c', 'i', '(', "'", 'd', '2', 'd', '4', "'", ')', 
',', ' ', 'M', 'o', 'v', 'e', '.', 'f', 'r', 'o', 
'm', '_', 'u', 'c', 'i', '(', "'", 'c', '2', 'c', 
'4', "'", ')', ',', ' ', 'M', 'o', 'v', 'e', '.', 
'f', 'r', 'o', 'm', '_', 'u', 'c', 'i', '(', "'", 
'b', '2', 'b', '4', "'", ')', ',', ' ', 'M', 'o', 
'v', 'e', '.', 'f', 'r', 'o', 'm', '_', 'u', 'c', 
'i', '(', "'", 'a', '2', 'a', '4', "'", ')', ']']


Solution

  • Creating that string str(legal_moves) at all is a mistake. Instead fix your sorting error by using an appropriate key:

    move_evals, legal_moves = (
        list(t)
        for t in zip(*sorted(
            zip(move_evals, legal_moves),
            key=lambda t: t[0]
        ))
    )
    

    That sorts the (eval, move) pairs by the evals alone. It doesn't try to compare the moves themselves.

    Alternatively, if you do want the raw moves themselves to influence the order in case of equal evals, do make Move objects comparable (by giving them at least a __lt__ method). Or include them in the key, for example key=lambda t: (t[0], t[1].as_string) (or however the Move object makes its string accessible).