Buchempfehlung
Windows System Programming
Windows System Programming
Das Kompendium liefert viele interessante Informationen zur Windows-Programmierung auf Englisch. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

fb:porticula NoPaste

Info
Info / Hilfe
Liste
Übersicht / Liste
Neu
Datei hochladen
Suche
Quellcode suchen
Download
Dateidownload

chess_gui_engine_vs_engine_0.3

Uploader:Mitgliedgrindstone
Datum/Zeit:18.11.2013 11:21:38

#Include Once "windows.bi"
#Include "fbgfx.bi"


Type chessMove
    x1 As Integer
    x2 As Integer
    y1 As Integer
    y2 As Integer
    t1 As Integer
    t2 As Integer
    move As String
End Type

Type wText
    opponent As String
    move As String
    depth As String
End Type

Const As Integer castlingWhite = 1, castlingBlack = 2
Const As String w = "white", b = "black"

Dim Shared As Integer mx, my, btn, ox, oy, dx, dy, depth, movetime
Dim Shared As Integer board(12,12) 'internal representation of board
Dim Shared As Integer castlingFlagWhite, castlingFlagBlack
Dim Shared As Integer bx, by        'position top/left of board
Dim Shared As wText wt
Dim Shared As FB.Image Ptr sImage
Dim Shared As FB.Image Ptr iPiece(12) '12 images
Dim Shared As String hod, currdepth, currmove, engineWhite, engineBlack, nameWhite, nameBlack, _
                     WindowText, move
Dim Shared As HANDLE hReadChildPipeWhite, hWriteChildPipeWhite, hReadChildPipeBlack, _
                     hWriteChildPipeBlack, hReadPipeWhite, hWritePipeWhite, hReadPipeBlack, _
                     hWritePipeBlack, hThisWindow

Declare Function GetEngineResponse(opponent As String) As String
Declare Function GetMove(opponent As String) As String
Declare Sub WriteEngineInfo(opponent As String, s As String)
Declare Sub update()
Declare Function strMoveToNumMove(move As String) As chessMove
Declare Sub makeMove(cMove As chessMove)
Declare Sub SetText

Dim As Integer x
Dim As String datum, g
Dim As chessMove cMove
Dim As STARTUPINFO siWhite, siBlack
Dim As PROCESS_INFORMATION pi
Dim As SECURITY_ATTRIBUTES sa

engineWhite = "stockfish_4_32bit.exe"
engineBlack = "Fruit-2-3-1.exe"

'Swap engineWhite,engineBlack

'install the pipes to the two engines
sa.nLength = SizeOf(SECURITY_ATTRIBUTES)
sa.lpSecurityDescriptor = NULL
sa.bInheritHandle = TRUE

CreatePipe(@hReadChildPipeWhite,@hWritePipeWhite,@sa,0)
SetHandleInformation(hWritePipeWhite,HANDLE_FLAG_INHERIT,0)

CreatePipe(@hReadPipeWhite,@hWriteChildPipeWhite,@sa,0)
SetHandleInformation(hReadPipeWhite,HANDLE_FLAG_INHERIT,0)

GetStartupInfo(@siWhite)

siWhite.dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW
siWhite.wShowWindow = SW_SHOW
siWhite.hStdOutput  = hWriteChildPipeWhite
siWhite.hStdError   = hWriteChildPipeWhite
siWhite.hStdInput   = hReadChildPipeWhite

CreateProcess(0,engineWhite,0,0,TRUE,0,0,0,@siWhite,@pi)

CreatePipe(@hReadChildPipeBlack,@hWritePipeBlack,@sa,0)
SetHandleInformation(hWritePipeBlack,HANDLE_FLAG_INHERIT,0)

CreatePipe(@hReadPipeBlack,@hWriteChildPipeBlack,@sa,0)
SetHandleInformation(hReadPipeBlack,HANDLE_FLAG_INHERIT,0)

GetStartupInfo(@siBlack)

siBlack.dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW
siBlack.wShowWindow = SW_SHOW
siBlack.hStdOutput  = hWriteChildPipeBlack
siBlack.hStdError   = hWriteChildPipeBlack
siBlack.hStdInput   = hReadChildPipeBlack

CreateProcess(0,engineBlack,0,0,TRUE,0,0,0,@siBlack,@pi)

CloseHandle(hWriteChildPipeWhite)
CloseHandle(hReadChildPipeWhite)
CloseHandle(hWriteChildPipeBlack)
CloseHandle(hReadChildPipeBlack)



ScreenRes 640,480,32
sImage = ImageCreate( 42, 42, 0 )  'save screen data

hThisWindow = GetForegroundWindow() 'get the window handle

'THIS DETERMINES WHERE TO PLACE BOARD IN WINDOW
bx = 130
by = 30

'read board
Restore boardLayout
For j As Integer = 0 To 11
    For i As Integer = 0 To 11
        Read board(i,j)
    Next i
Next j

'copy images from data statements to screen
Restore Pieces
For i As Integer = 0 To 5   'for each piece
    For y As Integer = 0 To 41  'for each row
        Read datum
        For x As Integer = 0 To 41  'for each column
            If Mid(datum,x+1,1)="." Then
                PSet(x+i*42,y),RGB(255,0,255) 'transparent color
                PSet(x+i*42+252,y),RGB(255,0,255)
            End If
            If Mid(datum,x+1,1)="#" Then
                PSet(x+i*42,y),RGB(0,0,0)
                PSet(x+i*42+252,y),RGB(0,0,0)
            End If
            If Mid(datum,x+1,1)="*" Then
                PSet(x+i*42,y),RGB(120,120,180)
                PSet(x+i*42+252,y),RGB(250,200,200)
            End If
        Next x
    Next y
Next i
'sleep

'allocate memory for 12 images
For i As Integer = 0 To 11
    iPiece(i) = ImageCreate(42,42,0)
Next i

'get set of 12 images
For i As Integer = 0 To 11
    Get (i*42,0)-(i*42+41,41), iPiece(i)
Next i

update()
move = ""
wt.move = "----"
castlingFlagWhite = 1 'set white castling flag
castlingFlagBlack = 1 'set black castling flag

depth = 10
movetime = 10000

Open ExePath + "\protocol.txt" For Output As #1 'open the protocol file
Locate 52,30
Print "Wait loading engines!"
WriteEngineInfo(w,"uci")
WriteEngineInfo(b,"uci")
Do
  g = GetEngineResponse(w)
Loop Until InStr(g,"uciok")
x = InStr(g,"id name ") + 8
nameWhite = Mid(g, x, InStr(x,g,Chr(13)) - x) 'get the name of the white engine

Do
  g = GetEngineResponse(b)
Loop Until InStr(g,"uciok")
x = InStr(g,"id name ") + 8
nameBlack = Mid(g, x, InStr(x,g,Chr(13)) - x) 'get the name of the black engine

Locate 52,30
Print "Calculate position..."


'***************  MAIN LOOP ************************
Do
    '****** ENGINE WHITE ***********
    Locate 2,20
    Print nameWhite
    'Print engineWhite
    Locate 48,20
    Print nameBlack
    'Print engineBlack

    If hod = "" Then 'it's the first move
        hod = "position startpos moves"
    Else
        WriteEngineInfo(w,hod) 'send the actual board setup to the white engine
    EndIf
    Print #1, "white ";hod

    'WriteEngineInfo(w,"go depth " + Str(depth)) 'calculate the next white move
    WriteEngineInfo("white","go movetime " + Str(movetime)) 'calculate the next white move

    move = GetMove(w) 'read the best move of the white engine
    hod += " " + move
    cMove.move = move 'for pawn promotion
    wt.move = move 'for the title bar
    SetText
    Locate 52,30
    If (move = "a1a1") Or (move = "(none)") Then
        Print " << CHECK MATE >> "
        Close
        Sleep
        Exit Do
    EndIf
    Print move

    'show animated move
    If (Left(move,4) = "e1g1") And castlingFlagWhite Then
        cMove = strMoveToNumMove(move)
        makeMove(cMove)
        cMove = strMoveToNumMove("h1f1")
        makeMove(cMove)
        update()
        castlingFlagWhite = 0 'reset white castling flag
    ElseIf (Left(move,4) = "e1c1") And castlingFlagWhite Then
        cMove = strMoveToNumMove(move)
        makeMove(cMove)
        cMove = strMoveToNumMove("a1d1")
        makeMove(cMove)
        update()
        castlingFlagWhite = 0 'reset white castling flag
    Else 'no castling
        cMove = strMoveToNumMove(move)
        makeMove(cMove)
        update()
    EndIf

    '****** ENGINE BLACK ***********
    Print #1, "black ";hod
    Locate 2,20
    Print nameWhite
    'Print engineWhite
    Locate 48,20
    Print nameBlack
    'Print engineBlack

    WriteEngineInfo(b,hod) 'send the actual board setup to the black engine

    'WriteEngineInfo(b,"go depth " + Str(depth)) 'calculate the next black move
    WriteEngineInfo(b,"go movetime " + Str(movetime)) 'calculate the next black move

    move = GetMove(b) 'read the best move of the white engine
    hod += " " + move
    cMove.move = move 'for pawn promotion
    wt.move = move
    SetText
    Locate 52,30
    If (move = "a1a1") Or (move = "(none)") Then
        Print " << CHECK MATE >> "
        Close
        Sleep
        Exit Do
    EndIf
    Print move

    If (Left(move,4) = "e8g8") And castlingFlagBlack Then
        cMove = strMoveToNumMove(move)
        makeMove(cMove)
        cMove = strMoveToNumMove("h8f8")
        makeMove(cMove)
        update()
        castlingFlagBlack = 0 'reset black castling flag
    ElseIf (Left(move,4) = "e8c8") And castlingFlagBlack Then
        cMove = strMoveToNumMove(move)
        makeMove(cMove)
        cMove = strMoveToNumMove("a8d8")
        makeMove(cMove)
        update()
        castlingFlagBlack = 0 'reset black castling flag
    Else 'no castling
        cMove = strMoveToNumMove(move)
        makeMove(cMove)
        update()
    EndIf

Loop Until InKey = Chr(27) 'Esc


End

Sub update()

    ScreenLock()
    'drawBoard
    Color RGB(0,0,0),RGB(100,255,100)
    Cls
    Dim As Integer shade
    shade = 1
    For y As Integer = 0 To 7
        shade = -shade
        For x As Integer = 0 To 7
            If shade = -1 Then
                Line (bx+x*42,by+y*42)-(bx+x*42+41,by+y*42+41),RGB(252,206,156),bf
            Else
                Line (bx+x*42,by+y*42)-(bx+x*42+41,by+y*42+41),RGB(179,110,44),bf
            End If
            shade = -shade
        Next x
    Next y
    'border of board
    Line (bx-1,by-1)-(bx+336,by+336),RGB(0,0,0),b

    'now draw image on square
    For y As Integer = 0 To 7 'column
        For x As Integer = 0 To 7 'line
            'put image onto square
            If board(x+2,y+2) <> 7 And board(x+2,y+2) <> 0 Then
                If board(x+2,y+2) < 0 Then 'black
                    Put (bx+x*42,by+y*42),iPiece(Abs(board(x+2,y+2))-1),Trans
                Else 'white
                    Put (bx+x*42,by+y*42),iPiece(Abs(board(x+2,y+2))+5),Trans
                End If
            End If
        Next x
    Next y

    ScreenUnlock()
End Sub

Sub makeMove(cMove As chessMove)
    Dim As Integer choice, i  'number of selected piece
    Dim As Integer px1, py1, px2, py2, dx, dy  'moving data

    Locate 1,1
    cMove.y1 = 8 - cMove.y1 'set correct line of internal board
    cMove.y2 = 8 - cMove.y2

    px1 = cMove.x1*42+bx   'screen pointer to chosen image
    py1 = cMove.y1*42+by
    px2 = cMove.x2*42+bx
    py2 = cMove.y2*42+by

    ox = px1
    oy = py1

    'make move on internal board
    choice = board(cMove.x1+2,cMove.y1+2)

    'pawn promotion
    Select Case Mid(cMove.move,5,1)
        Case "q"
            choice = Sgn(choice) * 5 'promote to queen
        Case "b"
            choice = Sgn(choice) * 4 'promote to bishop
        Case "k"
            choice = Sgn(choice) * 3 'promote to knight
        Case "r"
            choice = Sgn(choice) * 2 'promote to rook
    End Select

    board(cMove.x2+2,cMove.y2+2) = choice
    board(cMove.x1+2,cMove.y1+2)=0  'erase data

    'convert to image ID of that number
    If choice < 0 Then
        choice = Abs(choice) - 1
    Else
        choice = choice + 5
    End If

    Line (px1,py1)-(px1+41,py1+41),Point(px1+2,py1+2),bf 'clear
    For i = 0 To 3
        Line (px1+i,py1+i)-(px1+41-i,py1+41-i),RGB(0,0,244),b  'source
        Line (px2+i,py2+i)-(px2+41-i,py2+41-i),RGB(0,255,0),b  'destination
    Next i

    'compute direction of movement
    If px1 > px2 Then
        dx = -1
    Else
        dx = 1
    End If
    If py1 > py2 Then
        dy = -1
    Else
        dy = 1
    End If

    Get (px1,py1)-(px1+41,py1+41),sImage
    Put (px1,py1),iPiece(choice),Trans
    ox = px1
    oy = py1

    While px1 <> px2 Or py1 <> py2
        'update coordinates
        If px1 <> px2 Then
            px1 = px1 + dx
        End If
        If py1 <> py2 Then
            py1 = py1 + dy
        End If

        Put (ox,oy),sImage,PSet        'restore old back ground
        Get (px1,py1)-(px1+41,py1+41),sImage 'save new back ground
        Put (px1,py1),iPiece(choice),Trans  'place on new back ground
        ox = px1
        oy = py1

        Sleep 4

    Wend

End Sub

'convert string chess moves to numbers
Function strMoveToNumMove(move As String) As chessMove
    Dim As chessMove cm

    cm.move = move
    move = UCase(move)

    cm.x1 = Asc(Mid(move,1,1))-65
    cm.y1 = Val(Mid(move,2,1))
    cm.x2 = Asc(Mid(move,3,1))-65
    cm.y2 = Val(Mid(move,4,1))

    Return cm
End Function

'convert chess move numbers to string format
Function numMovetoStrMove(cm As chessMove) As String
    Return Chr(cm.x1+65)+Str(cm.y1)+Chr(cm.x2+65)+Str(cm.y2)
End Function

Function GetMove(opponent As String) As String
    Dim As String g, sRet
    Dim As Integer x

    wt.opponent = opponent
    g = ""
    Do
        g += GetEngineResponse(opponent) 'request a message from the engine
        currdepth = ""
        x = InStrRev(g,"info depth ")
        currdepth = Mid(g,x+11,2)
        Locate 55, 20
        Print UCase(opponent)
        Locate 56, 20
        Print "Current depth ";currdepth
        wt.depth = currdepth
        SetText
        Sleep 1
        x = InStrRev(g,"bestmove")
    Loop Until x 'the engine has finished the calculating for this move

    sRet = Mid(g,x + 9,InStr(x + 9,g," ") - (x + 9)) 'isolate the data of the move
    Return sRet 'send the move to the gui

End Function

Function GetEngineResponse(opponent As String) As String
    Dim As Integer iTotalBytesAvail, iNumberOfBytesWritten, iBytesToRead
    Dim As String sRet = "", sBuf

    Const As Integer MaxBytesToRead = 4096 'maximum number of bytes to be returned at one 'ReadFile'-operation

    Do
        sBuf = "" 'clear buffer
        Select Case opponent
            Case "white"
                PeekNamedPipe(hReadPipeWhite,NULL,NULL,NULL,@iTotalBytesAvail,NULL) 'find out if there's any data in the pipe
            Case "black"
                PeekNamedPipe(hReadPipeBlack,NULL,NULL,NULL,@iTotalBytesAvail,NULL) 'find out if there's any data in the pipe
        End Select
        If iTotalBytesAvail Then 'pipe is not empty
            If iTotalBytesAvail < MaxBytesToRead Then
                iBytesToRead = iTotalBytesAvail 'set all available bytes to be read
            Else
                iBytesToRead = MaxBytesToRead 'set the first 4096 bytes to be read
            EndIf
            sBuf = String(iBytesToRead,Chr(0)) 'set the length of the buffer string to the necessary value
            Select Case opponent
                Case "white"
                    ReadFile(hReadPipeWhite,StrPtr(sBuf),iBytesToRead,@iNumberOfBytesWritten,NULL) 'read the specified amount of bytes from the pipe
                Case "black"
                    ReadFile(hReadPipeBlack,StrPtr(sBuf),iBytesToRead,@iNumberOfBytesWritten,NULL) 'read the specified amount of bytes from the pipe
            End Select
            sRet += sBuf 'add the buffer to the return string
            Sleep 1
        Else 'pipe is empty
            Exit Do 'return
        EndIf
    Loop

    Return sRet
End Function

Sub WriteEngineInfo(opponent As String, s As String)
    Dim As Integer iNumberOfBytesWritten, x
    Dim As String sBuf

    sBuf = s + Chr(10)
    Select Case opponent
        Case "white"
            WriteFile(hWritePipeWhite,StrPtr(sBuf),Len(sBuf),@iNumberOfBytesWritten,NULL)
        Case "black"
            WriteFile(hWritePipeBlack,StrPtr(sBuf),Len(sBuf),@iNumberOfBytesWritten,NULL)
    End Select

End Sub

Sub SetText
    Dim As String text

    text = Left(UCase(wt.opponent),1) + " " + wt.move + " " + wt.depth
    SetWindowText(hThisWindow,StrPtr(text))
    Sleep 1

End Sub


'***************************************************

' 1 = pawn, 2 = rook, 3 = knight, 4 = bishop, 5 = queen, 6 = king, 7 = border
' black pieces given negative value, sgn() returns -1 for black and +1 for white

'    0  1  2  3  4  5  6  7  8  9  10 11  <--- internal coordinates
'          A  B  C  D  E  F  G  H         <--- display coordinates
boardLayout:
Data 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 '0
Data 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 '1
Data 7, 7,-2,-3,-4,-5,-6,-4,-3,-2, 7, 7 '2     8
Data 7, 7,-1,-1,-1,-1,-1,-1,-1,-1, 7, 7 '3     7
Data 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7 '4     6
Data 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7 '5     5
Data 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7 '6     4
Data 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7 '7     3
Data 7, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7 '8     2
Data 7, 7, 2, 3, 4, 5, 6, 4, 3, 2, 7, 7 '9     1
Data 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 '10
Data 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 '11


Pieces:
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data "....................####.................."
Data "...................#****#................."
Data "..................#******#................"
Data ".................#********#..............."
Data ".................#********#..............."
Data ".................#********#..............."
Data ".................#********#..............."
Data "..................#******#................"
Data "...................#****#................."
Data "...................######................."
Data "..................#******#................"
Data "................##********##.............."
Data "...............#************#............."
Data "..............#**************#............"
Data "..............################............"
Data ".................#********#..............."
Data ".................#********#..............."
Data ".................#********#..............."
Data "................#**********#.............."
Data "................#**********#.............."
Data "...............#************#............."
Data "..............#**************#............"
Data ".............#****************#..........."
Data "............#******************#.........."
Data "............#******************#.........."
Data "............####################.........."
Data "...........#********************#........."
Data "...........#********************#........."
Data "...........######################........."
Data ".........................................."
Data ".........................................."
Data ".........................................."

Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data "...........#####..######..#####..........."
Data "...........#***#..#****#..#***#..........."
Data "...........#***#..#****#..#***#..........."
Data "...........#***#..#****#..#***#..........."
Data "...........#***####****####***#..........."
Data "...........#******************#..........."
Data "...........#******************#..........."
Data "...........#******************#..........."
Data "...........#******************#..........."
Data "...........####################..........."
Data "............#****************#............"
Data ".............################............."
Data ".............#****#****#****#............."
Data ".............#****#****#****#............."
Data ".............################............."
Data ".............#**#****#****#*#............."
Data ".............#**#****#****#*#............."
Data ".............################............."
Data ".............#****#****#****#............."
Data ".............#****#****#****#............."
Data ".............################............."
Data ".............#**#****#****#*#............."
Data ".............#**#****#****#*#............."
Data "............##################............"
Data "...........#******************#..........."
Data "..........#********************#.........."
Data "..........#********************#.........."
Data ".........#**********************#........."
Data ".........########################........."
Data ".........................................."
Data ".........................................."
Data ".........................................."

Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data "....................#....................."
Data "...................##....................."
Data "..................#**#...................."
Data "..................#**###.................."
Data ".................#******###..............."
Data "................#**********#.............."
Data "................#***********#............."
Data "...............#**#*********#............."
Data "..............#**##**********#............"
Data ".............#**##.#*********#............"
Data ".............#**###***********#..........."
Data "............#*****************#..........."
Data "............#*****************#..........."
Data "...........#******************#..........."
Data "...........#*******************#.........."
Data "..........#******#####*********#.........."
Data "..........#******#..#**********#.........."
Data ".........#*******#..#**********#.........."
Data ".........#******#..#***********#.........."
Data "..........#****#..#***********#..........."
Data "..........#####..#************#..........."
Data "................#*************#..........."
Data "...............#*************#............"
Data "...............#*************#............"
Data "..............#***************#..........."
Data "..............#***************#..........."
Data ".............#*****************#.........."
Data ".............#******************#........."
Data "............#*******************#........."
Data "............######################........"
Data ".........................................."
Data ".........................................."
Data ".........................................."

Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".....................##..................."
Data "....................#**#.................."
Data "...................#****#................."
Data "..................#******#................"
Data ".................#********#..............."
Data "................#**********#.............."
Data "...............#************#............."
Data "...............#************#............."
Data "..............##************##............"
Data "..............#**************#............"
Data "..............#**************#............"
Data "..............#******##******#............"
Data ".............#*******##*******#..........."
Data ".............#*******##*******#..........."
Data ".............#*******##*******#..........."
Data ".............#****########****#..........."
Data ".............#****########****#..........."
Data ".............#*******##*******#..........."
Data ".............#*******##*******#..........."
Data ".............#*******##*******#..........."
Data ".............#*******##*******#..........."
Data ".............#*******##*******#..........."
Data "..............#******##******#............"
Data "..............#******##******#............"
Data "...............#************#............."
Data "...............#************#............."
Data "...............##############............."
Data "...............##**********##............."
Data "................############.............."
Data "..............##************##............"
Data "............##*****######*****##.........."
Data "...........#*****##......##*****#........."
Data "...........######..........######........."
Data ".........................................."
Data ".........................................."
Data ".........................................."

Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".....................#...................."
Data "....................#*#..................."
Data "...................#***#.................."
Data "..................#*****#................."
Data "..................#*****#................."
Data "..................#*****#................."
Data "............#.....#*****#.....#..........."
Data "...........#*#.....#***#.....#*#.........."
Data "..........#***#....#***#....#***#........."
Data "..........#***#....#***#....#***#........."
Data "...........#*#.....#***#.....#*#.........."
Data "...........#*#.....#***#.....#*#.........."
Data "..........#***#...#*****#...#***#........."
Data "..........#***#..#*******#..#***#........."
Data "..........#***#..#*******#..#***#........."
Data ".....##...#***#...#*****#...#***#...##...."
Data ".....#*#..#***#...#*****#...#***#..#*#...."
Data ".....#**#.#***#...#*****#...#***#.#**#...."
Data ".....#**#.#***#...#*****#...#***#.#**#...."
Data "......#*#.#***#...#*****#...#***#.#*#....."
Data "......#**##***#...#*****#...#***##**#....."
Data "......#**#*****#.#*******#.#*****#**#....."
Data ".......#*******##*********##*******#......"
Data ".......#***************************#......"
Data "........#*************************#......."
Data "........###########################......."
Data "........#*************************#......."
Data "........#*************************#......."
Data "........#*************************#......."
Data "........#*************************#......."
Data "........#*************************#......."
Data "........###########################......."
Data ".......#***************************#......"
Data ".......#***************************#......"
Data ".......#############################......"
Data ".........................................."
Data ".........................................."
Data ".........................................."

Data ".........................................."
Data ".........................................."
Data ".........................................."
Data "....................###..................."
Data "....................#*#..................."
Data "..................###*###................."
Data "..................#*****#................."
Data "..................###*###................."
Data "....................#*#..................."
Data "....................#*#..................."
Data "...................#####.................."
Data "..................#*****#................."
Data "..................#*****#................."
Data "..................#*****#................."
Data "...................#***#.................."
Data "......#########.....#*#.....#########....."
Data ".....#.........######*######.........#...."
Data ".....#..............#*#..............#...."
Data ".....#....####......#*#......####....#...."
Data ".....#...#****###...#*#...###****#...#...."
Data ".....#.##********##.#*#.##********##.#...."
Data ".....#.#***********##*##***********#.#...."
Data ".....#.#************#*#************#.#...."
Data ".....#.#*****####***#*#***####*****#.#...."
Data ".....#.#****#****##*#*#*##****#****#.#...."
Data "......#*****#******##*##******#*****#....."
Data ".......#****#*******#*#*******#****#......"
Data ".......#****#*******#*#*******#****#......"
Data "........#****#******#*#******#****#......."
Data "........#****#******#*#******#****#......."
Data ".........#****#*****#*#*****#****#........"
Data ".........#*****#****#*#****#*****#........"
Data "..........#*****#***#*#***#*****#........."
Data "..........#######################........."
Data "..........#*********************#........."
Data "..........#######################........."
Data ".........##*********************##........"
Data "........##***********************##......."
Data "........###########################......."
Data ".........................................."
Data ".........................................."
Data ".........................................."