1. CastlingWhen there are no pieces between the king and the rook (of the same color) on the left or right side of the king then the rook can move next to the king and the king jumps over the rook to the left or right.
This requires two moves: one from the rook and one from the king.
The player should know that the king is not in a check position and that the king has never moved before. When performing the castling the empty squares between the king and the rook are not a check position for the king.
The app will only perform the moves and will not verify the conditions of the castling.
On to the code.
When a player moves the rook to the square next to the king (on either side) than we will ask the player if a castling is needed.
For this we write a subroutine asking that question:
If the answer is "yes" than the castling subroutine is executed.
Private Sub castling_question(crrowcol As String) Dim answ As Object = xui.Msgbox2Async("Perform castling?","Castling","yes","","no",Null) Wait For (answ) Msgbox_Result (Result As Int) If Result = xui.DialogResponse_Positive Then xui.MsgboxAsync("Castling in progress...","Castling") castlingstr = "-O" Private crrow As Int = crrowcol.SubString2(0,1) Private crcol As Int = crrowcol.SubString(1) castling(crrow,crcol) refresh_board show_board_log End If End Sub Private Sub castling(rrow As Int, rcol As Int) Log("castling: " & rrow & " " & rcol) If rrow = 0 And rcol = 3 And board(0,4) = "BK1" Then ' long black king board(0,2) = "BK1" board(0,4) = "EEE" End If If rrow = 0 And rcol = 5 And board(0,4) = "BK1" Then ' short black king board(0,6) = "BK1" board(0,4) = "EEE" End If If rrow = 7 And rcol = 3 And board(7,4) = "WK1" Then ' long white king board(7,2) = "WK1" board(7,4) = "EEE" End If If rrow = 7 And rcol = 5 And board(7,4) = "WK1" Then ' short white king board(7,6) = "WK1" board(7,4) = "EEE" End If End Sub
The board array is changed for the king and later in the do_move subroutine the move from the rook is performed.
The call to the castling question subroutine is done in the pnl_click subroutine after the line destrowcol = rowcol:
The rook is about to move to one of the castling squares. Then it is time to ask the castling question.
If srctext.SubString2(1,2) = "R" Then If destrowcol.SubString2(0,1) = 0 And srctext.SubString2(0,1) = "B" Then If destrowcol.SubString(1) = 3 Or destrowcol.SubString(1) = 5 Then castling_question(destrowcol) Sleep(3000) End If End If If destrowcol.SubString2(0,1) = 7 And srctext.SubString2(0,1) = "W" Then If destrowcol.SubString(1) = 3 Or destrowcol.SubString(1) = 5 Then castling_question(destrowcol) Sleep(3000) End If End If End If
The sleep command pauses the app to make sure that the move of the rook and the addition of the note are performed.
To clear the castling string (and the other special move strings) we add the lines above the switch_turn call in the pnl_Click subroutine:
Here's an example of castling:
castlingstr = "" inpassingstr = "" promostr = ""
2. In passingWhen a white pawn is on row 3 and the black pawn has just moved next to the white pawn on row 3 then the white pawn can take the black pawn as if it was on row 2 diagonal. This situation is the same for the black pawn and row 4 and row 5 diagonal.
In the pawn_hints subroutine the squares that can be used to perform in passing are already in place.
The pawn of the opposite color needs to be taken from the square one row up or down and in the same column.
This we do in the do_move subroutine below the taken test and above the board array adjustment:
If drow = 2 And srctext.StartsWith("WP") And board((drow+1),dcol).StartsWith("BP") Then add_piece_to_pnltaken(board((drow+1),dcol),imagemap.Get(board((drow+1),dcol))) board((drow+1),dcol) = "EEE" take = "x" inpassingstr = "ep" End If If drow = 5 And srctext.StartsWith("BP") And board((drow-1),dcol).StartsWith("WP") Then add_piece_to_pnltaken(board((drow-1),dcol),imagemap.Get(board((drow-1),dcol))) board((drow-1),dcol) = "EEE" take = "x" inpassingstr = "ep" End If
3. PromotionWhen a pawn reaches the other side of the board (row 0 for a white pawn or row 7 for a black pawn) then that pawn can be promoted to a queen (or rook or bishop or knight).
In this app the pawn is replaced by a queen of the same color by default.
If you want the player to have a choice than you can write a subroutine to ask which piece should be used for promotion.
In the do_move subroutine above the call to the add_note_to_clvinfo subroutine you can add the following code:
Here's an example what happens when a pawn reaches the other side of the board:
If drow = 0 And srctext.StartsWith("WP") Then board(drow,dcol) = "WQ1" promostr = "=Q" End If If drow = 7 And srctext.StartsWith("BP") Then board(drow,dcol) = "BQ1" promostr = "=Q" End If
4. King's checkTo determine if a king piece is in a check position depends on a lot of factors.
Is there a piece directly threatening the king piece?
Is there a piece that is pinned between the king piece and a piece from the other player and that piece is moved?
Can the king piece move to a square where it is not in a check position?
Is the king piece in a stalemate situation and no other pieces from the same color can move?
Is the king in a checkmate position?
The app doesn't give an answer to all these questions.
The app shows a check situation resulting from a move of a piece from the opposite color player and that piece threatens the king piece.
A check_indication subroutine can show if a king piece is in a check position.
The bkrowcol and wkrowcol string variables hold the position of the king on the board.
Private Sub check_indication Private pcscolor As String = srctext.SubString2(0,1) Private pcsletter As String = srctext.SubString2(1,2) hintslst.Clear hintslst = get_hints(destrowcol,pcscolor,pcsletter) Private chrowcol As String If pcscolor = "W" Then chrowcol = bkrowcol ' black king position If pcscolor = "B" Then chrowcol = wkrowcol ' white king position Log("check indication: " & hintslst) If hintslst.IndexOf(chrowcol) <> -1 And pcsletter <> "K" Then Log("king check!") xui.MsgboxAsync("King check!","Check") Private pnlcheck As Panel = get_board_panel(destrowcol,pnlmain) cnvscell.Initialize(pnlcheck) show_cell_border(Colors.Red,10dip,cnvscell) Private pnlcheck As Panel = get_board_panel(chrowcol,pnlmain) cnvscell.Initialize(pnlcheck) show_cell_border(Colors.Red,10dip,cnvscell) End If hintslst.Clear End Sub
To update the positions of the kings we add 2 lines of code in the resfresh_board subroutine (in the inner loop above the next line):
We can call the check_indication subroutine in the pnl_Click subroutine above the line clickcnt = 0:
If board(r,c) = "BK1" Then bkrowcol = r&c If board(r,c) = "WK1" Then wkrowcol = r&c
Here's an example of a check situation: