fb:porticula NoPaste
chess_gui_engine_vs_engine_0.3
Uploader: | grindstone |
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 ".........................................."