Show moving hintsList
Show moving hints
1. Initialize the list
First the global hints list is cleared. Don't forget to declare and initialize this variable (hintslst)!Then the local hints list is initialized and the piece letter is checked in a select statement.
For each chess piece the call to the correct subroutine is made.
The hints list for the queen or the king is a combination of the moves from a rook and a bishop. The king can only go one square in all directions.
The prowcol variable holds the position from the piece on the board. The pcolor variable holds the color of the piece and the pletter variable holds the piece letter.
Private Sub get_hints(prowcol As String, pcolor As String, pletter As String) As List
hintslst.Clear
Private hilst As List
hilst.Initialize
Select pletter
Case "P"
hilst = pawn_hints(prowcol,pcolor,hilst)
Case "R"
Private is_king As Boolean = False
hilst = rook_hints(prowcol,pcolor,hilst,is_king)
Case "N"
hilst = knight_hints(prowcol,pcolor,hilst)
Case "B"
Private is_king As Boolean = False
hilst = bishop_hints(prowcol,pcolor,hilst,is_king)
Case "Q"
hilst = queen_hints(prowcol,pcolor,hilst)
Case "K"
hilst = king_hints(prowcol,pcolor,hilst)
End Select
Return hilst
End Sub
2. Pawn moves

A black pawn moves down from its starting position one or two squares. After that it only moves one square at a time.
A pawn can't move forward (up or down) if there is another piece in its path.
A pawn can take a piece from the opposite color if that piece is on the diagonal one square forward (up for white and down for black).
The first digit from the phrowcol variable is the row integer and the second digit is the column integer.
A row or column integer must be greater than or equal to 0 and less than or equal to 7.
private Sub pawn_hints(phrowcol As String, phcolor As String, hlst As List) As List
Private phrow As Int = phrowcol.SubString2(0,1)
Private phcol As Int = phrowcol.SubString(1)
If phcolor = "W" Then
If (phrow-1) >= 0 And board((phrow-1),phcol) = "EEE" Then
hlst.Add((phrow-1)&phcol)
End If
If phrow = 6 And (phrow-2) >= 0 And board((phrow-2),phcol) = "EEE" And hlst.IndexOf((phrow-1)&phcol) <> -1 Then
hlst.Add((phrow-2)&phcol)
End If
' take possible
If (phrow-1) >= 0 And (phcol-1) >= 0 And board((phrow-1),(phcol-1)).StartsWith("B") Then
hlst.Add((phrow-1)&(phcol-1))
End If
If (phrow-1) >= 0 And (phcol+1) <= 7 And board((phrow-1),(phcol+1)).StartsWith("B") Then
hlst.Add((phrow-1)&(phcol+1))
End If
' in passing
If phrow = 3 And (phcol-1) >= 0 And board(phrow,(phcol-1)).StartsWith("BP") Then
hlst.Add((phrow-1)&(phcol-1))
End If
If phrow = 3 And (phcol+1) <= 7 And board(phrow,(phcol+1)).StartsWith("BP") Then
hlst.Add((phrow-1)&(phcol+1))
End If
End If
If phcolor = "B" Then
If (phrow+1) <= 7 And board((phrow+1),phcol) = "EEE" Then
hlst.Add((phrow+1)&phcol)
End If
If phrow = 1 And (phrow+2) <= 7 And board((phrow+2),phcol) = "EEE" And hlst.IndexOf((phrow+1)&phcol) <> -1 Then
hlst.Add((phrow+2)&phcol)
End If
' take possible
If (phrow+1) <= 7 And (phcol-1) >= 0 And board((phrow+1),(phcol-1)).StartsWith("W") Then
hlst.Add((phrow+1)&(phcol-1))
End If
If (phrow+1) <= 7 And (phcol+1) <= 7 And board((phrow+1),(phcol+1)).StartsWith("W") Then
hlst.Add((phrow+1)&(phcol+1))
End If
' in passing
If phrow = 4 And (phcol-1) >= 0 And board(phrow,(phcol-1)).StartsWith("WP") Then
hlst.Add((phrow+1)&(phcol-1))
End If
If phrow = 4 And (phcol+1) <= 7 And board(phrow,(phcol+1)).StartsWith("WP") Then
hlst.Add((phrow+1)&(phcol+1))
End If
End If
Return hlst
End Sub
3. Rook moves

If there is a piece on its path and that piece is from the opposite color than the rook can take that piece and can't go further.
If a piece from the same color blocks the rook's path then the rook can't go further.
The tests use an offset value to verify if the next square is empty or the piece can be taken.
Private Sub rook_hints(rrowcol As String,rcolor As String,hlst As List,iking As Boolean) As List
Private offset As Int
Private rrow As Int = rrowcol.SubString2(0,1)
Private rcol As Int = rrowcol.SubString(1)
' up
offset = 1
Do While (rrow-offset) >= 0
If board((rrow-offset),rcol) = "EEE" Then
hlst.Add((rrow-offset)&rcol)
Else
If board((rrow-offset),rcol).SubString2(0,1) <> rcolor Then
hlst.Add((rrow-offset)&rcol)
End If
Exit
End If
If iking = True Then Exit
offset = offset + 1
Loop
' down
offset = 1
Do While (rrow+offset) <= 7
If board((rrow+offset),rcol) = "EEE" Then
hlst.Add((rrow+offset)&rcol)
Else
If board((rrow+offset),rcol).SubString2(0,1) <> rcolor Then
hlst.Add((rrow+offset)&rcol)
End If
Exit
End If
If iking = True Then Exit
offset = offset + 1
Loop
' left
offset = 1
Do While (rcol-offset) >= 0
If board(rrow,(rcol-offset)) = "EEE" Then
hlst.Add(rrow&(rcol-offset))
Else
If board(rrow,(rcol-offset)).SubString2(0,1) <> rcolor Then
hlst.Add(rrow&(rcol-offset))
End If
Exit
End If
If iking = True Then Exit
offset = offset + 1
Loop
' right
offset = 1
Do While (rcol+offset) <= 7
If board(rrow,(rcol+offset)) = "EEE" Then
hlst.Add(rrow&(rcol+offset))
Else
If board(rrow,(rcol+offset)).SubString2(0,1) <> rcolor Then
hlst.Add(rrow&(rcol+offset))
End If
Exit
End If
If iking = True Then Exit
offset = offset + 1
Loop
' castling
Return hlst
End Sub
4. Knight moves

A knight (in other languages it could be called a horse) can move in strange ways and jump over existing pieces.
The knight can go two squares up or down and then one square left or right.
The knight piece can also go one square up or down and two squares left or right.
If the destination square contains a piece from the opposite color then the knight can take that piece (except if it's the king because then that king is in a check position).
Private Sub knight_hints(nrowcol As String,ncolor As String,hlst As List) As List
Private nrow As Int = nrowcol.SubString2(0,1)
Private ncol As Int = nrowcol.SubString(1)
' 8 places 2-1 or 1-2
' lower half
If (nrow+2) <= 7 And (ncol-1) >= 0 Then
If board((nrow+2),(ncol-1)) = "EEE" Then
hlst.Add((nrow+2)&(ncol-1))
Else
If board((nrow+2),(ncol-1)).SubString2(0,1) <> ncolor Then
hlst.Add((nrow+2)&(ncol-1))
End If
End If
End If
If (nrow+2) <= 7 And (ncol+1) <= 7 Then
If board((nrow+2),(ncol+1)) = "EEE" Then
hlst.Add((nrow+2)&(ncol+1))
Else
If board((nrow+2),(ncol+1)).SubString2(0,1) <> ncolor Then
hlst.Add((nrow+2)&(ncol+1))
End If
End If
End If
If (nrow+1) <= 7 And (ncol-2) >= 0 Then
If board((nrow+1),(ncol-2)) = "EEE" Then
hlst.Add((nrow+1)&(ncol-2))
Else
If board((nrow+1),(ncol-2)).SubString2(0,1) <> ncolor Then
hlst.Add((nrow+1)&(ncol-2))
End If
End If
End If
If (nrow+1) <= 7 And (ncol+2) <= 7 Then
If board((nrow+1),(ncol+2)) = "EEE" Then
hlst.Add((nrow+1)&(ncol+2))
Else
If board((nrow+1),(ncol+2)).SubString2(0,1) <> ncolor Then
hlst.Add((nrow+1)&(ncol+2))
End If
End If
End If
' upper half
If (nrow-2) >= 0 And (ncol-1) >= 0 Then
If board((nrow-2),(ncol-1)) = "EEE" Then
hlst.Add((nrow-2)&(ncol-1))
Else
If board((nrow-2),(ncol-1)).SubString2(0,1) <> ncolor Then
hlst.Add((nrow-2)&(ncol-1))
End If
End If
End If
If (nrow-2) >= 0 And (ncol+1) <= 7 Then
If board((nrow-2),(ncol+1)) = "EEE" Then
hlst.Add((nrow-2)&(ncol+1))
Else
If board((nrow-2),(ncol+1)).SubString2(0,1) <> ncolor Then
hlst.Add((nrow-2)&(ncol+1))
End If
End If
End If
If (nrow-1) >= 0 And (ncol-2) >= 0 Then
If board((nrow-1),(ncol-2)) = "EEE" Then
hlst.Add((nrow-1)&(ncol-2))
Else
If board((nrow-1),(ncol-2)).SubString2(0,1) <> ncolor Then
hlst.Add((nrow-1)&(ncol-2))
End If
End If
End If
If (nrow-1) >= 0 And (ncol+2) <= 7 Then
If board((nrow-1),(ncol+2)) = "EEE" Then
hlst.Add((nrow-1)&(ncol+2))
Else
If board((nrow-1),(ncol+2)).SubString2(0,1) <> ncolor Then
hlst.Add((nrow-1)&(ncol+2))
End If
End If
End If
Return hlst
End Sub
5. Bishop moves

If there is a piece of the opposite color in the bishop's path it can take that piece and it can't go further.
If a piece from the same color blocks the path from the bishop then the bishop can't go further.
Private Sub bishop_hints(browcol As String,bcolor As String,hlst As List,iking As Boolean) As List
Private offset As Int
Private brow As Int = browcol.SubString2(0,1)
Private bcol As Int = browcol.SubString(1)
' left up
offset = 1
Do While (brow-offset) >= 0 And (bcol-offset) >= 0
If board((brow-offset),(bcol-offset)) = "EEE" Then
hlst.Add((brow-offset)&(bcol-offset))
Else
If board((brow-offset),(bcol-offset)).SubString2(0,1) <> bcolor Then
hlst.Add((brow-offset)&(bcol-offset))
End If
Exit
End If
If iking = True Then Exit
offset = offset + 1
Loop
' left down
offset = 1
Do While (brow+offset) <= 7 And (bcol-offset) >= 0
If board((brow+offset),(bcol-offset)) = "EEE" Then
hlst.Add((brow+offset)&(bcol-offset))
Else
If board((brow+offset),(bcol-offset)).SubString2(0,1) <> bcolor Then
hlst.Add((brow+offset)&(bcol-offset))
End If
Exit
End If
If iking = True Then Exit
offset = offset + 1
Loop
' right up
offset = 1
Do While (brow-offset) >= 0 And (bcol+offset) <= 7
If board((brow-offset),(bcol+offset)) = "EEE" Then
hlst.Add((brow-offset)&(bcol+offset))
Else
If board((brow-offset),(bcol+offset)).SubString2(0,1) <> bcolor Then
hlst.Add((brow-offset)&(bcol+offset))
End If
Exit
End If
If iking = True Then Exit
offset = offset + 1
Loop
' right down
offset = 1
Do While (brow+offset) <= 7 And (bcol+offset) <= 7
If board((brow+offset),(bcol+offset)) = "EEE" Then
hlst.Add((brow+offset)&(bcol+offset))
Else
If board((brow+offset),(bcol+offset)).SubString2(0,1) <> bcolor Then
hlst.Add((brow+offset)&(bcol+offset))
End If
Exit
End If
If iking = True Then Exit
offset = offset + 1
Loop
Return hlst
End Sub
6. Queen moves

The queen piece can go in all directions until there is a piece of the opposite color in its path that it can take.
A piece of the same color also blocks the path of the queen piece.
Private Sub queen_hints(qrowcol As String,qcolor As String,hlst As List) As List
Private is_king As Boolean = False
' rook hints
hlst = rook_hints(qrowcol,qcolor,hlst,is_king)
' bishop hints
Private hlst1 As List
hlst1.Initialize
hlst1 = bishop_hints(qrowcol,qcolor,hlst1,is_king)
hlst.AddAll(hlst1)
Return hlst
End Sub
7. King moves

A king piece can take a piece of the opposite color if that piece is one square away from the king piece.
If a king piece is in a check position it has to move to a non-check position.
The player can put a piece in between the king piece and the piece giving the check.
If the king can't go anywhere without being in a check position then the king is checkmate and the game is over.
Private Sub king_hints(krowcol As String,kcolor As String,hlst As List) As List
Private is_king As Boolean = True
' rook hints 1 cell
hlst = rook_hints(krowcol,kcolor,hlst,is_king)
' bishop hints 1 cell
Private hlst1 As List
hlst1.Initialize
hlst1 = bishop_hints(krowcol,kcolor,hlst1,is_king)
hlst.AddAll(hlst1)
Return hlst
End Sub
8. Show the list
To show the hints we use the show_hints subroutine.The hints list contains all the possible positions (rowcol) the piece can go to.
The cells or squares are shown with a green border.
Private Sub show_hints(hlst As List)
For i = 0 To hlst.Size -1
Dim hrowcol As String = hlst.Get(i)
Dim pnl1 As Panel = get_board_panel(hrowcol,pnlmain)
cnvscell.Initialize(pnl1)
show_cell_border(Colors.Green,10dip,cnvscell)
Next
End Sub
The get_board_panel subroutine is used to get the panel from the list.The board panel contains 64 panels and each panel contains 1 label with the piece info.
The routine picks the panel at rowcol position and tests for the panel tag to be the same as the given rowcol.
Public Sub get_board_panel(pnlrowcol As String,pnlboard As Panel) As Panel
For Each v As B4XView In pnlboard.GetAllViewsRecursive
If v Is Panel Then
If v.Tag = pnlrowcol Then
Return v
End If
End If
Next
Return Null
End Sub
The subroutine get_hints is called in the pnl_Click subroutine and after that the show_hints routine is called.This is the code for getting the hints (in pnl_Click above the line srcrowcol = rowcol):
Private pcscolor As String = srctext.SubString2(0,1)
Private pcsletter As String = srctext.SubString2(1,2)
hintslst = get_hints(rowcol,pcscolor,pcsletter)
Log("hintslst: " & hintslst)
show_hints(hintslst)
So now you are ready to test the app, but first we have to fix the problem with the vanishing pieces.In the pnl_Click subroutine you can add the following test below the else line:
If hintslst.IndexOf(rowcol) = -1 Then
refresh_board
clickcnt = 0
Return
End If
Now if you tap on the same panel or on a panel that is not in the hints list then the board is refreshed, the click count is reset to 0 and with the return statement we leave the subroutine.