-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHuoChess09923.java
More file actions
5254 lines (4417 loc) · 275 KB
/
HuoChess09923.java
File metadata and controls
5254 lines (4417 loc) · 275 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Project/Maven2/JavaApp/src/main/java/${packagePath}/${mainClassName}.java to edit this template
*/
package harmoniaphilosophica.com.huochess09923;
import java.util.Scanner;
/**
*
* @author skako
*/
public class HuoChess09923 {
// Huo Chess by Spiros Kakos (2018)
// License: Reuse the code as you please, as long as you mention the author and where you first read it!
// Declare variables
// Player color
public static String m_PlayerColor;
// Who plays
public static String m_WhoPlays;
// Move related variables
public static String playerMove;
public static String movingPiece;
public static String startingColumn;
public static String startingRank;
public static String finishingColumn;
public static String finishingRank;
public static int startingRankNum;
public static int finishingRankNum;
public static int startingColumnNum;
public static int finishingColumnNum;
public static boolean moveValidity;
public static boolean moveLegality;
// Additional variables for check legality of move
public static int p, h;
public static int how_to_move_Rank = 0;
public static int how_to_move_Column = 0;
public static boolean m_WrongColumn;
public static boolean exit_elegxos_nomimothtas;
public static boolean enpassant_occured;
public static String ProsorinoKommati_KingCheck;
public static boolean WhiteKingCheck;
public static boolean BlackKingCheck;
public static int WhiteKingColumn;
public static int WhiteKingRank;
public static int BlKingColumn;
public static int BlKingRank;
public static boolean DangerFromRight;
public static boolean DangerFromLeft;
public static boolean DangerFromUp;
public static boolean DangerFromDown;
public static boolean DangerFromUpRight;
public static boolean DangerFromDownLeft;
public static boolean DangerFromDownRight;
public static boolean DangerFromUpLeft;
// Variables to store the best move
public static boolean bestMoveFound;
public static int Best_Move_StartingColumnNumber;
public static int Best_Move_StartingRank;
public static int Best_Move_FinishingColumnNumber;
public static int Best_Move_FinishingRank;
// Variables to store the score
public static double tempScore;
public static double bestScore;
// The chessboard
//public static String[][] Skakiera = new String[8][8];
public static String[][] drawChessBoard = new String[8][8];
// The tool used to read the input from the user
static Scanner reader = new Scanner(System.in);
//v0.992
public static int Move_Number_Global;
////////////////////////////////////////////////////////////////////////////////////////////////////////
// DECLARE VARIABLES (v0.970: Sanitization)
////////////////////////////////////////////////////////////////////////////////////////////////////////
//C# TO JAVA CONVERTER WARNING: The java.io.OutputStreamWriter constructor does not accept all the arguments passed to the System.IO.StreamWriter constructor:
//ORIGINAL LINE: public static StreamWriter huo_sw1 = new StreamWriter("Minimax_Thought_Process.txt", true);
// public static OutputStreamWriter huo_sw1 = new OutputStreamWriter("Minimax_Thought_Process.txt");
//C# TO JAVA CONVERTER WARNING: The java.io.OutputStreamWriter constructor does not accept all the arguments passed to the System.IO.StreamWriter constructor:
//ORIGINAL LINE: public static StreamWriter huo_sw_attackers = new StreamWriter("Attackers.txt", true);
// public static OutputStreamWriter huo_sw_attackers = new OutputStreamWriter("Attackers.txt");
// New writers for logging the attackers, the defenders and the dangerous squares
//public static StreamWriter huo_sw_defenders = new StreamWriter("Defenders.txt", true);
//public static StreamWriter huo_sw_dangerous = new StreamWriter("Dangerous.txt", true);
public static String NextLine;
public static String FinalPositions;
//v0.990
public static String ThisIsStupidMove = "N";
public static boolean Danger_for_piece;
public static boolean ThereIsCheck;
//Is it possible to eat a piece of greater value?
public static boolean possibility_to_eat;
public static int ValueOfKommati = 0;
public static int ValueOfTargetPiece = 0;
// Chessboard for logging purposes
public static String[][] SkakieraLog = new String[8][8]; // Δήλωση πίνακα που αντιπροσωπεύει τη σκακιέρα
//v0.980: Change small Strings to Int
//0 = Not dangerous square
//1 = Dangerous square
public static int[][] Skakiera_Dangerous_Squares = new int[8][8];
//v0.990: New dangerous squares check to see if the computer moves his pieve into a square,
//where the only defender was the same moving piece! (and there exists an attacker of course...)
//public static int[,] Skakiera_Dangerous_Squares_2 = new int[8, 8];
public static int[][] Number_of_defenders = new int[8][8];
public static int[][] Number_of_attackers = new int[8][8];
//v0.980: Removed Attackers_coordinates_column/ rank since they are not used!
//public static int[,] Attackers_coordinates_column = new int[8, 8];
//public static int[,] Attackers_coordinates_rank = new int[8, 8];
public static int[][] Value_of_defenders = new int[8][8];
public static int[][] Value_of_attackers = new int[8][8];
//v0.980: Removed Exception_defender_column/ rank since they are not used!
//public static int[,] Exception_defender_column = new int[8, 8];
//public static int[,] Exception_defender_rank = new int[8, 8];
// Parameter which determined the weight of danger in the counting of the score of positions
//v0.980: Removed humanDangerParameter and computerDangerParameter
//public static int humanDangerParameter = 0;
//public static int computerDangerParameter = 1;
// Is it possible to eat back the piece that was moved by the computer?
public static boolean possibility_to_eat_back;
//v0.970 added
public static int ValueOfHumanMovingPiece = 0;
public static int ValueOfMovingPiece = 0;
// Variables to store the scores of positions during the analysis
//v0.970: Changed them to integers
public static int Temp_Score_Move_0;
public static int Temp_Score_Move_1_human;
public static int Temp_Score_Move_2;
public static int Temp_Score_Move_3_human;
public static int Temp_Score_Move_4;
public static int Temp_Score_Move_5_human;
public static int Temp_Score_Move_6;
// 0.970
// These arrays will hold the Minimax analysis nodes data (skakos)
// Dimension ,1: For the score
// Dimension ,2: For the parent
// Dimensions 3-6: For the initial move starting/ finishing columns-ranks (only for the 0-level array)
// Changed them to integers for less memory usage
//v0.980: Reduced size of arrays
public static int[][] NodesAnalysis0 = new int[1000000][6];
public static int[][] NodesAnalysis1 = new int[1000000][2];
public static int[][] NodesAnalysis2 = new int[1000000][2];
public static int[][] NodesAnalysis3 = new int[10000000][2];
public static int[][] NodesAnalysis4 = new int[10000000][2];
// v0.990 Move 4 changes
// These variables cannot be activated.
// If they are activated, the program does not start.
// (a memory limitation problem?)
// public static int[][] NodesAnalysis3 = new int[10000000][2];
// public static int[][] NodesAnalysis4 = new int[100000000][2]; // Increased depth => Increased size (logical...)
// public static String[] NodesAnalysis0_Move = new String[1000000]; //v0.990
// public static String[] NodesAnalysis1_Move = new String[1000000]; //v0.990
// public static String[] NodesAnalysis2_Move = new String[1000000]; //v0.990
// //public static String[] NodesAnalysis3_Move = new String[1000000]; //v0.990
// //public static String[] NodesAnalysis4_Move = new String[1000000]; //v0.990
// public static String[][][] NodesAnalysis0_Chessboard = new String[8][8][1000000]; //v0.990
// public static String[][][] NodesAnalysis1_Chessboard = new String[8][8][1000000]; //v0.990
// public static String[][][] NodesAnalysis2_Chessboard = new String[8][8][1000000]; //v0.990
// public static String[][][] NodesAnalysis2_Chessboard_2 = new String[8][8][1000000]; //v0.990
// public static String[][][] NodesAnalysis4_Chessboard_4 = new String[8][8][1000000]; //v0.990
// //public static String[,,] NodesAnalysis3_Chessboard = new String[8, 8, 1000000]; //v0.990
// //public static String[,,] NodesAnalysis4_Chessboard = new String[8, 8, 1000000]; //v0.990
// public static String[][][] NodesAnalysis0_Chessboard_before = new String[8][8][1000000]; //v0.990
// public static String[][][] NodesAnalysis1_Chessboard_before = new String[8][8][1000000]; //v0.990
// public static String[][][] NodesAnalysis2_Chessboard_before = new String[8][8][1000000]; //v0.990
// //public static String[,,] NodesAnalysis3_Chessboard_before = new String[8, 8, 1000000]; //v0.990
//public static String[,,] NodesAnalysis4_Chessboard_before = new String[8, 8, 1000000]; //v0.990
//public static int[,] NodesAnalysis3 = new int[1000000, 2];
public static int Nodes_Total_count;
public static int NodeLevel_0_count;
public static int NodeLevel_1_count;
public static int NodeLevel_2_count;
public static int NodeLevel_3_count;
public static int NodeLevel_4_count;
public static int NodeLevel_5_count;
public static int NodeLevel_6_count;
// If Hu eats a piece, then make the square a preferred target!!!
public static int Human_last_move_target_column;
public static int Human_last_move_target_row;
// The chessboard (=skakiera in Greek)
public static String[][] Skakiera = new String[8][8]; // Δήλωση πίνακα που αντιπροσωπεύει τη σκακιέρα
public static String[][] Skakiera_Thinking_init = new String[8][8];
// Variable which determines of the program will show the inner
// thinking process of the AI. Good for educational purposes!!!
// UNCOMMENT TO SHOW INNER THINKING MECHANISM!
//bool huo_debug;
// Arrays to use in ComputerMove function
// Penalty for moving the only piece that defends a square to that square (thus leavind the defender
// alone in the square he once defended, defenceless!)
// This penalty is also used to indicate that the computer loses its Queen with the move analyzed
//v0.980: Removed. It wa not used.
//public static bool Danger_penalty;
//public static String m_PlayerColor;
//v0.980
//public static String m_ComputerLevel = "Kakos";
//public static String m_WhoPlays;
public static String m_WhichColorPlays;
public static String MovingPiece;
// Variable to store temporarily the piece that is moving
public static String ProsorinoKommati;
//public static String ProsorinoKommati_KingCheck;
// Variables to check the legality of the move
//public static boolean exit_elegxos_nomimothtas = false;
//public static int h;
//public static int p;
//public static int how_to_move_Rank;
//public static int how_to_move_Column;
public static boolean KingCheck = false;
// Coordinates of the starting square of the move
public static String m_StartingColumn;
public static int m_StartingRank;
public static String m_FinishingColumn;
public static int m_FinishingRank;
// Variable for en passant moves
//public static boolean enpassant_occured;
// Move number
public static int Move;
//v0.980
public static int number_of_moves_analysed;
// Variable to show if promotion of a pawn occured
public static boolean Promotion_Occured = false;
// Variable to show if castrling occured
public static boolean Castling_Occured = false;
public static boolean White_Castling_Occured = false;
public static boolean Black_Castling_Occured = false;
//v0.9921: The code is used again for castling!
public static boolean White_King_Moved = false;
public static boolean Black_King_Moved = false;
public static boolean Castling_Move = false;
// Variables to help find out if it is legal for the computer to perform castling
//v0.980: Removed all that code! It was not used anyway!
//public static bool White_King_Moved = false;
//public static bool Bl_King_Moved = false;
//public static bool White_Rook_a1_Moved = false;
//public static bool White_Rook_h1_Moved = false;
//public static bool Bl_Rook_a8_Moved = false;
//public static bool Bl_Rook_h8_Moved = false;
//v0.980: Removed unsused variables.
//public static bool Can_Castle_Big_White;
//public static bool Can_Castle_Big_Bl;
//public static bool Can_Castle_Small_White;
//public static bool Can_Castle_Small_Bl;
// If it possible to eat the queen of the opponent, go for it!
// v0.980: removed since it was not used
//public static bool go_for_it;
// Variables to show where the kings are in the chessboard
//public static int WhiteKingColumn;
//public static int WhiteKingRank;
//public static int BlKingColumn;
//public static int BlKingRank;
// Variables to show if king is in check
//public static boolean WhiteKingCheck;
//public static boolean BlackKingCheck;
// Variables to show if there is a possibility for mate
//public static bool WhiteMate = false;
//public static bool BlMate = false;
//public static bool Mate;
// Variable to show if a move is found for the H/Y to do
public static boolean Best_Move_Found;
// Variables to help find if a king is under check.
// (see CheckForWhiteCheck and CheckForBlackCheck functions)
//public static boolean DangerFromRight;
//public static boolean DangerFromLeft;
//public static boolean DangerFromUp;
//public static boolean DangerFromDown;
//public static boolean DangerFromUpRight;
//public static boolean DangerFromDownRight;
//public static boolean DangerFromUpLeft;
//public static boolean DangerFromDownLeft;
// Initial coordinates of the two kings
// (see CheckForWhiteCheck and CheckForBlackCheck functions)
public static int StartingWhiteKingColumn;
public static int StartingWhiteKingRank;
public static int StartingBlKingColumn;
public static int StartingBlKingRank;
// Volumn number inserted by the user
public static int m_StartingColumnNumber;
public static int m_FinishingColumnNumber;
///////////////////////////////////////////////////////////////////////////////////////////////////
// Μεταβλητές για τον έλεγχο της "ορθότητας" και της "νομιμότητας" μιας κίνησης του χρήστη
// Variables to check the correctess (ορθότητα) and the legality (νομιμότητα) of the moves
///////////////////////////////////////////////////////////////////////////////////////////////////
// Variable for the correctness of the move
public static boolean m_OrthotitaKinisis;
// Variable for the legality of the move
public static boolean m_NomimotitaKinisis;
// Has the user entered a wrong column?
//public static boolean m_WrongColumn;
// Variables for 'For' loops
public static int i;
public static int j;
// User choices
public static int ApophasiXristi = 1;
public static int choise_of_user;
//////////////////////////////////////
// Computer Thought
//////////////////////////////////////
// Chessboards used for the computer throught
public static String[][] Skakiera_Move_0 = new String[8][8]; // Δήλωση πίνακα που αντιπροσωπεύει τη σκακιέρα
public static String[][] Skakiera_Move_After = new String[8][8];
public static String[][] Skakiera_Thinking = new String[8][8];
public static String[][] Skakiera_CM_Check = new String[8][8];
// Rest of variables used for computer thought
//public static double Best_Move_Score;
public static int Current_Move_Score;
//public static int Best_Move_StartingColumnNumber;
//public static int Best_Move_FinishingColumnNumber;
//public static int Best_Move_StartingRank;
//public static int Best_Move_FinishingRank;
public static int Move_Analyzed;
public static boolean Stop_Analyzing;
public static int Thinking_Depth;
public static int m_StartingColumnNumber_HY;
public static int m_FinishingColumnNumber_HY;
public static int m_StartingRank_HY;
public static int m_FinishingRank_HY;
public static boolean First_Call;
public static String Who_Is_Analyzed;
public static String MovingPiece_HY;
// For writing the computer move
public static String HY_Starting_Column_Text;
public static String HY_Finishing_Column_Text;
// Variables which help find the best move of the Hu-opponent during the HY thought analysis
//v0.980 removed
//public static bool First_Call_Human_Thought;
//public static String MovingPiece_Human = "";
//public static int m_StartingColumnNumber_Human = 1;
//public static int m_FinishingColumnNumber_Human = 1;
//public static int m_StartingRank_Human = 1;
//public static int m_FinishingRank_Human = 1;
// Coordinates of the square Where the player can perform en passant
public static int enpassant_possible_target_rank;
public static int enpassant_possible_target_column;
//v0.980: Removed unused variables
// Is there a possible mate?
//public static bool Human_is_in_check;
//public static bool Possible_mate;
// Does the HY moves its King with the move it is analyzing?
//public static bool moving_the_king;
//v0.992
public static String prev_MovingPiece;
public static int prev_Best_Move_StartingColumnNumber;
public static int prev_Best_Move_StartingRank;
public static boolean Human_Move_Found;
public static boolean Pat_Found;
public static boolean Mate_Found;
public static int m_StartingColumnNumber_mate;
public static int m_FinishingColumnNumber_mate;
public static int m_StartingRank_mate;
public static int m_FinishingRank_mate;
///////////////////////////////////////////////////////////////////////////////////////////////////
// END OF VARIABLES DECLARATION
///////////////////////////////////////////////////////////////////////////////////////////////////
public static void main(String[] args) {
//Thinking_Depth = 2;
Thinking_Depth = 4;
// Ask for the color the player wants to play with
System.out.println("Huo Chess v0.991 by Spiros Kakos");
System.out.println("Please choose color (w/b)");
m_PlayerColor = reader.next();
//m_PlayerColor = reader.next();
// Initialize variables
//v0.9921
White_King_Moved = false;
Black_King_Moved = false;
White_Castling_Occured = false;
Black_Castling_Occured = false;
// Print the choice of the player
// System.out.println("Your choice: " + m_PlayerColor);
// Transform w and b to White and Black and print again (not needed, just to show how the if command works)
if (m_PlayerColor.equals("w"))
System.out.println("Your color : " + "White");
else if (m_PlayerColor.equals("b"))
System.out.println("Your color : " + "Black");
else
System.out.println("Invalid choice");
if (m_PlayerColor.equals("w"))
{
// Human player plays
m_WhoPlays = "human";
// Call the function which sets up the initial position
startingPosition();
// Call the function which draws the position
drawPosition();
// Call the function which asks from the user to enter his move
EnterMove();
}
if (m_PlayerColor.equals("b"))
{
// Call the function which sets up the initial position
startingPosition();
// Call the function to start the computer thinking
Move_Analyzed = 0;
Stop_Analyzing = false;
First_Call = true;
Best_Move_Found = false;
Who_Is_Analyzed = "HY";
m_WhichColorPlays = "White";
ComputerMove(Skakiera);
}
}
// Function which sets up the initial chessboard position
public static void startingPosition() {
// Note that chessboard ranks and columns numbers start from 0
// i = Column (starting from 0)
// j = Rank (starting from 0)
for (int i = 7; i > -1; i--)
{
for (int j = 7; j > -1; j--)
{
// Clear the chessboard
Skakiera[i][j] = "";
}
}
// Put the pieces in the chessboard (e.g. WR for White Rook)
Skakiera[0][0] = "WR";
Skakiera[0][1] = "WP";
Skakiera[1][0] = "WN";
Skakiera[1][1] = "WP";
Skakiera[2][0] = "WB";
Skakiera[2][1] = "WP";
Skakiera[3][0] = "WQ";
Skakiera[3][1] = "WP";
Skakiera[4][0] = "WK";
Skakiera[4][1] = "WP";
Skakiera[5][0] = "WB";
Skakiera[5][1] = "WP";
Skakiera[6][0] = "WN";
Skakiera[6][1] = "WP";
Skakiera[7][0] = "WR";
Skakiera[7][1] = "WP";
// Put the black pieces as well
Skakiera[0][7] = "BR";
Skakiera[0][6] = "BP";
Skakiera[1][7] = "BN";
Skakiera[1][6] = "BP";
Skakiera[2][7] = "BB";
Skakiera[2][6] = "BP";
Skakiera[3][7] = "BQ";
Skakiera[3][6] = "BP";
Skakiera[4][7] = "BK";
Skakiera[4][6] = "BP";
Skakiera[5][7] = "BB";
Skakiera[5][6] = "BP";
Skakiera[6][7] = "BN";
Skakiera[6][6] = "BP";
Skakiera[7][7] = "BR";
Skakiera[7][6] = "BP";
}
// Function to draw the chessboard position
// It simply prints the pieces, nothing fancy
public static void drawPosition() {
// Transform chessboard to the drawChessBoard
// by adding spaces in the empty squares.
// This allows the program to draw a decent chessboard.
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
if (!Skakiera[i][j].equals(""))
drawChessBoard[i][j] = Skakiera[i][j];
else if (Skakiera[i][j].equals(""))
drawChessBoard[i][j] = " ";
}
}
// Print an empty line to separate the printed chessboard from the previous text in the screen
System.out.println("");
// Print one rank at a time
//for (int i = 7; i > -1; i--)
//{
// System.out.println(
// "[" + Skakiera[0][i] + "]" +
// "[" + Skakiera[1][i] + "]" +
// "[" + Skakiera[2][i] + "]" +
// "[" + Skakiera[3][i] + "]" +
// "[" + Skakiera[4][i] + "]" +
// "[" + Skakiera[5][i] + "]" +
// "[" + Skakiera[6][i] + "]" +
// "[" + Skakiera[7][i] + "]"
// );
//}
System.out.println(
"-------------------------");
// Print one rank at a time
for (int i = 7; i > -1; i--)
{
System.out.println(
"|" + drawChessBoard[0][i] +
"|" + drawChessBoard[1][i] +
"|" + drawChessBoard[2][i] +
"|" + drawChessBoard[3][i] +
"|" + drawChessBoard[4][i] +
"|" + drawChessBoard[5][i] +
"|" + drawChessBoard[6][i] +
"|" + drawChessBoard[7][i] + "|"
);
System.out.println(
"-------------------------");
}
}
// Function which asks for the user to enter his move
public static void EnterMove() {
System.out.println("");
System.out.println("Enter move (e.g. c2c4) and press Enter. Enter 'q' to quit.");
// Read the move the user inputs
playerMove = reader.next();
// Break the move entered in starting and finishing columns and ranks
startingColumn = Character.toString( playerMove.charAt(0) );
startingRank = Character.toString( playerMove.charAt(1) );
finishingColumn = Character.toString( playerMove.charAt(2) );
finishingRank = Character.toString( playerMove.charAt(3) );
if(playerMove.equals("q"))
System.exit(0);
System.out.println("Move : " + startingColumn + startingRank + " -> " + finishingColumn + finishingRank);
// Convert characters to numbers for the program to be able to process them
startingRankNum = Integer.valueOf(startingRank);
finishingRankNum = Integer.valueOf(finishingRank);
switch (startingColumn)
{
case "a":
startingColumnNum = 1; break;
case "b":
startingColumnNum = 2; break;
case "c":
startingColumnNum = 3; break;
case "d":
startingColumnNum = 4; break;
case "e":
startingColumnNum = 5; break;
case "f":
startingColumnNum = 6; break;
case "g":
startingColumnNum = 7; break;
case "h":
startingColumnNum = 8; break;
}
switch (finishingColumn)
{
case "a":
finishingColumnNum = 1; break;
case "b":
finishingColumnNum = 2; break;
case "c":
finishingColumnNum = 3; break;
case "d":
finishingColumnNum = 4; break;
case "e":
finishingColumnNum = 5; break;
case "f":
finishingColumnNum = 6; break;
case "g":
finishingColumnNum = 7; break;
case "h":
finishingColumnNum = 8; break;
}
// Store the moving piece in the relative variable
movingPiece = Skakiera[(startingColumnNum-1)][(startingRankNum-1)];
System.out.println("Piece: " + movingPiece);
System.out.println("Move : " + startingColumnNum + startingRankNum + " -> " + finishingColumnNum + finishingRankNum);
//movingPiece = Skakiera[(startingRankNum-1)][(startingColumnNum-1)];
// Just a test to show how if statement is working
// if ((startingRankNum == finishingRankNum) || (startingColumnNum == finishingColumnNum))
// System.out.println("Test 1!");
// Call the function which checks for move legality.
// There result of the check will be returned to the variable moveLegality
// The parameters passed over to the function are the starting and finishing ranks and columns plus the moving piece
m_WhoPlays = "Human";
m_WrongColumn = false;
//V0.9921
Castling_Move = false;
//v0.9921: Code for castling
if (MovingPiece.equals("WK"))
White_King_Moved = true;
else if (MovingPiece.equals("BK"))
Black_King_Moved = true;
// v0.992: Pawn promotion is checked once centrally through pawn promotion function PawnPromotion()!!
// However this is needed here so as to calculate correctly the value of the human piece!
// So since I do this here, the PawnPromotion() call is not needed... :P
// v0.990
// Promotion
if ((MovingPiece.equals("WP")) && (m_FinishingRank == 8))
MovingPiece = "WQ";
if ((MovingPiece.equals("BP")) && (m_FinishingRank == 1))
MovingPiece = "BQ";
// Check if castling occured (so as to move the rook next to the moving king)
// v0.9921: Simplified code
if (m_PlayerColor.equals("w"))
{
//MessageBox.Show("Checkpoint 1.5");
if ((MovingPiece.equals("WK")) &&
(m_StartingColumnNumber == 5) &&
(m_StartingRank == 1) &&
(m_FinishingColumnNumber == 7) &&
(m_FinishingRank == 1))
{
Skakiera[(5)][(0)] = "WR";
Skakiera[(7)][(0)] = "";
White_Castling_Occured = true;
//MessageBox.Show( "Ο λευκός κάνει μικρό ροκε." );
}
else if ((MovingPiece.equals("WK")) &&
(m_StartingColumnNumber == 5) &&
(m_StartingRank == 1) &&
(m_FinishingColumnNumber == 3) &&
(m_FinishingRank == 1))
{
Skakiera[(3)][(0)] = "WR";
Skakiera[(0)][(0)] = "";
White_Castling_Occured = true;
//MessageBox.Show( "Ο λευκός κάνει μεγάλο ροκε." );
}
}
else if (m_PlayerColor.equals("b"))
{
if ((MovingPiece.equals("BK")) &&
(m_StartingColumnNumber == 5) &&
(m_StartingRank == 8) &&
(m_FinishingColumnNumber == 7) &&
(m_FinishingRank == 8))
{
Skakiera[(5)][(7)] = "BR";
Skakiera[(7)][(7)] = "";
Black_Castling_Occured = true;
//MessageBox.Show( "Ο μαύρος κάνει μικρό ροκε." );
}
else if ((MovingPiece.equals("BK")) &&
(m_StartingColumnNumber == 5) &&
(m_StartingRank == 8) &&
(m_FinishingColumnNumber == 3) &&
(m_FinishingRank == 8))
{
Skakiera[(3)][(7)] = "BR";
Skakiera[(0)][(7)] = "";
Black_Castling_Occured = true;
//MessageBox.Show( "Ο μαύρος κάνει μεγάλο ροκε." );
}
}
// Call the function which checks the move's legality
// startingRankNum = startingRankNum + 1;
// startingColumnNum = startingColumnNum + 1;
// finishingRankNum = finishingRankNum + 1;
// finishingColumnNum = finishingColumnNum + 1;
moveValidity = ElegxosOrthotitas(Skakiera, 0, startingRankNum, startingColumnNum, finishingRankNum, finishingColumnNum, movingPiece);
moveLegality = ElegxosNomimotitas(Skakiera, 0, startingRankNum, startingColumnNum, finishingRankNum, finishingColumnNum, movingPiece);
//v0.9921: If castling, then Orthotita is also OK!
if (Castling_Move == true)
{
moveValidity = true;
moveLegality = true;
}
if ((moveValidity == true) && (moveLegality == true))
{
System.out.println("Valid move");
// Do the move
Skakiera[(finishingColumnNum-1)][(finishingRankNum-1)] = movingPiece;
Skakiera[(startingColumnNum-1)][(startingRankNum-1)] = "";
// Draw the chessboard
drawPosition();
// Call the function to start the computer thinking
Move_Analyzed = 0;
Stop_Analyzing = false;
First_Call = true;
Best_Move_Found = false;
Who_Is_Analyzed = "HY";
m_WhichColorPlays = "Black";
ComputerMove(Skakiera);
}
else
{
System.out.println("Wrong move!");
System.out.println("Castling_Move = " + Castling_Move);
System.out.println("Validity = " + moveValidity);
System.out.println("Legality = " + moveLegality);
}
}
public static void CheckMove(String[][] CMSkakiera, int m_StartingRankCM, int m_StartingColumnNumberCM, int m_FinishingRankCM, int m_FinishingColumnNumberCM, String MovingPieceCM)
{
///#region WriteLog
//huo_sw1.WriteLine("");
//huo_sw1.WriteLine("ChMo -- Entered CheckMove");
//huo_sw1.WriteLine(string.Concat("ChMo -- Depth analyzed: ", Move_Analyzed.ToString()));
//huo_sw1.WriteLine(string.Concat("ChMo -- Number of moves analyzed: ", number_of_moves_analysed.ToString()));
//huo_sw1.WriteLine(string.Concat("ChMo -- Move analyzed: ", m_StartingColumnNumber_HY.ToString(), m_StartingRank_HY.ToString(), " -> ", m_FinishingColumnNumber_HY.ToString(), m_FinishingRank_HY.ToString()));
//huo_sw1.WriteLine(string.Concat("ChMo -- Number of Nodes 0: ", NodeLevel_0_count.ToString()));
//huo_sw1.WriteLine(string.Concat("ChMo -- Number of Nodes 1: ", NodeLevel_1_count.ToString()));
//huo_sw1.WriteLine(string.Concat("ChMo -- Number of Nodes 2: ", NodeLevel_2_count.ToString()));
//huo_sw1.WriteLine(string.Concat("ChMo -- Number of Nodes 3: ", NodeLevel_3_count.ToString()));
//huo_sw1.WriteLine(string.Concat("ChMo -- Number of Nodes 4: ", NodeLevel_4_count.ToString()));
//huo_sw1.WriteLine(string.Concat("ChMo -- Number of Nodes 5: ", NodeLevel_5_count.ToString()));
//huo_sw1.WriteLine(string.Concat("ChMo -- Number of Nodes 6: ", NodeLevel_6_count.ToString()));
//huo_sw1.WriteLine("");
///#endregion WriteLog
String ProsorinoKommatiCM;
for (int iii = 0; iii <= 7; iii++)
{
for (int jjj = 0; jjj <= 7; jjj++)
{
Skakiera_CM_Check[iii][jjj] = CMSkakiera[(iii)][(jjj)];
}
}
number_of_moves_analysed++;
m_WhoPlays = "Human";
m_WrongColumn = false;
// Check correctness of move
m_OrthotitaKinisis = ElegxosOrthotitas(CMSkakiera, 0, m_StartingRankCM, m_StartingColumnNumberCM, m_FinishingRankCM, m_FinishingColumnNumberCM, MovingPieceCM);
// if move is correct, then check the legality also
if (m_OrthotitaKinisis == true)
{
m_NomimotitaKinisis = ElegxosNomimotitas(CMSkakiera, 0, m_StartingRankCM, m_StartingColumnNumberCM, m_FinishingRankCM, m_FinishingColumnNumberCM, MovingPieceCM);
}
// Restore the normal value of the m_WhoPlays
m_WhoPlays = "HY";
//C# TO JAVA CONVERTER TODO TASK: There is no preprocessor in Java:
///#region CheckCheck
// Temporarily move the piece to see if the king will continue to be under check
Skakiera_CM_Check[(m_StartingColumnNumberCM - 1)][(m_StartingRankCM - 1)] = "";
ProsorinoKommatiCM = Skakiera_CM_Check[(m_FinishingColumnNumberCM - 1)][(m_FinishingRankCM - 1)];
// Προσωρινή αποθήκευση του κομματιού που βρίσκεται στο τετράγωνο προορισμού
// (βλ. μετά για τη χρησιμότητα του, εκεί που γίνεται έλεγχος για το αν συνεχίζει να υφίσταται σαχ).
Skakiera_CM_Check[(m_FinishingColumnNumberCM - 1)][(m_FinishingRankCM - 1)] = MovingPieceCM;
//C# TO JAVA CONVERTER TODO TASK: There is no preprocessor in Java:
///#region Remove
//v0.990: Need to check again the dangerous squares? The computer might attempt to move
// his piece to a square where the moving piece was the only defender!
//v0.990 change: The dangerous squares must be checked AGAIN after the move!
//The moving piece might be moving into a dangerous square!
//v0.990 change: Added this section here!
/*
#region DangerousSquares
Danger_for_piece = false;
for (int o1 = 0; o1 <= 7; o1++)
{
for (int p1 = 0; p1 <= 7; p1++)
{
//v0.980: Change small Strings to Int
Skakiera_Dangerous_Squares_2[(o1), (p1)] = 0;
}
}
// Find attackers-defenders
FindAttackers(CMSkakiera);
FindDefenders(CMSkakiera);
// Determine dangerous squares
for (int o1 = 0; o1 <= 7; o1++)
{
for (int p1 = 0; p1 <= 7; p1++)
{
//v0.990 debug
//MessageBox.Show(String.Concat("Number of attackers for ", (o1 + 1).ToString(), (p1 + 1).ToString(), " : ", Number_of_attackers[o1, p1].ToString()));
//MessageBox.Show(String.Concat("Number of defenders for ", (o1 + 1).ToString(), (p1 + 1).ToString(), " : ", Number_of_defenders[o1, p1].ToString()));
//v0.990 change: Changed ">" to ">="
if (Number_of_attackers[o1, p1] >= Number_of_defenders[o1, p1])
//if (Number_of_attackers[o1, p1] > Number_of_defenders[o1, p1])
//v0.980: Change small Strings to Int
Skakiera_Dangerous_Squares_2[(o1), (p1)] = 1;
}
}
#endregion DangerousSquares
if(Skakiera_Dangerous_Squares_2[(m_FinishingColumnNumberCM - 1), (m_FinishingRankCM - 1)] == 1)
m_NomimotitaKinisis = false;
*/
//C# TO JAVA CONVERTER TODO TASK: There is no preprocessor in Java:
///#endregion Remove
//////////////////////////////////////////////////////////////////////////
// is the king still under check?
//////////////////////////////////////////////////////////////////////////
//v0.990
WhiteKingCheck = CheckForWhiteCheck(Skakiera_CM_Check);
//WhiteKingCheck = CheckForWhiteCheck(CMSkakiera);
if ((m_WhichColorPlays.equals("White")) && (WhiteKingCheck == true))
{
m_NomimotitaKinisis = false;
}
///////////////////////////////////////////////////////////////////////////
// is the black king under check?
///////////////////////////////////////////////////////////////////////////
//v0.990
//BlackKingCheck = CheckForBlackCheck(CMSkakiera);
BlackKingCheck = CheckForBlackCheck(Skakiera_CM_Check);
if ((m_WhichColorPlays.equals("Black")) && (BlackKingCheck == true))
{
m_NomimotitaKinisis = false;
}
// Restore pieces to their initial positions
// CMSkakiera[(m_StartingColumnNumberCM - 1), (m_StartingRankCM - 1)] = MovingPieceCM;
// CMSkakiera[(m_FinishingColumnNumberCM - 1), (m_FinishingRankCM - 1)] = ProsorinoKommatiCM;
//C# TO JAVA CONVERTER TODO TASK: There is no preprocessor in Java:
///#endregion CheckCheck
//v0.990: Removed! This is already done in ComputerMove!
/*
if (((m_OrthotitaKinisis == true) && (m_NomimotitaKinisis == true)) && (Move_Analyzed == 0))
{
// Store the move to ***_HY variables (because after continuous calls of ComputerMove the initial move under analysis will be lost...)
MovingPiece_HY = MovingPiece;
m_StartingColumnNumber_HY = m_StartingColumnNumber;
m_FinishingColumnNumber_HY = m_FinishingColumnNumber;
m_StartingRank_HY = m_StartingRank;
m_FinishingRank_HY = m_FinishingRank;
// Store the initial move coordinates (at the node 0 level)
NodesAnalysis0[NodeLevel_0_count, 2] = m_StartingColumnNumber_HY;
NodesAnalysis0[NodeLevel_0_count, 3] = m_FinishingColumnNumber_HY;
NodesAnalysis0[NodeLevel_0_count, 4] = m_StartingRank_HY;
NodesAnalysis0[NodeLevel_0_count, 5] = m_FinishingRank_HY;
// Check is HY eats the opponents queen (so it is preferable to do so...)
// Not operational yet...
//if ((ProsorinoKommati.equals("WQ")) || (ProsorinoKommati.equals("BQ")))
// go_for_it = true;
// v0.970: Danger penalty now checked directly in ComputerMove
}
*/
}
public static void ComputerMove(String[][] Skakiera_Thinking_init)
{
// v0.990 change: The best score for every move will be stored at each level. Only if the new move analyzed
// has a better score than the best score, will it be analyzed (target: trim the analysis tree)
//Move_Analyzed = 0; // NEW
int bestScoreLevel0 = 0;
//V0.990: Initialized the values
int iii = 0;
int jjj = 0;
Temp_Score_Move_0 = 0;
Temp_Score_Move_1_human = 0;
Temp_Score_Move_2 = 0;
Human_last_move_target_column = 0;
Human_last_move_target_row = 0;
MovingPiece = "";
ProsorinoKommati = "";
exit_elegxos_nomimothtas = false;
First_Call = true;
h = 0;
p = 0;
WhiteKingColumn = 0;
WhiteKingRank = 0;
BlKingColumn = 0;
BlKingRank = 0;
DangerFromUp = false;
m_OrthotitaKinisis = false;
m_NomimotitaKinisis = false;
i = 0;
j = 0;
Current_Move_Score = 0;
Best_Move_FinishingColumnNumber = 0;
Best_Move_FinishingRank = 0;
Best_Move_StartingColumnNumber = 0;
Best_Move_StartingRank = 0;
Stop_Analyzing = true;
m_StartingColumnNumber_HY = 0;
m_StartingRank_HY = 0;
m_FinishingColumnNumber_HY = 0;
m_FinishingRank_HY = 0;
enpassant_possible_target_column = 0;
//First_Caenpassant_possible_target_rankll = 0;
//v0.990: Removed the "0" variables.
//String MovingPiece;
//String ProsorinoKommati0;
//int m_StartingColumnNumber;
//int m_FinishingColumnNumber;
//int m_StartingRank;
//int m_FinishingRank;
//v0.990
//String[][] Skakiera_Move_After_0 = new String[8][8];
// If there is a possibility to eat back what was eaten, then go for it!
possibility_to_eat_back = false;
possibility_to_eat = false;
//v0.992
Mate_Found = false;
Pat_Found = false;
m_StartingColumnNumber_mate = 0;
m_FinishingColumnNumber_mate = 0;
m_StartingRank_mate = 0;
m_FinishingRank_mate = 0;
///#region InitializeNodes
// START [MiniMax algorithm - skakos]
NodeLevel_0_count = 0;
NodeLevel_1_count = 0;
NodeLevel_2_count = 0;
//v0.980: Removed unwanted nodes (+total nodes)
NodeLevel_3_count = 0;
NodeLevel_4_count = 0;