Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversion from PBN to LIN is losing information #26

Open
ThorvaldAagaard opened this issue Aug 10, 2023 · 4 comments
Open

Conversion from PBN to LIN is losing information #26

ThorvaldAagaard opened this issue Aug 10, 2023 · 4 comments

Comments

@ThorvaldAagaard
Copy link
Contributor

I have a match recorded in a PBN-file and would like to convert it to a LIN-file, so I created a small script like this

image

The file was converted fine, but all information about the match was lost

The file usafrance.pbn is part of the old BBO-client, and using that application the PBN-file is converted correctly.

I have attached the 3 files as a zip-file because github is not supporting the extensions

usafrance.zip

It would be nice with some extra linefeeds in the lin-file for improved readabiliy

@dominicprice
Copy link
Owner

Hi,
I didn't know about the vg tag in lin - I'll do some investigating. Also looking into your other bug about the comments in PBN.
Thanks for bringing to my attention, it is sometimes hard to find enough data to test this stuff against!
Dom

@ThorvaldAagaard
Copy link
Contributor Author

I have implemented a small script, that can create a better .lin-file from the PBN. That .lin-file can now be read from the BBO-application and show the match.

Interestingly, there are some bugs in the implementation in the BBO-application, so the two .lin-files are not identical.

For now I have two differences:
1: endplay is printing deals in the wrong order
2: BBO-application is messing up names in the lin-file, but displaying it correctly

image

Here is the script if you can make any use of it:

import sys
import endplay.parsers.pbn as pbn
import endplay.parsers.lin as lin
import endplay.config as config

# Create a dictionary to map suit symbols to character representations
suit_symbols = {
    'C': '♣',  # Clubs
    'D': '♦',  # Diamonds
    'H': '♥',  # Hearts
    'S': '♠',  # Spades
}

try:
   with open("usafrance.pbn") as f:
      boards = pbn.load(f)
except pbn.PBNDecodeError as e:
    print("OK: There was an issue decoding the PBN file.")
    print("Error message:", e)
    print("Current line:", e.line)
    print("Line number:", e.lineno)
    sys.exit(1)

# Define a function to convert room values to numeric values for sorting
def room_to_numeric(room):
    if room == "Open":
        return 0
    elif room == "Closed":
        return 1
    else:
        return 2  # Handle other cases as needed
    
# Sort the array of Board objects based on board.number and board.info.room
sorted_boards = sorted(
    boards,
    key=lambda board: (board.board_num, room_to_numeric(board.info.room))
)

config.use_unicode = False 
# Use a list comprehension to extract the contract information from each board
contract_info = [board.contract for board in sorted_boards]

# Join the contract information into a single line
contract_line = ','.join(str(contract) for contract in contract_info).replace('NT','N')

print(f"vg|{boards[0].info.event},{boards[0].info.stage},I,1,16,{boards[0].info.hometeam},0,{boards[0].info.visitteam},0|")
# Print the single line with all contract information
print(f"rs|{contract_line}|")
print("pn|")
print(sorted_boards[0].info.south, end=",")
print(sorted_boards[0].info.west, end=",")
print(sorted_boards[0].info.north, end=",")
print(sorted_boards[0].info.east, end=",")
print(sorted_boards[1].info.south, end=",")
print(sorted_boards[1].info.west, end=",")
print(sorted_boards[1].info.north, end=",")
print(sorted_boards[1].info.east, end="")
print("|pg||")
print(f"mn|{boards[0].info.event} - {boards[0].info.stage}|", end='')
for board in boards:
    # Remove st| (small text) from the lin-file
    linfile = lin.dumps([board])
    linfile = linfile.replace('\n', '')
    if board.info.room == "Closed":
        # replace the board number. Board number will be added for room
        linfile = linfile.replace(f',|rh||ah|Board {board.board_num}','')
        linfile = linfile.replace('|mb|','\n|sa|0|mb|',1)
        linfile = linfile.replace('st|',f'qx|c{board.board_num},BOARD {board.board_num}|rh||ah|Board {board.board_num}')
    if board.info.room == "Open":
        linfile = linfile.replace(f',|rh||ah|Board {board.board_num}','')
        linfile = linfile.replace('|mb|','\n|sa|0|mb|',1)
        linfile = linfile.replace('st|',f'qx|o{board.board_num},BOARD {board.board_num}|rh||ah|Board {board.board_num}')
    linfile += 'pg||'
    linfile = linfile.replace('||','||\n') 
    # remove just to compare
    linfile = linfile.replace('||\n','||',1) 
    print(linfile)

And this is how it now looks in the application:
image

@ThorvaldAagaard
Copy link
Contributor Author

I have found another bug in the BBO vugraph as the above sheet for some strange reason will print the open room as the last names read in the lin-file, so I have just added an extra line with the same information as the first line with player names

@dominicprice
Copy link
Owner

Thanks for sharing --- I will have to do some more studying of the LIN format, and am thinking about some extra flags to make it a bit more customizable, but this is handy to see what sort of things people might want to do

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants