Components and supplies
1
M5Stack
Apps and platforms
1
Arduino IDE
Project description
Code
ArduinoMegaChess for M5Stack
arduino
1//ArduinoMega Chess 1.0 M5Stack 2//engine 1.4 3//Sergey Urusov, ususovsv@gmail.com 4 5#include <M5Stack.h> 6#include <Preferences.h> 7 8Preferences prefs; 9 10uint16_t CBLACK,CBLUE,CRED,CGREEN,CCYAN,CMAGENTA,CYELLOW,CWHITE,CGRAY,CDARK,CGRAY2,CBLACKF,CWHITEF,CWHITEFIG,CBLACKFIG,CBLACKCONT; 11 12int cycle=0; // 13const signed char fp=1; 14const signed char fn=2; 15const signed char fb=3; 16const signed char fr=4; 17const signed char fq=5; 18const signed char fk=6; 19const int fig_weight[]={0,100,320,330,500,900,0}; 20const char fig_symb[]=" NBRQK"; 21unsigned long count; 22boolean rotate=false; 23const signed char polezero[8][8] PROGMEM={ 24 { 0, 0, 0, 0, 0, 0, 0, 0}, 25 { 0, 0, 0, 0, 0, 0, 0, 0}, 26 { 0, 0, 0, 0, 0, 0, 0, 0}, 27 { 0, 0, 0, 0, 0, 0, 0, 0}, 28 { 0, 0, 0, 0, 0, 0, 0, 0}, 29 { 0, 0, 0, 0, 0, 0, 0, 0}, 30 { 0, 0, 0, 0, 0, 0, 0, 0}, 31 { 0, 0, 0, 0, 0, 0, 0, 0}, 32 }; 33const signed char polestart[8][8] PROGMEM={ 34 {-fr,-fn,-fb,-fq,-fk,-fb,-fn,-fr}, 35 {-fp,-fp,-fp,-fp,-fp,-fp,-fp,-fp}, 36 { 0, 0, 0, 0, 0, 0, 0, 0}, 37 { 0, 0, 0, 0, 0, 0, 0, 0}, 38 { 0, 0, 0, 0, 0, 0, 0, 0}, 39 { 0, 0, 0, 0, 0, 0, 0, 0}, 40 { fp, fp, fp, fp, fp, fp, fp, fp}, 41 { fr, fn, fb, fq, fk, fb, fn, fr}, 42 }; 43 44signed char pole[8][8]={ // 3 45 {-fr,-fn,-fb,-fq,-fk,-fb,-fn,-fr}, 46 {-fp,-fp,-fp,-fp,-fp,-fp,-fp,-fp}, 47 { 0, 0, 0, 0, 0, 0, 0, 0}, 48 { 0, 0, 0, 0, 0, 0, 0, 0}, 49 { 0, 0, 0, 0, 0, 0, 0, 0}, 50 { 0, 0, 0, 0, 0, 0, 0, 0}, 51 { fp, fp, fp, fp, fp, fp, fp, fp}, 52 { fr, fn, fb, fq, fk, fb, fn, fr}, 53 }; 54 55signed char pole0[8][8]; // 56signed char poledisp[8][8]; // 57signed char polechoice[7]; // 58boolean w00,w000,b00,b000; 59signed char blinkstep; 60typedef struct { 61 signed char fig1, fig2; // 62 signed char x1,y1,x2,y2; // 63 signed char check; // 64 signed char type; // 1- ,2- ,3- ,4-5-6-7- ,,, 65 int weight; // , 66} step_type; 67const int MAXSTEPS=1000; //. 68//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 69int MINDEPTH; //. 70int MAXDEPTH; //. 71int LIMDEPTH; //. 72const signed char MAXCUTS=10; //.. - - (10- , 20) 73boolean TRACE=0; 74boolean solving=false; 75boolean choice=false; 76boolean sound=1; 77short cur_step=1; // , 1.... 78short limit=0; // , 0-2; 79//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 80const long limits[3]={4,15,60}; 81// 0 1 2 82step_type steps[MAXSTEPS]; // 83step_type cuts[MAXCUTS]; // - 84step_type lastbest,lastanimatedgreen; 85int lastscore; 86int minbeta,maxalpha; 87int startweight; 88int cur_level; // () 89int start_var; // , 1.... 90int cur_var; // , 1.... 91int current_var; // , 1.... 92int cur_choice; // 93boolean check_on_table; // 94boolean isstatus; 95signed char WKJ=0,WKI=0,BKJ=0,BKI=0; // 96boolean endspiel=false; // 97signed char progress; // 0-100 98boolean only_action=false; // - 99unsigned long starttime,endtime,limittime,quitime=0; 100int menu=0; // 101unsigned long lastpressed,lastpressedleft,lastpressedright,lastpressedany; 102boolean submenu=0; 103boolean movesload=0; 104boolean isbeta=1; 105boolean hidden=false; 106 107const uint8_t fig[6][72] PROGMEM={ 108{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7E, 0x0, 0x0, 0xFF, 0x0, 1090x0, 0xFF, 0x0, 0x0, 0xFF, 0x0, 0x0, 0x7E, 0x0, 0x0, 0x3C, 0x0, 0x1, 0xFF, 0x80, 0x1, 0xFF, 0x80, 1100x0, 0x3C, 0x0, 0x0, 0x3C, 0x0, 0x0, 0x7E, 0x0, 0x0, 0x7E, 0x0, 0x0, 0xFF, 0x0, 0x1, 0xFF, 0x80, 1110x3, 0xFF, 0xC0, 0x7, 0xFF, 0xE0, 0x7, 0xFF, 0xE0, 0x7, 0xFF, 0xE0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 112}, // 113{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0x0, 0x0, 0xFF, 0x0, 0x1, 0xFF, 0x80, 0x3, 0xFF, 0xC0, 1140x7, 0xFF, 0xE0, 0xF, 0xFF, 0xF0, 0x1F, 0xFF, 0xF8, 0x1F, 0x3F, 0xF8, 0x1E, 0x3F, 0xF8, 0xC, 0x7F, 0xF8, 1150x0, 0xFF, 0xF0, 0x1, 0xFF, 0xE0, 0x1, 0xFF, 0xC0, 0x1, 0xFF, 0x80, 0x1, 0xFF, 0x0, 0x0, 0xFE, 0x0, 1160x0, 0x7E, 0x0, 0x7, 0xFF, 0xE0, 0xF, 0xFF, 0xF0, 0xF, 0xFF, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 117}, // 118{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3C, 0x0, 0x0, 0x7E, 0x0, 0x0, 0x7E, 0x0, 0x0, 0x3C, 0x0, 1190x1, 0xFF, 0x80, 0x3, 0xFF, 0xC0, 0x7, 0xFF, 0xE0, 0x7, 0xFF, 0xE0, 0x7, 0xFF, 0xE0, 0x7, 0xFF, 0xE0, 1200x7, 0xFF, 0xE0, 0x7, 0xFF, 0xE0, 0x7, 0xFF, 0xE0, 0x3, 0xFF, 0xC0, 0x1, 0xFF, 0x80, 0x0, 0xFF, 0x0, 1210x8, 0x7E, 0x10, 0x1C, 0x7E, 0x38, 0x3F, 0xFF, 0xFC, 0x3F, 0xFF, 0xFC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 122}, // 123{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xF, 0x3C, 0xF0, 0xF, 0x3C, 0xF0, 0xF, 0xFF, 0xF0, 0xF, 0xFF, 0xF0, 1240x7, 0xFF, 0xE0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 1250x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 1260x3, 0xFF, 0xC0, 0x7, 0xFF, 0xE0, 0xF, 0xFF, 0xF0, 0xF, 0xFF, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 127}, // 128{0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x3, 0x3C, 0xC0, 0x7, 0x99, 0xE0, 0x33, 0x18, 0xCC, 0x7B, 0x18, 0xDE, 1290x33, 0x18, 0xCC, 0x33, 0x18, 0xCC, 0x33, 0x18, 0xCC, 0x33, 0x18, 0xCC, 0x33, 0x18, 0xCC, 0x33, 0xBD, 0xCC, 1300x1B, 0xBD, 0xD8, 0x1F, 0xFF, 0xF8, 0x1F, 0xFF, 0xF8, 0xF, 0xFF, 0xF0, 0xF, 0xFF, 0xF0, 0x7, 0xFF, 0xE0, 1310x3, 0xFF, 0xC0, 0x7, 0xFF, 0xE0, 0xF, 0xFF, 0xF0, 0xF, 0xFF, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 132}, // 133{0x0, 0x0, 0x0, 0x0, 0x3C, 0x0, 0x0, 0x3C, 0x0, 0x0, 0x3C, 0x0, 0xF, 0x3C, 0xF0, 0x1F, 0xFF, 0xF8, 1340x3F, 0xFF, 0xFC, 0x7F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFE, 1350x7F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFE, 0x3F, 0xFF, 0xFC, 0x1F, 0xFF, 0xF8, 0xF, 0xFF, 0xF0, 0x7, 0xFF, 0xE0, 1360x3, 0xFF, 0xC0, 0x7, 0xFF, 0xE0, 0xF, 0xFF, 0xF0, 0xF, 0xFF, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 137} // 138}; 139const uint8_t fig_cont[6][72] PROGMEM={ 140{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7E, 0x0, 0x0, 0x81, 0x0, 0x1, 0x0, 0x80, 1410x1, 0x0, 0x80, 0x1, 0x0, 0x80, 0x0, 0x81, 0x0, 0x3, 0xC3, 0xC0, 0x2, 0x0, 0x40, 0x2, 0x0, 0x40, 1420x3, 0xC3, 0xC0, 0x0, 0x42, 0x0, 0x0, 0x81, 0x0, 0x0, 0x81, 0x0, 0x1, 0x0, 0x80, 0x2, 0x0, 0x40, 1430x4, 0x0, 0x20, 0x8, 0x0, 0x10, 0x8, 0x0, 0x10, 0x8, 0x0, 0x10, 0xF, 0xFF, 0xF0, 0x0, 0x0, 0x0 144}, // 145{0x0, 0x0, 0x0, 0x0, 0x66, 0x0, 0x0, 0x99, 0x0, 0x1, 0x0, 0x80, 0x2, 0xC0, 0x40, 0x4, 0xC0, 0x20, 1460x8, 0x0, 0x10, 0x10, 0x0, 0x8, 0x20, 0x0, 0x4, 0x20, 0xC0, 0x4, 0x21, 0x40, 0x4, 0x12, 0x80, 0x4, 1470xD, 0x0, 0x8, 0x2, 0x0, 0x10, 0x2, 0x0, 0x20, 0x2, 0x0, 0x40, 0x2, 0x0, 0x80, 0x1, 0x1, 0x0, 1480x7, 0x81, 0xE0, 0x8, 0x0, 0x10, 0x10, 0x0, 0x8, 0x10, 0x0, 0x8, 0x1F, 0xFF, 0xF8, 0x0, 0x0, 0x0 149}, // 150{0x0, 0x0, 0x0, 0x0, 0x3C, 0x0, 0x0, 0x42, 0x0, 0x0, 0x81, 0x0, 0x0, 0x81, 0x0, 0x1, 0xC3, 0x80, 1510x2, 0x18, 0x40, 0x4, 0x18, 0x20, 0x8, 0x18, 0x10, 0x8, 0x18, 0x10, 0x9, 0xFF, 0x90, 0x9, 0xFF, 0x90, 1520x8, 0x18, 0x10, 0x8, 0x18, 0x10, 0x8, 0x18, 0x10, 0x4, 0x18, 0x20, 0x2, 0x18, 0x40, 0x9, 0x0, 0x90, 1530x14, 0x81, 0x28, 0x23, 0x81, 0xC4, 0x40, 0x0, 0x2, 0x40, 0x0, 0x2, 0x7F, 0xFF, 0xFE, 0x0, 0x0, 0x0 154}, // 155{0x0, 0x0, 0x0, 0x1F, 0x3C, 0xF8, 0x10, 0xC3, 0x8, 0x10, 0xC3, 0x8, 0x10, 0x0, 0x8, 0x10, 0x0, 0x8, 1560xB, 0xFF, 0xD0, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 1570x4, 0x0, 0x20, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 1580x4, 0x0, 0x20, 0xB, 0xFF, 0xD0, 0x10, 0x0, 0x8, 0x10, 0x0, 0x8, 0x1F, 0xFF, 0xF8, 0x0, 0x0, 0x0 159}, // 160{0x0, 0x18, 0x0, 0x3, 0x24, 0xC0, 0x4, 0xC3, 0x20, 0x38, 0x66, 0x1C, 0x4C, 0xA5, 0x32, 0x84, 0xA5, 0x21, 1610x4C, 0xA5, 0x32, 0x4C, 0xA5, 0x32, 0x4C, 0xA5, 0x32, 0x4C, 0xA5, 0x32, 0x4C, 0xA5, 0x32, 0x4C, 0x42, 0x32, 1620x24, 0x42, 0x24, 0x20, 0x0, 0x4, 0x20, 0x0, 0x4, 0x10, 0x0, 0x8, 0x10, 0x0, 0x8, 0x8, 0x0, 0x10, 1630x4, 0x0, 0x20, 0xF, 0xFF, 0xF0, 0x10, 0x0, 0x8, 0x10, 0x0, 0x8, 0x1F, 0xFF, 0xF8, 0x0, 0x0, 0x0 164}, // 165{0x0, 0x7E, 0x0, 0x0, 0x42, 0x0, 0x0, 0x42, 0x0, 0xF, 0xC3, 0xF0, 0x10, 0xC3, 0x8, 0x20, 0x7E, 0x4, 1660x40, 0x3C, 0x2, 0x80, 0x18, 0x1, 0x80, 0x18, 0x1, 0x80, 0x18, 0x1, 0x80, 0x18, 0x1, 0x80, 0x18, 0x1, 1670x80, 0x18, 0x1, 0x80, 0x18, 0x1, 0x40, 0x18, 0x2, 0x20, 0x18, 0x4, 0x10, 0x18, 0x8, 0x8, 0x18, 0x10, 1680x4, 0x18, 0x20, 0xB, 0xFF, 0xD0, 0x10, 0x0, 0x8, 0x10, 0x0, 0x8, 0x1F, 0xFF, 0xF8, 0x0, 0x0, 0x0 169} // 170}; 171 172 173const int pos[7][8][8] PROGMEM={ 174 {{ 0, 0, 0, 0, 0, 0, 0, 0}, // 175 {100,100,100,100,100,100,100,100}, //{ 50, 50, 50, 50, 50, 50, 50, 50}, 176 { 20, 30, 40, 50, 50, 40, 30, 20}, //{ 10, 10, 20, 30, 30, 20, 10, 10}, 177 { 5, 5, 10, 25, 25, 10, 5, 5}, 178 { 0, 0, 0, 20, 20, 0, 0, 0}, 179 { 5, -5,-10, 0, 0,-10, -5, 5}, 180 { 5, 10, 10,-20,-20, 10, 10, 5}, //{ 5, 10, 10,-20,-20, 10, 10, 5}, 181 { 0, 0, 0, 0, 0, 0, 0, 0}}, 182 183 {{-50,-40,-30,-30,-30,-30,-40,-50}, // 184 {-40,-20, 0, 0, 0, 0,-20,-40}, 185 {-30, 0, 10, 15, 15, 10, 0,-30}, 186 {-30, 5, 15, 20, 20, 15, 5,-30}, 187 {-30, 0, 15, 20, 20, 15, 0,-30}, 188 {-30, 5, 10, 15, 15, 10, 5,-30}, 189 {-40,-20, 0, 5, 5, 0,-20,-40}, 190 {-50,-40,-30,-30,-30,-30,-40,-50}}, 191 192 {{-20,-10,-10,-10,-10,-10,-10,-20}, // 193 {-10, 0, 0, 0, 0, 0, 0,-10}, 194 {-10, 0, 5, 10, 10, 5, 0,-10}, 195 {-10, 5, 5, 10, 10, 5, 5,-10}, 196 {-10, 0, 10, 10, 10, 10, 0,-10}, 197 {-10, 10, 10, 10, 10, 10, 10,-10}, 198 {-10, 5, 0, 0, 0, 0, 5,-10}, 199 {-20,-10,-10,-10,-10,-10,-10,-20}}, 200 201 {{ 0, 0, 0, 0, 0, 0, 0, 0}, // 202 { 5, 10, 10, 10, 10, 10, 10, 5}, 203 { -5, 0, 0, 0, 0, 0, 0, -5}, 204 { -5, 0, 0, 0, 0, 0, 0, -5}, 205 { -5, 0, 0, 0, 0, 0, 0, -5}, 206 { -5, 0, 0, 0, 0, 0, 0, -5}, 207 { -5, 0, 0, 0, 0, 0, 0, -5}, 208 { 0, 0, 0, 5, 5, 0, 0, 0}}, 209 210 {{-20,-10,-10, -5, -5,-10,-10,-20}, // 211 {-10, 0, 0, 0, 0, 0, 0,-10}, 212 {-10, 0, 5, 5, 5, 5, 0,-10}, 213 { -5, 0, 5, 5, 5, 5, 0, -5}, 214 { 0, 0, 5, 5, 5, 5, 0, -5}, 215 {-10, 5, 5, 5, 5, 5, 0,-10}, 216 {-10, 0, 5, 0, 0, 0, 0,-10}, 217 {-20,-10,-10, -5, -5,-10,-10,-20}}, 218 219 {{-30,-40,-40,-50,-50,-40,-40,-30}, // 220 {-30,-40,-40,-50,-50,-40,-40,-30}, 221 {-30,-40,-40,-50,-50,-40,-40,-30}, 222 {-30,-40,-40,-50,-50,-40,-40,-30}, 223 {-20,-30,-30,-40,-40,-30,-30,-20}, 224 {-10,-20,-20,-20,-20,-20,-20,-10}, 225 { 10, 10,-10,-10,-10,-10, 10, 10}, //{ 20, 20, 0, 0, 0, 0, 20, 20}, 226 { 10, 40, 30, 0, 0, 0, 50, 10}}, //{ 20, 30, 10, 0, 0, 10, 30, 20}}, 227 228 {{-50,-40,-30,-20,-20,-30,-40,-50}, // 229 {-30,-20,-10, 0, 0,-10,-20,-30}, 230 {-30,-10, 20, 30, 30, 20,-10,-30}, 231 {-30,-10, 30, 40, 40, 30,-10,-30}, 232 {-30,-10, 30, 40, 40, 30,-10,-30}, 233 {-30,-10, 20, 30, 30, 20,-10,-30}, 234 {-30,-30, 0, 0, 0, 0,-30,-30}, 235 {-50,-30,-30,-30,-30,-30,-30,-50}} 236}; 237 238//********************************** 239void drawBitmap(int16_t x, int16_t y, 240 const uint8_t *bitmap, int16_t w, int16_t h, 241 uint16_t color) { 242 int16_t i, j, byteWidth = (w + 7) / 8; 243 for(j=0; j<h; j++) { 244 for(i=0; i<w; i++ ) { 245 if(pgm_read_byte(bitmap + j * byteWidth + i / 8) & (128 >> (i & 7))) { 246 M5.Lcd.drawPixel(x+i, y+j, color); 247 } 248 } 249 } 250} 251//**************************** 252uint8_t music[1000]; 253void tone_volume(uint16_t frequency, uint32_t duration) { 254 float interval=0.001257*float(frequency); 255 float phase=0; 256 for (int i=0;i<1000;i++) { 257 music[i]=127+126*sin(phase); 258 phase+=interval; 259 } 260 music[999]=0; 261 int remains=duration; 262 for (int i=0;i<duration;i+=200) { 263 if (remains<200) { 264 music[remains*999/200]=0; 265 } 266 M5.Speaker.playMusic(music,5000); 267 remains-=200; 268 } 269} 270//**************************** 271void beep(int leng) { 272 if (sound) M5.Speaker.setVolume(1); else M5.Speaker.setVolume(0); 273 tone_volume(1000,leng); 274} 275//**************************** 276void definecolors() { 277 CBLACK =0x0000; 278 CBLUE =0x07FF; //0x001F; 279 CRED =0xF800; 280 CGREEN =0x07E0; 281 CCYAN =0x07FF; 282 CMAGENTA=0xF81F; 283 CYELLOW =0xFFE0; 284 CWHITE =0xFFFF; 285 CWHITEFIG =getColor(200,200,140); 286 CGRAY =0x7BEF; 287 CDARK =getColor(32,32,32); 288 CGRAY2 =getColor(16,16,16); 289 CBLACKF =getColor(114,75,0); 290 CWHITEF =getColor(180,114,0); 291 CBLACKFIG =getColor(15,24,8); 292 CBLACKCONT =getColor(160,160,120); 293} 294//**************************** 295uint16_t getColor(uint8_t red, uint8_t green, uint8_t blue) 296{ 297 red >>= 3; 298 green >>= 2; 299 blue >>= 3; 300 return (red << 11) | (green << 5) | blue; 301} 302//**************************** 303void clearstatus() { 304 M5.Lcd.fillRect(240,166,80,20,BLACK); 305 M5.Lcd.drawFastHLine(10,237,220,BLACK); 306 M5.Lcd.drawFastHLine(10,239,220,BLACK); 307} 308//**************************** 309void setup() { 310 Serial.begin(115200); 311 Serial.flush(); 312 Serial.println(F("Start")); 313 M5.begin(); 314 315 prefs.begin("AM_Chess", false); 316 317 M5.Lcd.setBrightness(200); // BRIGHTNESS = MAX 255 318 M5.Lcd.fillScreen(BLACK); // CLEAR SCREEN 319 M5.Lcd.setRotation(0); // SCREEN ROTATION = 0 320 definecolors(); 321 beep(100); 322 for (int i=0;i<MAXSTEPS;i++) { 323 steps[i].x1=0; steps[i].y1=0; 324 steps[i].x2=0; steps[i].y2=0; 325 steps[i].fig1=0; steps[i].fig2=0; 326 steps[i].check=0; 327 steps[i].type=0; 328 steps[i].weight=0; 329 } 330 M5.Lcd.setTextColor(getColor(230,230,200)); 331 M5.Lcd.setTextSize(2); 332 M5.Lcd.setCursor(50,30); M5.Lcd.print("Arduino Mega Chess"); 333 M5.Lcd.setCursor(88,50); M5.Lcd.print("for M5Stack"); 334 M5.Lcd.setTextColor(CGRAY); 335 M5.Lcd.setCursor(62,70); M5.Lcd.print("by Sergey Urusov"); 336 M5.Lcd.setTextSize(1); 337 M5.Lcd.setCursor(100,95); M5.Lcd.print("urusovsv@gmail.com"); 338 M5.Lcd.setCursor(85,110); M5.Lcd.print("version 1.0, engine 1.4"); 339 M5.Lcd.setCursor(80,220); M5.Lcd.print("press any key to READ this"); 340 M5.Lcd.setTextColor(CWHITEFIG); 341 M5.Lcd.drawRect(38,150,60,30,CGRAY); 342 M5.Lcd.drawRect(130,150,60,30,CGRAY); 343 M5.Lcd.drawRect(225,150,60,30,CGRAY); 344 M5.Lcd.setTextSize(1); 345 M5.Lcd.setCursor(57,162); M5.Lcd.print("Left"); 346 M5.Lcd.setCursor(143,162); M5.Lcd.print("Choice"); 347 M5.Lcd.setCursor(240,162); M5.Lcd.print("Right"); 348 M5.Lcd.setCursor(110,190); M5.Lcd.print("long press - menu"); 349 M5.Lcd.setCursor(110,200); M5.Lcd.print("or exit from menu"); 350 351 uint32_t tim=millis(); 352 while (millis()-tim<1500) { 353 M5.update(); 354 if (M5.BtnA.wasPressed()||M5.BtnB.wasPressed()||M5.BtnC.wasPressed()) { 355 beep(100); 356 M5.Lcd.fillRect(75,220,180,12,CBLACK); 357 M5.Lcd.setTextColor(CGRAY); 358 M5.Lcd.setCursor(77,220); M5.Lcd.print("press any key to ENTER game"); 359 while (millis()-tim<30000) { 360 M5.update(); 361 if (M5.BtnA.wasPressed()||M5.BtnB.wasPressed()||M5.BtnC.wasPressed()) break; 362 } 363 break; 364 } 365 } 366 beep(100); 367 M5.Lcd.fillScreen(BLACK); // CLEAR SCREEN 368 initboard(); 369} 370//**************************** 371void initboard() { 372 for (int i=0;i<8;i++) 373 for (int j=0;j<8;j++) poledisp[j][i]=-100; // 374 M5.Lcd.fillScreen(CBLACK); 375 M5.Lcd.setTextColor(CGRAY); 376 M5.Lcd.setTextSize(1); 377 for (int j=1;j<9;j++) { 378 M5.Lcd.setCursor(0,j*28-17); 379 if (rotate) M5.Lcd.print(j); else M5.Lcd.print(9-j); 380 } 381 for (byte i=1;i<9;i++) { 382 M5.Lcd.setCursor(i*28-9,227); 383 if (rotate) M5.Lcd.print(char(96+9-i)); else M5.Lcd.print(char(96+i)); 384 } 385 initscreen(); 386} 387//**************************** 388void initscreen() { 389 show_board(); 390 show_steps(); 391} 392//**************************** 393void loop() { 394 gui(); 395 if (solving) { 396 for (int i=1;i<3;i++) { tone_volume(400+400*i,100); delay(70); } 397 hidden=false; 398 lastscore=solve_step(); 399 float tim=float(millis()-starttime)/1000; 400 for (int i=2;i>=1;i--) { tone_volume(400+400*i,100); delay(70); } 401 if (lastscore>-9000&&lastscore!=8999) { 402 movestep(cur_step); 403 cur_step++; steps[cur_step].fig1=0; 404 } 405 initscreen(); 406 animate_step(cur_step-1,false); 407 clearstatus(); 408 if (lastscore>9000) { 409 M5.Lcd.setTextSize(1); 410 M5.Lcd.setTextColor(CGREEN,CBLACK); 411 M5.Lcd.setCursor(260,176); 412 if (lastscore<9999) { 413 M5.Lcd.print("# in "); 414 M5.Lcd.print((9999-lastscore)/2+1); M5.Lcd.print(F(" st")); 415 } else M5.Lcd.print("Checkmate"); 416 } else if (lastscore<-9000) { 417 M5.Lcd.setTextSize(1); 418 M5.Lcd.setTextColor(CRED,CBLACK); 419 M5.Lcd.setCursor(260,176); 420 steps[cur_step].fig1=0; 421 M5.Lcd.print("GIVE UP!"); 422 show_steps(); 423 } else if (lastscore==8999) { //Draw 424 M5.Lcd.setTextSize(1); 425 M5.Lcd.setTextColor(CYELLOW); 426 M5.Lcd.setCursor(260,176); 427 M5.Lcd.print("Draw"); 428 } 429 M5.Lcd.setTextSize(1); 430 M5.Lcd.setTextColor(CGRAY); 431 M5.Lcd.setCursor(240,176); 432 M5.Lcd.print(tim,0); 433 M5.Lcd.print("s "); 434 if (abs(lastscore)<5000) { 435 M5.Lcd.print(lastscore); 436 } 437 M5.Lcd.setCursor(240,166); 438 M5.Lcd.print(count); 439 M5.Lcd.print("pos"); 440 Serial.print(F("Positions estimated=")); Serial.println(count); 441 Serial.print(F("Time=")); Serial.print(tim,1); Serial.println("s"); 442 Serial.print(F("Speed=")); Serial.print(count/tim,1); Serial.println("nps"); 443 lastpressedany=millis(); 444 } 445 delay(10); 446 447 448} 449//**************************** 450void load_moves() { 451 start_var=cur_step+21; 452 only_action=false; 453 lastbest.fig1=0; 454 steps[0].fig1=0; 455 load_variants(cur_step); 456 current_var=start_var; 457 int cv=cur_var; 458 hidden=true; 459 uint32_t tim=millis(); 460 solve_step(); 461 if (millis()-tim<1000) delay(millis()-tim); 462 cur_var=cv; 463 sort_variants(cur_step+21,cur_step+20+cur_var); 464 465} 466//********************************** 467void gui() { 468 if (isstatus) { 469 if (millis()-quitime>1000) { 470 if (isstatus) show_status(); 471 quitime=millis(); 472 } 473 } 474 M5.update(); 475 if (M5.BtnB.wasPressed()) 476 if (lastpressed==0) lastpressed=millis(); // 477 if (M5.BtnA.wasPressed()) 478 if (lastpressedleft==0) lastpressedleft=millis(); // 479 if (M5.BtnC.wasPressed()) 480 if (lastpressedright==0) lastpressedright=millis(); // 481 482 lastpressedany=max(max(max(lastpressed,lastpressedleft),lastpressedright),lastpressedany); 483 484 if (!menu&&!isstatus&&rotate==cur_step%2) { // AI 485 if (millis()>lastpressedany+3000) { 486 delay(100); 487 solving=true; 488 Serial.println(F("\ 489Autostart solving!")); 490 return; 491 } 492 float angle=3.1416-6.2832*(millis()-lastpressedany)/3000; 493 M5.Lcd.drawLine(308,175,308+9*sin(angle),175+9*cos(angle),CGRAY); 494 delay(200); 495 } 496 497 if (!menu&&!isstatus&&rotate!=cur_step%2) { // 498 if (!movesload) { 499 load_moves(); 500 movesload=1; 501 animate_step(cur_step-1,true); 502 } 503 animategreen_step(current_var,false); 504 delay(100); 505 } 506 507 if (M5.BtnB.isReleased()&&lastpressed) 508 if (millis()-lastpressed>500) { // 509 if (!isstatus) { 510 if (movesload) animategreen_step(current_var,true); 511 movesload=0; 512 lastpressed=0; 513 beep(50); 514 if (menu==0) menu=1; else menu=0; 515 submenu=0; 516 show_menu(); 517 } 518 return; 519 } else { 520 if (movesload&&cur_var>0) animategreen_step(current_var,true); 521 beep(5); 522 lastpressed=0; 523 switch (menu) { 524 case 0: // 525 if (solving) { // 526 beep(100); 527 solving=false; 528 } else { // AI 529 if (movesload) { 530 movesload=0; 531 float tim=float(millis()-starttime)/1000; 532 tone_volume(600,100); 533 steps[cur_step]=steps[current_var]; 534 movestep(cur_step); 535 cur_step++; steps[cur_step].fig1=0; 536 initscreen(); 537 animate_step(cur_step-1,false); 538 clearstatus(); 539 } else { 540 delay(100); 541 solving=1; 542 animate_step(cur_step,false); 543 } 544 } 545 return; 546 case 1: 547 if (submenu) { //new game 548 beep(200); 549 cur_step=1; 550 steps[1].fig1=0; 551 for (int i=0;i<8;i++) 552 for (int j=0;j<8;j++) pole[j][i]=(signed char)pgm_read_byte(&polestart[j][i]); 553 lastanimatedgreen.x1==99; 554 kingpositions(); 555 initboard(); 556 clearstatus(); 557 menu=0; 558 initscreen(); 559 show_menu(); 560 } else if (cur_step>1) { // 561 beep(100); 562 cur_step--; 563 animate_step(cur_step,true); 564 lastscore=0; 565 backstep(cur_step); 566 steps[cur_step].fig1=0; 567 lastscore=0; 568 show_board(); 569 menu=0; 570 show_steps(); 571 clearstatus(); 572 return; 573 } break; 574 case 2: 575 if (submenu) { //load game 576 short cur_step_=prefs.getShort("cur_step"); 577 short limit_=prefs.getShort("limit"); 578 if (cur_step>0&&cur_step<1000&&limit>=0&&limit<3) { 579 initboard(); 580 cur_step=cur_step_; limit=limit_; 581 sound=prefs.getBool("sound"); 582 rotate=prefs.getBool("rotate"); 583 prefs.getBytes("pole",pole,sizeof(pole)); 584 prefs.getBytes("steps",steps,sizeof(step_type)*cur_step); 585 beep(100); 586 } else { 587 beep(1000); sound=1; rotate=0; limit=0; cur_step=1; 588 } 589 //File file = SD.open("/AM_Chess.sav"); 590 //if (file) { 591 // Serial.println("file open"); 592 // file.read((uint8_t*)pole,64); 593 // uint8_t c[sizeof(step_type)]; 594 // file.read(c,sizeof(cur_step)); memcpy(&cur_step,c,sizeof(cur_step)); 595 // file.read(c,sizeof(limit)); memcpy(&limit,c,sizeof(limit)); 596 // file.read(c,sizeof(sound)); memcpy(&sound,c,sizeof(sound)); 597 // step_type t; 598 // for (int i=1;i<cur_step;i++) { 599 // t=steps[i]; 600 // file.read(c,sizeof(step_type)); 601 // memcpy(&t,c,sizeof(step_type)); 602 // } 603 // file.close(); 604 // beep(100); 605 //} else { beep(1000); Serial.println("SD card error!"); } 606 steps[0].fig1=0; 607 steps[cur_step].fig1=0; 608 lastanimatedgreen.x1==99; 609 initboard(); 610 kingpositions(); 611 clearstatus(); 612 menu=0; 613 show_menu(); 614 initscreen(); 615 return; 616 } else { // 617 beep(100); 618 rotate=!rotate; 619 initboard(); 620 return; 621 } break; 622 case 3: 623 if (submenu) { //save game 624 prefs.putShort("cur_step",cur_step); 625 prefs.putShort("limit",limit); 626 prefs.putBool("sound",sound); 627 prefs.putBool("rotate",rotate); 628 prefs.putBytes("pole",pole,sizeof(pole)); 629 prefs.putBytes("steps",steps,sizeof(step_type)*cur_step); 630 beep(50); delay(50); beep(50); delay(50); beep(50); 631 //File file = SD.open("/AM_Chess.sav", FILE_WRITE); 632 //if (file) { 633 // Serial.println("file open for write"); 634 // file.write((const uint8_t*)pole,64); 635 // uint8_t c[sizeof(step_type)]; 636 // memcpy(c,&cur_step,sizeof(cur_step)); file.write(c,sizeof(cur_step)); 637 // memcpy(c,&limit,sizeof(limit)); file.write(c,sizeof(limit)); 638 // memcpy(c,&sound,sizeof(sound)); file.write(c,sizeof(sound)); 639 // step_type t; 640 // for (int i=1;i<cur_step;i++) { 641 // t=steps[i]; 642 // memcpy(c,&t,sizeof(step_type)); 643 // file.write(c,sizeof(step_type)); 644 // } 645 // file.close(); 646 // beep(100); 647 //} else { beep(1000); Serial.println("SD card error!"); } 648 menu=0; 649 show_menu(); 650 return; 651 } else { // Game 652 submenu=1; menu=1; 653 show_menu(); 654 } break; 655 case 4: 656 if (submenu) { // USB 657 if (!load_usb()) return; 658 limit=2; 659 beep(200); 660 menu=0; 661 initboard(); 662 kingpositions(); 663 clearstatus(); 664 initscreen(); 665 return; 666 } else { // 667 beep(100); 668 limit++; if (limit>2) limit=0; 669 show_menu(); 670 return; 671 } 672 case 5: // 673 if (sound==1) { beep(100); sound=0; } else { sound=1; beep(200); } 674 show_menu(); 675 return; 676 } //switch 677 678 } 679 if (M5.BtnA.wasPressed()) { 680 lastpressedleft=0; 681 if (menu==0) { 682 if (movesload&&cur_var>0) { 683 animategreen_step(current_var,true); 684 current_var--; 685 if (current_var<cur_step+21) current_var=cur_step+21+cur_var-1; 686 } 687 } else { 688 beep(100); 689 menu--; 690 if (menu<1) 691 if (submenu) menu=4; else menu=5; 692 show_menu(); 693 delay(200); 694 } 695 } 696 if (M5.BtnC.wasPressed()) { 697 lastpressedright=0; 698 if (menu==0) { 699 if (movesload&&cur_var>0) { 700 animategreen_step(current_var,true); 701 current_var++; 702 if (current_var>=cur_step+21+cur_var) current_var=cur_step+21; 703 } 704 } else { 705 beep(100); 706 menu++; if (menu>5) menu=1; 707 if (submenu&&menu>4) menu=1; 708 show_menu(); 709 delay(200); 710 } 711 } 712 713 714} 715//********************************** 716void animategreen_step(int nstep, boolean hide) { 717 if (cur_var==0) return; 718 int j=steps[nstep].x1; 719 int j2=steps[nstep].x2; 720 int dj=j2-j; 721 int i=steps[nstep].y1; 722 int i2=steps[nstep].y2; 723 int di=i2-i; 724 if (di!=0) di=di/abs(di); 725 if (dj!=0) dj=dj/abs(dj); 726 if (lastanimatedgreen.x1==steps[nstep].x1&&lastanimatedgreen.y1==steps[nstep].y1&& 727 lastanimatedgreen.x2==steps[nstep].x2&&lastanimatedgreen.y2==steps[nstep].y2&& 728 lastanimatedgreen.fig1==steps[nstep].fig1&&!hide) { 729 int show=(millis()/500)%2; 730 movestep(nstep); 731 if (show) show_cont(i2,j2); 732 backstep(nstep); 733 if (!show) show_fig(i2,j2); 734 if (!rotate) M5.Lcd.drawRect(i2*28+8,j2*28+1,27,27,CGREEN); 735 else M5.Lcd.drawRect((7-i2)*28+8,(7-j2)*28+1,27,27,CGREEN); 736 return; 737 } 738 lastanimatedgreen=steps[nstep]; 739 if (hide) show_fig(i,j); 740 while (j!=steps[nstep].x2||i!=steps[nstep].y2) { 741 show_fig(i,j); 742 if (!hide) 743 if (!rotate) M5.Lcd.drawRect(i*28+8,j*28+1,27,27,CGREEN); 744 else M5.Lcd.drawRect((7-i)*28+8,(7-j)*28+1,27,27,CGREEN); 745 int mj=0; 746 if (j!=steps[nstep].x2) { j+=dj; mj=1; } 747 if (abs(steps[nstep].fig1)==fn&&mj==1) continue; 748 if (i!=steps[nstep].y2) i+=di; 749 } 750 if (hide) { show_fig(i,j); lastanimatedgreen.x1=99; } 751 752} 753//**************************** 754void show_cont(int i,int j) { 755uint16_t color,color_cont; 756 color=CBLACKF; 757 if ((i+j+2)%2==0) color=CWHITEF; 758 int jj=j, ii=i; 759 if (rotate) { jj=7-j; ii=7-i; } 760 M5.Lcd.fillRect(ii*28+7,jj*28,29,29,color); 761 //M5.Lcd.drawRect(ii*28+7,jj*28,29,29,CGREEN); 762 color=CBLACK; 763 if (pole[j][i]>0) color=CWHITE; 764 if (pole[j][i]!=0) { 765 drawBitmap(ii*28+10, jj*28+3,&fig_cont[abs(pole[j][i])-1][0], 24, 24,color); 766 } 767} 768//********************************** 769void animate_step(int nstep, boolean hide) { 770uint16_t color=getColor(220,220,200); 771 if (!hide&&nstep-1>0&&steps[nstep-1].fig1!=0) animate_step(nstep-1,true); 772 if (nstep<1||steps[nstep].fig1==0) return; 773 int j=steps[nstep].x1; 774 int dj=steps[nstep].x2-steps[nstep].x1; 775 int i=steps[nstep].y1; 776 int di=steps[nstep].y2-steps[nstep].y1; 777 if (di!=0) di=di/abs(di); 778 if (dj!=0) dj=dj/abs(dj); 779 if (hide) show_fig(i,j); 780 while (j!=steps[nstep].x2||i!=steps[nstep].y2) { 781 show_fig(i,j); 782 if (!hide) 783 if (!rotate) M5.Lcd.drawRect(i*28+8,j*28+1,27,27,color); 784 else M5.Lcd.drawRect((7-i)*28+8,(7-j)*28+1,27,27,color); 785 int mj=0; 786 if (j!=steps[nstep].x2) { j+=dj; mj=1; } 787 if (abs(steps[nstep].fig1)==fn&&mj==1) continue; 788 if (i!=steps[nstep].y2) i+=di; 789 } 790 show_fig(i,j); 791 if (!hide) 792 if (!rotate) M5.Lcd.drawRect(i*28+8,j*28+1,27,27,color); 793 else M5.Lcd.drawRect((7-i)*28+8,(7-j)*28+1,27,27,color); 794} 795//********************************** 796void show_status() { 797 if (rotate!=cur_step%2) return; 798 int tim=(millis()-starttime)/1000; 799 int cur=220000*tim/(limittime-starttime); 800 if (cur>220) { cur=220; solving=false; } 801 M5.Lcd.drawFastHLine(10,237,cur,CGRAY); 802 M5.Lcd.drawFastHLine(10,239,progress*2,CGRAY); 803 int m=tim/60; 804 int s=tim%60; 805 M5.Lcd.setTextWrap(1); 806 M5.Lcd.setTextColor(CGRAY); 807 M5.Lcd.setTextSize(1); 808 M5.Lcd.fillRect(240,166,80,10,CBLACK); 809 M5.Lcd.setCursor(242,166); 810 if (m>0) { M5.Lcd.print(m); M5.Lcd.print(":"); } 811 if (s>0) { 812 if (s<10&&m>0) M5.Lcd.print("0"); 813 M5.Lcd.print(s); 814 } else if (m>0) M5.Lcd.print("00"); else M5.Lcd.print("0"); 815 M5.Lcd.setCursor(280,166); 816 M5.Lcd.print(cur_level); 817 M5.Lcd.setCursor(242,176); 818 if (cur_step%2==1) M5.Lcd.setTextColor(CWHITE); else M5.Lcd.setTextColor(CGRAY); 819 if (lastbest.fig1!=steps[0].fig1||lastbest.x1!=steps[0].x1||lastbest.y1!=steps[0].y1|| 820 lastbest.x2!=steps[0].x2||lastbest.y2!=steps[0].y2) { 821 lastbest=steps[0]; 822 M5.Lcd.fillRect(240,176,80,10,CBLACK); 823 M5.Lcd.setCursor(242,176); 824 M5.Lcd.setTextColor(CGRAY); 825 M5.Lcd.print(str_step(0)); 826 blinkstep=0; 827 } 828 if (steps[0].fig1!=0&&blinkstep==0&&tim>5) { 829 signed char poleb[8][8]; 830 for (int i=0;i<8;i++) 831 for (int j=0;j<8;j++) { poleb[j][i]=pole[j][i]; pole[j][i]=pole0[j][i]; } 832 movestep(0); 833 show_board(); 834 delay(100); 835 backstep(0); 836 show_board(); 837 for (int i=0;i<8;i++) 838 for (int j=0;j<8;j++) pole[j][i]=poleb[j][i]; 839 kingpositions(); 840 } 841 blinkstep++; 842 if (blinkstep>2) blinkstep=0; 843} 844//**************************** 845void show_fig(int i,int j) { 846uint16_t color,color_cont; 847 color=CBLACKF; 848 if ((i+j+2)%2==0) color=CWHITEF; 849 int jj=j, ii=i; 850 if (rotate) { jj=7-j; ii=7-i; } 851 M5.Lcd.fillRect(ii*28+7,jj*28,29,29,color); 852 M5.Lcd.drawRect(ii*28+7,jj*28,29,29,CGRAY); 853 color=CBLACKFIG; color_cont=CBLACKCONT; //CGRAY; 854 if (pole[j][i]>0) { color=CWHITEFIG; color_cont=CBLACK; } 855 if (pole[j][i]!=0) { 856 drawBitmap(ii*28+10, jj*28+3,&fig[abs(pole[j][i])-1][0], 24, 24,color); 857 drawBitmap(ii*28+10, jj*28+3,&fig_cont[abs(pole[j][i])-1][0], 24, 24,color_cont); 858 } 859} 860//**************************** 861void show_board() { 862 for (int i=0;i<8;i++) 863 for (int j=0;j<8;j++) { 864 if (poledisp[j][i]!=pole[j][i]) show_fig(i,j); 865 poledisp[j][i]=pole[j][i]; 866 } 867} 868//********************************** 869boolean load_usb() { 870char s='x',i=0,j=0; boolean load=false; 871 Serial.println(F("Wait for FEN position")); 872 for (int i=0;i<8;i++) 873 for (int j=0;j<8;j++) { 874 pole0[j][i]=pole[j][i]; 875 pole[j][i]=(char)pgm_read_byte(&polezero[j][i]); 876 } 877 while (s!=' ') { 878 s=Serial.read(); 879 if (i>7) { i=0; j++; } 880 if (!getpole(j,i)) break; 881 switch (s) { 882 case '/': i=0; break; 883 case 'p': pole[j][i]=-fp; i++; break; 884 case 'P': pole[j][i]=fp; i++; break; 885 case 'n': pole[j][i]=-fn; i++; break; 886 case 'N': pole[j][i]=fn; i++; break; 887 case 'b': pole[j][i]=-fb; i++; break; 888 case 'B': pole[j][i]=fb; i++; break; 889 case 'r': pole[j][i]=-fr; i++; break; 890 case 'R': pole[j][i]=fr; i++; break; 891 case 'q': pole[j][i]=-fq; i++; break; 892 case 'Q': pole[j][i]=fq; i++; break; 893 case 'k': pole[j][i]=-fk; i++; break; 894 case 'K': pole[j][i]=fk; i++; break; 895 case '1': i++; break; 896 case '2': i+=2; break; 897 case '3': i+=3; break; 898 case '4': i+=4; break; 899 case '5': i+=5; break; 900 case '6': i+=6; break; 901 case '7': i+=7; break; 902 case '8': i=0; j++; break; 903 case ' ': break; 904 } 905 delay(20); 906 if (i+j>0&&Serial.available()==0) break; 907 } 908 s=0; 909 if (Serial.available()>0) s=Serial.read(); 910 while (Serial.available()>0) Serial.read(); 911 if (s=='w'||s==0) { cur_step=1; load=true; rotate=1; } 912 else if (s=='b') { cur_step=2; load=true; rotate=0; } 913 else load=false; 914 if (load) { 915 steps[1].fig1=0; steps[2].fig1=0; 916 Serial.println(F("Position loaded")); 917 } else { 918 for (int i=0;i<8;i++) 919 for (int j=0;j<8;j++) 920 pole[j][i]=pole0[j][i]; 921 } 922 return load; 923} 924//********************************** 925String str_step(int i) { 926 String s=""; 927 if (steps[i].fig1==0) return s; 928 if (steps[i].type==2) s="0-0"; 929 else if (steps[i].type==3) s="0-0-0"; 930 else { 931 if (abs(steps[i].fig1)>1) s=fig_symb[abs(steps[i].fig1)]; 932 if (abs(steps[i].fig1<5)) { 933 s=s+char(97+steps[i].y1); 934 s=s+String(8-steps[i].x1); 935 if (steps[i].fig2==0) s=s+"-"; 936 } 937 if (steps[i].fig2!=0) { 938 s=s+"x"; 939 if (abs(steps[i].fig2)>1) s=s+fig_symb[abs(steps[i].fig2)]; 940 } 941 s=s+char(97+steps[i].y2); 942 s=s+String(8-steps[i].x2); 943 } 944 if (steps[i].type>3) s=s+fig_symb[steps[i].type-2]; 945 if (steps[i].check==1) s=s+"+"; else 946 if (steps[i].check==2) s=s+"#"; 947 return s; 948} 949//**************************** 950void show_steps() { 951uint16_t color=getColor(200,200,180); 952 M5.Lcd.fillRect(234,0,90,160,getColor(8,8,8)); 953 M5.Lcd.fillRect(234,0,90,24,CDARK); 954 M5.Lcd.setTextSize(1); 955 M5.Lcd.setTextColor(getColor(160,160,140),CDARK); 956 M5.Lcd.setCursor(241,2); 957 M5.Lcd.print(" ArduinoMega"); 958 M5.Lcd.setCursor(240,14); 959 M5.Lcd.print("Chess M5Stack"); 960 int i=1; int y=27; 961 int cur=(cur_step+1)/2; // 962 int lim_step=cur_step; 963 if (cur>6) i=cur-5; 964 while (i<=cur&&y<140) { // 965 M5.Lcd.setCursor(240,y); 966 M5.Lcd.setTextColor(CGRAY); 967 M5.Lcd.print(i); 968 M5.Lcd.print(". "); 969 if (i*2-1==cur_step-1) M5.Lcd.setTextColor(color); 970 if (steps[i*2-1].fig1!=0) M5.Lcd.print(str_step(i*2-1)); 971 if (steps[i*2].fig1==0||i*2>lim_step) break; 972 M5.Lcd.setTextColor(CBLACK); 973 M5.Lcd.setCursor(240,y+10); 974 M5.Lcd.print(i); 975 M5.Lcd.print(" "); 976 M5.Lcd.setTextColor(CGRAY); 977 if (i*2==cur_step-1) M5.Lcd.setTextColor(color); 978 M5.Lcd.print(str_step(i*2)); 979 i++; y+=22; 980 } 981 show_menu(); 982} 983//**************************** 984void show_menu() { 985uint16_t color=getColor(220,220,200); 986 if (menu==0) submenu=0; else animategreen_step(current_var,true); 987 988 M5.Lcd.fillRect(233,190,86,50,CBLACK); 989 M5.Lcd.setTextSize(1); 990 if (menu==1) M5.Lcd.setTextColor(CBLACK,CBLUE); else M5.Lcd.setTextColor(color,CGRAY2); 991 if (submenu) { 992 M5.Lcd.setCursor(242,190); M5.Lcd.print(" New Game "); 993 } else { 994 M5.Lcd.setCursor(233,190); M5.Lcd.print(" Back "); 995 } 996 if (menu==2) M5.Lcd.setTextColor(CBLACK,CBLUE); else M5.Lcd.setTextColor(color,CGRAY2); 997 if (submenu) { 998 M5.Lcd.setCursor(242,203); M5.Lcd.print(" Load Game "); 999 } else { 1000 M5.Lcd.setCursor(271,190); M5.Lcd.print(" Rotate "); 1001 } 1002 if (menu==3) M5.Lcd.setTextColor(CBLACK,CBLUE); else M5.Lcd.setTextColor(color,CGRAY2); 1003 if (submenu) { 1004 M5.Lcd.setCursor(242,216); M5.Lcd.print(" Save Game "); 1005 } else { 1006 M5.Lcd.setCursor(242,203); M5.Lcd.print(" Game menu "); 1007 } 1008 if (menu==4) M5.Lcd.setTextColor(CBLACK,CBLUE); else M5.Lcd.setTextColor(color,CGRAY2); 1009 if (submenu) { 1010 M5.Lcd.setCursor(242,229); M5.Lcd.print(" USB FEN "); 1011 } else { 1012 M5.Lcd.setCursor(242,216); M5.Lcd.print(" Level "); 1013 switch (limit) { 1014 case 0: M5.Lcd.print("LOW "); break; 1015 case 1: M5.Lcd.print("MED "); break; 1016 case 2: M5.Lcd.print("HIGH"); break; 1017 } 1018 } 1019 if (menu==5) M5.Lcd.setTextColor(CBLACK,CBLUE); else M5.Lcd.setTextColor(color,CGRAY2); 1020 if (submenu) { 1021 } else { 1022 M5.Lcd.setCursor(242,227); M5.Lcd.print(" Sound "); 1023 if (sound) M5.Lcd.print("ON "); else M5.Lcd.print("OFF "); 1024 } 1025} 1026 1027//**************************** 1028boolean getdiagrowcheckw(signed char dj,signed char di) { // 1029signed char d,j1,i1; 1030 j1=WKJ; i1=WKI; 1031 for (d=1;d<8;d++) { 1032 j1+=dj; i1+=di; 1033 if (getpole(j1,i1)) { 1034 if (pole[j1][i1]==-fq||pole[j1][i1]==-fb) return true; 1035 if (pole[j1][i1]!=0) break; 1036 } else break; 1037 } 1038 return false; 1039} 1040//**************************** 1041boolean getdiagrowcheckb(signed char dj,signed char di) { // 1042signed char d,j1,i1; 1043 j1=BKJ; i1=BKI; 1044 for (d=1;d<8;d++) { 1045 j1+=dj; i1+=di; 1046 if (getpole(j1,i1)) { 1047 if (pole[j1][i1]==fq||pole[j1][i1]==fb) return true; 1048 if (pole[j1][i1]!=0) break; 1049 } else break; 1050 } 1051 return false; 1052} 1053//**************************** 1054boolean getstreightrowcheckw(signed char dj,signed char di) { // - 1055signed char d,j1,i1; 1056 j1=WKJ; i1=WKI; 1057 for (d=1;d<8;d++) { 1058 j1+=dj; i1+=di; 1059 if (getpole(j1,i1)) { 1060 if (pole[j1][i1]==-fq||pole[j1][i1]==-fr) return true; 1061 if (pole[j1][i1]!=0) break; 1062 } else break; 1063 } 1064 return false; 1065} 1066//**************************** 1067boolean getstreightrowcheckb(signed char dj,signed char di) { // - 1068signed char d,j1,i1; 1069 j1=BKJ; i1=BKI; 1070 for (d=1;d<8;d++) { 1071 j1+=dj; i1+=di; 1072 if (getpole(j1,i1)) { 1073 if (pole[j1][i1]==fq||pole[j1][i1]==fr) return true; 1074 if (pole[j1][i1]!=0) break; 1075 } else break; 1076 } 1077 return false; 1078} 1079//**************************** 1080boolean get_check(signed char king) { // 1081 if (king==fk) { // 1082 if (getdiagrowcheckw(-1, 1)) return true; 1083 if (getdiagrowcheckw(-1,-1)) return true; 1084 if (getdiagrowcheckw( 1,-1)) return true; 1085 if (getdiagrowcheckw( 1, 1)) return true; 1086 if (getstreightrowcheckw(-1, 0)) return true; 1087 if (getstreightrowcheckw( 0, 1)) return true; 1088 if (getstreightrowcheckw( 0,-1)) return true; 1089 if (getstreightrowcheckw( 1, 0)) return true; 1090 if (getpole(WKJ-2,WKI-1)&&pole[WKJ-2][WKI-1]==-fn) return true; 1091 if (getpole(WKJ-2,WKI+1)&&pole[WKJ-2][WKI+1]==-fn) return true; 1092 if (getpole(WKJ-1,WKI-2)&&pole[WKJ-1][WKI-2]==-fn) return true; 1093 if (getpole(WKJ-1,WKI+2)&&pole[WKJ-1][WKI+2]==-fn) return true; 1094 if (getpole(WKJ+1,WKI-2)&&pole[WKJ+1][WKI-2]==-fn) return true; 1095 if (getpole(WKJ+1,WKI+2)&&pole[WKJ+1][WKI+2]==-fn) return true; 1096 if (getpole(WKJ+2,WKI-1)&&pole[WKJ+2][WKI-1]==-fn) return true; 1097 if (getpole(WKJ+2,WKI+1)&&pole[WKJ+2][WKI+1]==-fn) return true; 1098 if (getpole(WKJ-1,WKI-1)&&pole[WKJ-1][WKI-1]==-fp) return true; 1099 if (getpole(WKJ-1,WKI+1)&&pole[WKJ-1][WKI+1]==-fp) return true; 1100 } else { // 1101 if (getdiagrowcheckb( 1,-1)) return true; 1102 if (getdiagrowcheckb( 1, 1)) return true; 1103 if (getdiagrowcheckb(-1, 1)) return true; 1104 if (getdiagrowcheckb(-1,-1)) return true; 1105 if (getstreightrowcheckb( 1, 0)) return true; 1106 if (getstreightrowcheckb( 0, 1)) return true; 1107 if (getstreightrowcheckb( 0,-1)) return true; 1108 if (getstreightrowcheckb(-1, 0)) return true; 1109 if (getpole(BKJ+2,BKI-1)&&pole[BKJ+2][BKI-1]==fn) return true; 1110 if (getpole(BKJ+2,BKI+1)&&pole[BKJ+2][BKI+1]==fn) return true; 1111 if (getpole(BKJ+1,BKI-2)&&pole[BKJ+1][BKI-2]==fn) return true; 1112 if (getpole(BKJ+1,BKI+2)&&pole[BKJ+1][BKI+2]==fn) return true; 1113 if (getpole(BKJ-1,BKI-2)&&pole[BKJ-1][BKI-2]==fn) return true; 1114 if (getpole(BKJ-1,BKI+2)&&pole[BKJ-1][BKI+2]==fn) return true; 1115 if (getpole(BKJ-2,BKI-1)&&pole[BKJ-2][BKI-1]==fn) return true; 1116 if (getpole(BKJ-2,BKI+1)&&pole[BKJ-2][BKI+1]==fn) return true; 1117 if (getpole(BKJ+1,BKI-1)&&pole[BKJ+1][BKI-1]==fp) return true; 1118 if (getpole(BKJ+1,BKI+1)&&pole[BKJ+1][BKI+1]==fp) return true; 1119 } 1120 if (abs(BKJ-WKJ)<=1&&abs(BKI-WKI)<=1) return true; // 1121 return false; 1122} 1123//**************************** 1124boolean getpole(signed char j,signed char i) { // 1125 if (j>=0&&j<8&&i>=0&&i<8) return true; 1126 return false; 1127} 1128//**************************** 1129void addstep(signed char j1,signed char i1,signed char j2,signed char i2,signed char type) { 1130 int st=start_var+cur_var; 1131 steps[st].x1=j1; 1132 steps[st].x2=j2; 1133 steps[st].y1=i1; 1134 steps[st].y2=i2; 1135 steps[st].fig1=pole[j1][i1]; 1136 steps[st].fig2=pole[j2][i2]; 1137 if (type==1) { // 1138 steps[st].fig2=-steps[st].fig1; 1139 } 1140 steps[st].type=type; 1141 signed char ko=-fk; // 1142 if (steps[st].fig1>0) ko=fk; 1143 movestep(st); 1144 if (get_check(ko)) { backstep(st); return; } // - 1145 boolean che=get_check(-ko); // 1146 backstep(st); 1147 steps[st].weight=abs(steps[st].fig2)-abs(steps[st].fig1); 1148 if (type>3) steps[st].weight+=fig_weight[type-2]; 1149 if (endspiel&&steps[st].fig1==ko) steps[st].weight+=10; // - 1150 steps[st].check=che; 1151 if (che) steps[st].weight+=10; 1152 if (only_action) { 1153 if (steps[st].fig1==fp&&steps[st].x2==1||steps[st].fig1==-fp&&steps[st].x2==6) // 1154 { cur_var++; return; } 1155 if (steps[st].fig2==0&&steps[st].type<4&&!che&&!check_on_table) return; 1156 } 1157 1158 cur_var++; 1159} 1160//**************************** 1161void getrowstepsw(signed char j,signed char i,signed char dj,signed char di) { // 1162signed char d,j1,i1; 1163 j1=j; i1=i; 1164 for (d=1;d<8;d++) { 1165 j1+=dj; i1+=di; 1166 if (getpole(j1,i1)) { 1167 if (pole[j1][i1]<=0) addstep(j,i,j1,i1,0); 1168 if (pole[j1][i1]!=0) break; 1169 } else break; 1170 } 1171} 1172//**************************** 1173void getrowstepsb(signed char j,signed char i,signed char dj,signed char di) { // 1174signed char d,j1,i1; 1175 j1=j; i1=i; 1176 for (d=1;d<8;d++) { 1177 j1+=dj; i1+=di; 1178 if (getpole(j1,i1)) { 1179 if (pole[j1][i1]>=0) addstep(j,i,j1,i1,0); 1180 if (pole[j1][i1]!=0) break; 1181 } else break; 1182 } 1183} 1184//**************************** 1185void getonestepw(signed char j,signed char i,signed char dj,signed char di) { // 1186signed char j1,i1; 1187 j1=j+dj; i1=i+di; 1188 if (getpole(j1,i1)) 1189 if (pole[j1][i1]<=0) addstep(j,i,j1,i1,0); 1190} 1191//**************************** 1192void getonestepb(signed char j,signed char i,signed char dj,signed char di) { // 1193signed char j1,i1; 1194 j1=j+dj; i1=i+di; 1195 if (getpole(j1,i1)) 1196 if (pole[j1][i1]>=0) addstep(j,i,j1,i1,0); 1197} 1198//**************************** 1199void sort_variants(int from, int to) { // 1200 while (1) { 1201 int mov=0; 1202 for (int i=from;i<to;i++) // 1203 if (steps[i].weight<steps[i+1].weight) { 1204 mov++; 1205 step_type buf=steps[i]; 1206 steps[i]=steps[i+1]; 1207 steps[i+1]=buf; 1208 } 1209 if (mov==0) break; 1210 } 1211} 1212//**************************** 1213void load_variants(int nstep) { // nstep 1214 cur_var=0; 1215 if (pole[WKJ][WKI]!=fk||pole[BKJ][BKI]!=-fk) kingpositions(); 1216 if (nstep%2==1) check_on_table=get_check(fk); 1217 else check_on_table=get_check(-fk); // 1218 for (signed char i=0;i<8;i++) 1219 for (signed char j=0;j<8;j++) 1220 if (pole[j][i]>0&&nstep%2==1||pole[j][i]<0&&nstep%2==0) { 1221 switch (pole[j][i]) { 1222 case fp: // 1223 if (getpole(j-1,i)&&pole[j-1][i]==0) 1224 if (j!=1) addstep(j,i,j-1,i,0); else 1225 for (signed char t=4;t<8;t++) addstep(1,i,0,i,t); //-... 1226 if (j==6&&pole[j-1][i]==0&&pole[j-2][i]==0) addstep(j,i,j-2,i,0); 1227 if (getpole(j-1,i-1)&&pole[j-1][i-1]<0) 1228 if (j!=1) addstep(j,i,j-1,i-1,0); else 1229 for (signed char t=4;t<8;t++) addstep(j,i,j-1,i-1,t); //-... 1230 if (getpole(j-1,i+1)&&pole[j-1][i+1]<0) 1231 if (j!=1) addstep(j,i,j-1,i+1,0); else 1232 for (signed char t=4;t<8;t++) addstep(j,i,j-1,i+1,t); //-... 1233 if (j==3&&steps[nstep-1].fig1==-fp&&steps[nstep-1].x2==3&&steps[nstep-1].x1==1) { 1234 if (steps[nstep-1].y2-i==1) { // 1235 addstep(j,i,j-1,i+1,1); 1236 } else if (steps[nstep-1].y2-i==-1) { // 1237 addstep(j,i,j-1,i-1,1); 1238 } 1239 } 1240 break; 1241 case -fp: // 1242 if (getpole(j+1,i)&&pole[j+1][i]==0) 1243 if (j!=6) addstep(j,i,j+1,i,0); else 1244 for (signed char t=4;t<8;t++) addstep(j,i,j+1,i,t); //-... 1245 if (j==1&&pole[j+1][i]==0&&pole[j+2][i]==0) addstep(j,i,j+2,i,0); 1246 if (getpole(j+1,i-1)&&pole[j+1][i-1]>0) 1247 if (j!=6) addstep(j,i,j+1,i-1,0); else 1248 for (signed char t=4;t<8;t++) addstep(j,i,j+1,i-1,t); //-... 1249 if (getpole(j+1,i+1)&&pole[j+1][i+1]>0) 1250 if (j!=6) addstep(j,i,j+1,i+1,0); else 1251 for (signed char t=4;t<8;t++) addstep(j,i,j+1,i+1,t); //-... 1252 if (j==4&&steps[nstep-1].fig1==fp&&steps[nstep-1].x2==4&&steps[nstep-1].x1==6) { 1253 if (steps[nstep-1].y2-i==1) { // 1254 addstep(j,i,j+1,i+1,1); 1255 } else if (steps[nstep-1].y2-i==-1) { // 1256 addstep(j,i,j+1,i-1,1); 1257 } 1258 } 1259 break; 1260 case fn: // 1261 getonestepw(j,i,-2,-1); 1262 getonestepw(j,i,-2,1); 1263 getonestepw(j,i,-1,-2); 1264 getonestepw(j,i,-1,2); 1265 getonestepw(j,i,2,-1); 1266 getonestepw(j,i,2,1); 1267 getonestepw(j,i,1,-2); 1268 getonestepw(j,i,1,2); 1269 break; 1270 case -fn: // 1271 getonestepb(j,i,-2,-1); 1272 getonestepb(j,i,-2,1); 1273 getonestepb(j,i,-1,-2); 1274 getonestepb(j,i,-1,2); 1275 getonestepb(j,i,2,-1); 1276 getonestepb(j,i,2,1); 1277 getonestepb(j,i,1,-2); 1278 getonestepb(j,i,1,2); 1279 break; 1280 case fb: // 1281 getrowstepsw(j,i,1,1); 1282 getrowstepsw(j,i,-1,-1); 1283 getrowstepsw(j,i,1,-1); 1284 getrowstepsw(j,i,-1,1); 1285 break; 1286 case -fb: // 1287 getrowstepsb(j,i,1,1); 1288 getrowstepsb(j,i,-1,-1); 1289 getrowstepsb(j,i,1,-1); 1290 getrowstepsb(j,i,-1,1); 1291 break; 1292 case fr: // 1293 getrowstepsw(j,i,1,0); 1294 getrowstepsw(j,i,-1,0); 1295 getrowstepsw(j,i,0,1); 1296 getrowstepsw(j,i,0,-1); 1297 break; 1298 case -fr: // 1299 getrowstepsb(j,i,1,0); 1300 getrowstepsb(j,i,-1,0); 1301 getrowstepsb(j,i,0,1); 1302 getrowstepsb(j,i,0,-1); 1303 break; 1304 case fq: // 1305 getrowstepsw(j,i,1,1); 1306 getrowstepsw(j,i,-1,-1); 1307 getrowstepsw(j,i,1,-1); 1308 getrowstepsw(j,i,-1,1); 1309 getrowstepsw(j,i,1,0); 1310 getrowstepsw(j,i,-1,0); 1311 getrowstepsw(j,i,0,1); 1312 getrowstepsw(j,i,0,-1); 1313 break; 1314 case -fq: // 1315 getrowstepsb(j,i,1,1); 1316 getrowstepsb(j,i,-1,-1); 1317 getrowstepsb(j,i,1,-1); 1318 getrowstepsb(j,i,-1,1); 1319 getrowstepsb(j,i,1,0); 1320 getrowstepsb(j,i,-1,0); 1321 getrowstepsb(j,i,0,1); 1322 getrowstepsb(j,i,0,-1); 1323 break; 1324 case fk: // 1325 getonestepw(j,i, 1,-1); 1326 getonestepw(j,i, 1, 0); 1327 getonestepw(j,i, 1, 1); 1328 getonestepw(j,i, 0,-1); 1329 getonestepw(j,i, 0, 1); 1330 getonestepw(j,i,-1,-1); 1331 getonestepw(j,i,-1, 0); 1332 getonestepw(j,i,-1, 1); 1333 if (!check_on_table) add_rok(j,i,nstep); 1334 break; 1335 case -fk: // 1336 getonestepb(j,i, 1,-1); 1337 getonestepb(j,i, 1, 0); 1338 getonestepb(j,i, 1, 1); 1339 getonestepb(j,i, 0,-1); 1340 getonestepb(j,i, 0, 1); 1341 getonestepb(j,i,-1,-1); 1342 getonestepb(j,i,-1, 0); 1343 getonestepb(j,i,-1, 1); 1344 if (!check_on_table) add_rok(j,i,nstep); 1345 break; 1346 } //switch 1347 } //if 1348 1349 if (nstep>cur_step) { 1350 for (int i=start_var;i<start_var+cur_var;i++) { // 1351 for (signed char j=0;j<MAXCUTS;j++) 1352 if (cuts[j].fig1==steps[i].fig1&& 1353 cuts[j].x1==steps[i].x1&&cuts[j].y1==steps[i].y1&& 1354 cuts[j].x2==steps[i].x2&&cuts[j].y2==steps[i].y2) { 1355 steps[i].weight+=100+cuts[j].weight; 1356 break; 1357 } 1358 if (nstep>1&&steps[nstep-1].fig2!=0) // - 1359 if (steps[nstep-1].x2==steps[i].x2&&steps[nstep-1].y2==steps[i].y2) 1360 steps[i].weight+=1000; 1361 } 1362 } 1363 1364 sort_variants(start_var,start_var+cur_var-1); 1365 1366 } 1367//**************************** 1368void movestep(int nstep) { 1369 pole[steps[nstep].x1][steps[nstep].y1]=0; 1370 pole[steps[nstep].x2][steps[nstep].y2]=steps[nstep].fig1; 1371 if (steps[nstep].fig1==fk) { 1372 WKJ=steps[nstep].x2; WKI=steps[nstep].y2; 1373 } else if (steps[nstep].fig1==-fk) { 1374 BKJ=steps[nstep].x2; BKI=steps[nstep].y2; 1375 } 1376 if (steps[nstep].type==0) return; 1377 if (steps[nstep].type==1) // 1378 if (steps[nstep].fig1>0) 1379 pole[steps[nstep].x2+1][steps[nstep].y2]=0; 1380 else 1381 pole[steps[nstep].x2-1][steps[nstep].y2]=0; 1382 else if (steps[nstep].type==2) // 1383 if (steps[nstep].fig1>0) { // 1384 pole[7][4]=0; pole[7][5]=fr; pole[7][6]=fk; pole[7][7]=0; //show_board(); delay(3000); 1385 } else { // 1386 pole[0][4]=0; pole[0][5]=-fr; pole[0][6]=-fk; pole[0][7]=0; //show_board(); delay(3000); 1387 } 1388 else if (steps[nstep].type==3) // 1389 if (steps[nstep].fig1>0) { // 1390 pole[7][0]=0; pole[7][1]=0; pole[7][2]=fk; pole[7][3]=fr; pole[7][4]=0; 1391 } else { // 1392 pole[0][0]=0; pole[0][1]=0; pole[0][2]=-fk; pole[0][3]=-fr; pole[0][4]=0; 1393 } 1394 else if (steps[nstep].type>3) //-.... 1395 if (steps[nstep].fig1>0) pole[steps[nstep].x2][steps[nstep].y2]=steps[nstep].type-2; 1396 else pole[steps[nstep].x2][steps[nstep].y2]=2-steps[nstep].type; 1397} 1398//**************************** 1399void backstep(int nstep) { 1400 pole[steps[nstep].x1][steps[nstep].y1]=steps[nstep].fig1; 1401 pole[steps[nstep].x2][steps[nstep].y2]=steps[nstep].fig2; 1402 if (steps[nstep].fig1==fk) { 1403 WKJ=steps[nstep].x1; WKI=steps[nstep].y1; 1404 } else if (steps[nstep].fig1==-fk) { 1405 BKJ=steps[nstep].x1; BKI=steps[nstep].y1; 1406 } 1407 if (steps[nstep].type==0) return; 1408 if (steps[nstep].type==1) { // 1409 pole[steps[nstep].x2][steps[nstep].y2]=0; 1410 if (steps[nstep].fig1>0) 1411 pole[steps[nstep].x2+1][steps[nstep].y2]=-fp; 1412 else 1413 pole[steps[nstep].x2-1][steps[nstep].y2]=fp; 1414 } else if (steps[nstep].type==2) // 1415 if (steps[nstep].fig1>0) { // 1416 pole[7][4]=fk; pole[7][5]=0; pole[7][6]=0; pole[7][7]=fr; 1417 } else { // 1418 pole[0][4]=-fk; pole[0][5]=0; pole[0][6]=0; pole[0][7]=-fr; // show_board(); delay(3000); 1419 } 1420 else if (steps[nstep].type==3) // 1421 if (steps[nstep].fig1>0) { // 1422 pole[7][0]=fr; pole[7][1]=0; pole[7][2]=0; pole[7][3]=0; pole[7][4]=fk; 1423 } else { // 1424 pole[0][0]=-fr; pole[0][1]=0; pole[0][2]=0; pole[0][3]=0; pole[0][4]=-fk; 1425 } 1426 1427} 1428//**************************** 1429void get_wrocks(int nstep) { 1430 w00=true; w000=true; 1431 for (int i=1;i<nstep;i++) { 1432 if (steps[i].fig1==fk) { w00=false; w000=false; return; } 1433 if (steps[i].fig1==fr) 1434 if (steps[i].x1==7&&steps[i].y1==7) w00=false; 1435 else if (steps[i].x1==7&&steps[i].y1==0) w000=false; 1436 } 1437} 1438//**************************** 1439void get_brocks(int nstep) { 1440 b00=true; b000=true; 1441 for (int i=1;i<nstep;i++) { 1442 if (steps[i].fig1==-fk) { b00=false; b000=false; return; } 1443 if (steps[i].fig1==-fr) 1444 if (steps[i].x1==0&&steps[i].y1==7) b00=false; 1445 else if (steps[i].x1==0&&steps[i].y1==0) b000=false; 1446 } 1447} 1448//**************************** 1449void add_rok(signed char j,signed char i,int nstep) { // 1450boolean che1,che2; 1451 if (nstep%2==1) { // 1452 if (j!=7||i!=4) return; 1453 if (pole[7][5]==0&&pole[7][6]==0&&pole[7][7]==fr) { // 1454 pole[7][4]=0; 1455 WKI=5; che1=get_check(fk); 1456 WKI=6; che2=get_check(fk); 1457 WKI=4; pole[7][4]=fk; 1458 get_wrocks(nstep); 1459 if (!che1&&!che2&&w00) addstep(7,4,7,6,2); 1460 } 1461 if (pole[7][0]==fr&&pole[7][1]==0&&pole[7][2]==0&&pole[7][3]==0) { // 1462 pole[7][4]=0; 1463 WKI=2; che1=get_check(fk); 1464 WKI=3; che2=get_check(fk); 1465 WKI=4; pole[7][4]=fk; 1466 get_wrocks(nstep); 1467 if (!che1&&!che2&&w000) addstep(7,4,7,2,3); 1468 } 1469 } else { // 1470 if (j!=0||i!=4) return; 1471 if (pole[0][5]==0&&pole[0][6]==0&&pole[0][7]==-fr) { // 1472 pole[0][4]=0; 1473 BKI=5; che1=get_check(-fk); 1474 BKI=6; che2=get_check(-fk); 1475 BKI=4; pole[0][4]=-fk; 1476 get_brocks(nstep); 1477 if (!che1&&!che2&&b00) addstep(0,4,0,6,2); 1478 } 1479 if (pole[0][0]==-fr&&pole[0][1]==0&&pole[0][2]==0&&pole[0][3]==0) { // 1480 pole[0][4]=0; 1481 BKI=2; che1=get_check(-fk); 1482 BKI=3; che2=get_check(-fk); 1483 BKI=4; pole[0][4]=-fk; 1484 get_brocks(nstep); 1485 if (!che1&&!che2&&b000) addstep(0,4,0,2,3); 1486 } 1487 1488 } 1489} 1490//**************************** 1491int addrowstepsw(signed char j,signed char i,signed char dj,signed char di,signed char dc) { // 1492signed char d,j1,i1; int c=0; 1493 j1=j; i1=i; 1494 for (d=1;d<8;d++) { 1495 j1+=dj; i1+=di; 1496 if (getpole(j1,i1)) { 1497 if (pole[j1][i1]==0) c+=dc; 1498 else if (pole[j1][i1]>0) { // 1499 c+=1; break; 1500 } else { 1501 if (cur_step>6) c+=-pole[j1][i1]; // 1502 break; 1503 } 1504 } else break; 1505 } 1506 return c; 1507} 1508//**************************** 1509int addrowstepsb(signed char j,signed char i,signed char dj,signed char di,signed char dc) { // 1510signed char d,j1,i1; int c=0; 1511 j1=j; i1=i; 1512 for (d=1;d<8;d++) { 1513 j1+=dj; i1+=di; 1514 if (getpole(j1,i1)) { 1515 if (pole[j1][i1]==0) c-=dc; 1516 else if (pole[j1][i1]<0) { // 1517 c-=1; break; 1518 } else { 1519 if (cur_step>6) c-=pole[j1][i1]; // 1520 break; 1521 } 1522 } else break; 1523 } 1524 return c; 1525} 1526//**************************** 1527int addonestepw(signed char j,signed char i,signed char dj,signed char di) { // 1528signed char j1,i1; 1529 j1=j+dj; i1=i+di; 1530 if (getpole(j1,i1)) 1531 if (pole[j1][i1]==0) return 2; 1532 else if (pole[j1][i1]>0) return 1; 1533 else return -pole[j1][i1]; 1534 return 0; 1535} 1536//**************************** 1537int addonestepb(signed char j,signed char i,signed char dj,signed char di) { // 1538signed char j1,i1; 1539 j1=j+dj; i1=i+di; 1540 if (getpole(j1,i1)) 1541 if (pole[j1][i1]==0) return -2; 1542 else if (pole[j1][i1]<0) return -1; 1543 else return -pole[j1][i1]; 1544 return 0; 1545} 1546//**************************** 1547int activity() { // - + 1548int c=0; 1549signed char pwj[8],pwi[8],pbj[8],pbi[8],ipw=0,ipb=0,nbw=0,nbb=0; 1550 for (signed char i=0;i<8;i++) 1551 for (signed char j=0;j<8;j++) 1552 if (pole[j][i]!=0) { 1553 switch (pole[j][i]) { 1554 case fp: // 1555 if (getpole(j,i+1)&&pole[j][i+1]==fp) c+=2; // 1556 if (getpole(j-1,i)&&pole[j-1][i]==fp) c-=20; // 1557 pwj[ipw]=j; pwi[ipw]=i; ipw++; 1558 break; 1559 case -fp: // 1560 if (getpole(j,i-1)&&pole[j][i-1]==-fp) c-=2; // 1561 if (getpole(j+1,i)&&pole[j+1][i]==-fp) c+=20; // 1562 pbj[ipb]=j; pbi[ipb]=i; ipb++; 1563 break; 1564 case fn: // 1565 c+=addonestepw(j,i,-2,-1); 1566 c+=addonestepw(j,i,-2,1); 1567 c+=addonestepw(j,i,-1,-2); 1568 c+=addonestepw(j,i,-1,2); 1569 c+=addonestepw(j,i,2,-1); 1570 c+=addonestepw(j,i,2,1); 1571 c+=addonestepw(j,i,1,-2); 1572 c+=addonestepw(j,i,1,2); 1573 break; 1574 case -fn: // 1575 c+=addonestepb(j,i,-2,-1); 1576 c+=addonestepb(j,i,-2,1); 1577 c+=addonestepb(j,i,-1,-2); 1578 c+=addonestepb(j,i,-1,2); 1579 c+=addonestepb(j,i,2,-1); 1580 c+=addonestepb(j,i,2,1); 1581 c+=addonestepb(j,i,1,-2); 1582 c+=addonestepb(j,i,1,2); 1583 break; 1584 case fb: // 1585 c+=addrowstepsw(j,i,1,1,2); //!! 1.4 1586 c+=addrowstepsw(j,i,-1,-1,3);//!! 1587 c+=addrowstepsw(j,i,1,-1,2); //!! 1588 c+=addrowstepsw(j,i,-1,1,3); //!! 1589 nbw++; 1590 break; 1591 case -fb: // 1592 c+=addrowstepsb(j,i,1,1,3); //!! 1.4 1593 c+=addrowstepsb(j,i,-1,-1,2);//!! 1594 c+=addrowstepsb(j,i,1,-1,3); //!! 1595 c+=addrowstepsb(j,i,-1,1,2); //!! 1596 nbb++; 1597 break; 1598 case fr: // 1599 c+=addrowstepsw(j,i,1,0,2); // 1600 c+=addrowstepsw(j,i,-1,0,2); 1601 c+=addrowstepsw(j,i,0,1,1); 1602 c+=addrowstepsw(j,i,0,-1,1); 1603 break; 1604 case -fr: // 1605 c+=addrowstepsb(j,i,1,0,2); // 1606 c+=addrowstepsb(j,i,-1,0,2); 1607 c+=addrowstepsb(j,i,0,1,1); 1608 c+=addrowstepsb(j,i,0,-1,1); 1609 break; 1610 case fq: // 1611 if (cur_step>10) { 1612 c+=addrowstepsw(j,i,1,1,1); 1613 c+=addrowstepsw(j,i,-1,-1,2); 1614 c+=addrowstepsw(j,i,1,-1,1); 1615 c+=addrowstepsw(j,i,-1,1,2); 1616 c+=addrowstepsw(j,i,1,0,1); 1617 c+=addrowstepsw(j,i,-1,0,2); 1618 c+=addrowstepsw(j,i,0,1,1); 1619 c+=addrowstepsw(j,i,0,-1,1); 1620 } 1621 break; 1622 case -fq: // 1623 if (cur_step>10) { 1624 c+=addrowstepsb(j,i,1,1,2); 1625 c+=addrowstepsb(j,i,-1,-1,1); 1626 c+=addrowstepsb(j,i,1,-1,2); 1627 c+=addrowstepsb(j,i,-1,1,1); 1628 c+=addrowstepsb(j,i,1,0,2); 1629 c+=addrowstepsb(j,i,-1,0,1); 1630 c+=addrowstepsb(j,i,0,1,1); 1631 c+=addrowstepsb(j,i,0,-1,1); 1632 } 1633 break; 1634 } //switch 1635 if (cur_step>6) { 1636 if (pole[j][i]>0) { // 1637 if (abs(WKJ-j)<2&&abs(WKI-i)<2) c+=3; 1638 if (abs(BKJ-j)<2&&abs(BKI-i)<2) c+=3; 1639 if (abs(WKJ-j)<3&&abs(WKI-i)<3) c+=2; 1640 if (abs(BKJ-j)<3&&abs(BKI-i)<3) c+=2; 1641 } else { // 1642 if (abs(WKJ-j)<2&&abs(WKI-i)<2) c-=3; 1643 if (abs(BKJ-j)<2&&abs(BKI-i)<2) c-=3; 1644 if (abs(WKJ-j)<3&&abs(WKI-i)<3) c-=2; 1645 if (abs(BKJ-j)<3&&abs(BKI-i)<3) c-=2; 1646 } 1647 } 1648 } 1649 if (nbw>1) c+=30; // 1650 if (nbb>1) c-=30; 1651 for (signed char w=0;w<ipw;w++) { // 1652 boolean pass=1; 1653 for (signed char b=0;b<ipb;b++) { 1654 if (pwi[w]>0&&pbi[b]==pwi[w]-1&&pbj[b]<pwj[w]) pass=0; // 1655 if (pbi[b]==pwi[w]&&pbj[b]<pwj[w]) pass=0; // 1656 if ( pwi[w]<7&&pbi[b]==pwi[w]+1&&pbj[b]<pwj[w]) pass=0; // 1657 if (!pass) break; 1658 } 1659 if (pass) { 1660 c+=50; 1661 if (!endspiel) break; // 1662 } 1663 } 1664 for (signed char b=0;b<ipb;b++) { // 1665 boolean pass=1; 1666 for (signed char w=0;w<ipw;w++) { 1667 if (pbi[b]>0&&pwi[w]==pbi[b]-1&&pwj[w]>pbj[b]) pass=0; // 1668 if (pwi[w]==pbi[b]&&pwj[w]>pbj[b]) pass=0; // 1669 if (pbi[b]<7&&pwi[w]==pbi[b]+1&&pwj[w]>pbj[b]) pass=0; // 1670 if (!pass) break; 1671 } 1672 if (pass) { 1673 c-=50; 1674 if (!endspiel) break; // 1675 } 1676 } 1677 return c; 1678} 1679//**************************** 1680int evaluate(int nstep) { // 1681 long ww=0, wb=0; 1682 for (signed char i=0;i<8;i++) 1683 for (signed char j=0;j<8;j++) 1684 if (pole[j][i]<0) { 1685 wb+=fig_weight[-pole[j][i]]+(short)pgm_read_word(&pos[-pole[j][i]-1][7-j][i]); 1686 } 1687 else if (pole[j][i]>0) { 1688 ww+=fig_weight[pole[j][i]]+(short)pgm_read_word(&pos[pole[j][i]-1][j][i]); 1689 } 1690 count++; // 1691 long str=activity(); 1692 if (endspiel) { // 1693 wb+=(short)pgm_read_word(&pos[6][7-BKJ][BKI])-(short)pgm_read_word(&pos[5][7-BKJ][BKI]); 1694 ww+=(short)pgm_read_word(&pos[6][WKJ][WKI])-(short)pgm_read_word(&pos[5][WKJ][WKI]); 1695 if (wb<450&&ww>450) { // - - 1696 str-=(abs(WKJ-BKJ)+abs(WKI-BKI))*30; 1697 } else if (ww<450&&wb>450) { // 1698 str+=(abs(WKJ-BKJ)+abs(WKI-BKI))*30; 1699 } 1700 } 1701 if (nstep>8) { // 1702 if (steps[nstep-1].fig1==steps[nstep-5].fig1&&steps[nstep-2].fig1==steps[nstep-6].fig1&& 1703 steps[nstep-3].fig1==steps[nstep-7].fig1&&steps[nstep-4].fig1==steps[nstep-8].fig1) 1704 if (steps[nstep-1].x1==steps[nstep-5].x1&&steps[nstep-2].x1==steps[nstep-6].x1&& 1705 steps[nstep-3].x1==steps[nstep-7].x1&&steps[nstep-4].x1==steps[nstep-8].x1) 1706 if (steps[nstep-1].x2==steps[nstep-5].x2&&steps[nstep-2].x2==steps[nstep-6].x2&& 1707 steps[nstep-3].x2==steps[nstep-7].x2&&steps[nstep-4].x2==steps[nstep-8].x2) 1708 if (steps[nstep-1].y1==steps[nstep-5].y1&&steps[nstep-2].y1==steps[nstep-6].y1&& 1709 steps[nstep-3].y1==steps[nstep-7].y1&&steps[nstep-4].y1==steps[nstep-8].x1) 1710 if (steps[nstep-1].y2==steps[nstep-5].y2&&steps[nstep-2].y2==steps[nstep-6].y2&& 1711 steps[nstep-3].y2==steps[nstep-7].y2&&steps[nstep-4].y2==steps[nstep-8].y2) 1712 { 1713 //Serial.println(F(" Draw - 3 repeat")); 1714 return 0; 1715 } 1716 } 1717 if (nstep%2==1) return 5000*(ww-wb)/(ww+wb+2000)+str; else return 5000*(wb-ww)/(ww+wb+2000)-str; 1718} 1719//**************************** 1720void add_cut(int ind) {// ind 1721 int minbeta=30000, minindex=MAXCUTS-1; 1722 for (signed char i=0;i<MAXCUTS;i++) { 1723 if (cuts[i].weight==0) { minindex=i; break; }// 1724 if (cuts[i].fig1==steps[ind].fig1&& 1725 cuts[i].x1==steps[ind].x1&&cuts[i].y1==steps[ind].y1&& 1726 cuts[i].x2==steps[ind].x2&&cuts[i].y2==steps[ind].y2) { 1727 cuts[i].weight++; return; // - 1 1728 } 1729 if (cuts[i].weight<minbeta) { // 1730 minbeta=cuts[i].weight; 1731 minindex=i; 1732 } 1733 } 1734 cuts[minindex]=steps[ind]; 1735 cuts[minindex].weight=1; //1 1736} 1737//**************************** 1738int quiescence(int start, int nstep, int alpha, int beta ) { 1739 if (nstep-cur_step>=LIMDEPTH||start>MAXSTEPS-100) return evaluate(nstep); 1740 if (!solving&&progress==0) return -5000; 1741 int score=-20000; 1742 start_var=start; 1743 only_action=true; 1744 load_variants(nstep); 1745 if (!check_on_table) { 1746 int stand_pat = evaluate(nstep); 1747 if (stand_pat >= score) score=stand_pat; 1748 if (score>alpha) alpha=score; 1749 if (alpha>=beta&&isbeta) return alpha; 1750 } 1751 if (cur_var==0) { 1752 if (check_on_table) { 1753 if (TRACE) Serial.println(F("checkmate?")); 1754 return -10000+nstep-cur_step; 1755 } else return evaluate(nstep); 1756 } 1757 int j=start+cur_var; 1758 for (int i=start;i<j;i++) { // 1759 if (TRACE) { //***** 1760 for (int u=0;u<nstep-cur_step;u++) Serial.print(F(" . ")); 1761 Serial.println(str_step(i)); 1762 } 1763 movestep(i); 1764 steps[nstep]=steps[i]; 1765 int tmp=-quiescence(j+1,nstep+1,-beta,-alpha); 1766 backstep(i); 1767 if (tmp>score) score=tmp; 1768 if (score>alpha) alpha=score; 1769 if (alpha>=beta&&isbeta) { 1770 add_cut(nstep); 1771 return alpha; 1772 } 1773 gui(); 1774 } 1775 return score; 1776} 1777//**************************** 1778int alphaBeta(int start, int nstep, int alpha, int beta, int depthleft) { 1779//start - 1780//nstep - 1781int score=-20000,best; 1782 if( depthleft==0) return quiescence(start,nstep,alpha,beta) ; 1783 if (start>MAXSTEPS-100) return evaluate(nstep); 1784 start_var=start; 1785 only_action=false; 1786 if (nstep!=cur_step) load_variants(nstep); 1787 if (cur_var==0) { 1788 if (check_on_table) { 1789 if (TRACE) Serial.println(F("checkmate!")); 1790 return -10000+nstep-cur_step; 1791 } 1792 return 0; 1793 } 1794 int j=start+cur_var; 1795 best=start; 1796 for (int i=start;i<j;i++) { // 1797 if (nstep==cur_step) { 1798 if (!hidden) { 1799 Serial.print(str_step(i)); Serial.print(" "); 1800 Serial.print(i-start+1); Serial.print("/"); Serial.print(j-start); 1801 } 1802 if (steps[i].weight<-9000) { Serial.println(F(" checkmate")); continue; } 1803 if (steps[i].fig2!=0||steps[i].check||(alpha<-100&&isbeta)) 1804 // , , -100 1805 { LIMDEPTH=MAXDEPTH+2; if (!hidden) Serial.print(F("+2")); } else LIMDEPTH=MAXDEPTH; 1806 } else { 1807 if (TRACE) { //***** 1808 for (int u=0;u<nstep-cur_step;u++) Serial.print(F(" ")); 1809 Serial.println(str_step(i)); 1810 } 1811 } 1812 movestep(i); 1813 steps[nstep]=steps[i]; 1814 int tmp=-alphaBeta(j+1,nstep+1,-beta,-alpha,depthleft-1); 1815 backstep(i); 1816 steps[i].weight=tmp; 1817 if (tmp>score) score=tmp; 1818 if (score>alpha) { 1819 alpha=score; 1820 if (nstep>cur_step) add_cut(nstep); // 1821 if (TRACE) { Serial.print(F("ALPHA+:")); Serial.println(score); } 1822 best=i; 1823 if (nstep==cur_step) { 1824 steps[0]=steps[best]; 1825 if (!hidden) Serial.print(F(" BEST")); 1826 } 1827 } 1828 if (alpha>=beta&&isbeta) { 1829 if (nstep>cur_step) add_cut(nstep); // 1830 if (TRACE) { Serial.print(F("BETA CUT:")); Serial.println(score); } 1831 return alpha; 1832 } 1833 if (nstep==cur_step) { 1834 if (!hidden) { Serial.print(F(" ")); Serial.println(tmp); } 1835 progress=100*(i-start+1)/(j-start); 1836 if (alpha==9999||alpha==-5000) break; 1837 if (!solving) { 1838 if (alpha>startweight&&cur_level>2) break; 1839 else { // - +50% 1840 if (cur_level>1&&100*(millis()-starttime)/(limittime-starttime)>240-limit*20) break; 1841 } 1842 } 1843 } 1844 if (nstep==cur_step+1&&!solving&&progress==0) break; 1845 gui(); 1846 } 1847 if (nstep==cur_step) { steps[nstep]=steps[best]; steps[0]=steps[best]; } 1848 return score; 1849} 1850//**************************** 1851void kingpositions() { 1852 for (signed char i=0;i<8;i++) // 1853 for (signed char j=0;j<8;j++) 1854 if (pole[j][i]==fk) { 1855 WKJ=j; WKI=i; 1856 } else if (pole[j][i]==-fk) { 1857 BKJ=j; BKI=i; 1858 } 1859} 1860//**************************** 1861int get_endspiel() { // 1862 int weight=0; 1863 for (signed char i=0;i<8;i++) 1864 for (signed char j=0;j<8;j++) 1865 if (pole[j][i]<0) 1866 weight+=fig_weight[-pole[j][i]]; 1867 else if (pole[j][i]>0) 1868 weight+=fig_weight[pole[j][i]]; // 8000 1869 if (weight<3500) endspiel=true; else endspiel=false; 1870 return weight; 1871} 1872//**************************** 1873boolean is_drawn() { // 1874 boolean drawn=false; 1875 int cn=0,cbw=0,cbb=0,co=0,cb=0,cw=0; 1876 for (signed char i=0;i<8;i++) 1877 for (signed char j=0;j<8;j++) { 1878 if (abs(pole[j][i])==1) co++; 1879 if (abs(pole[j][i])>3&&abs(pole[j][i])<6) co++; // , , 1880 if (abs(pole[j][i])==6) continue; // 1881 if (abs(pole[j][i])==2) cn++; // 1882 if (abs(pole[j][i])==3&&(i+j+2)%2==0) cbb++; // 1883 if (abs(pole[j][i])==3&&(i+j+2)%2==1) cbw++; // 1884 if (pole[j][i]==3) cw++; // 1885 if (pole[j][i]==-3) cb++; // 1886 } 1887 if (cn==1&&co+cbb+cbw==0) drawn=true; // 1888 if (cbb+cbw==1&&co+cn==0) drawn=true; // 1889 if (co+cn+cbb==0||co+cn+cbw==0) drawn=true; // 1890 if (co+cn==0&&cb==1&&cw==1) drawn=true; // 1891 if (drawn) return drawn; 1892 int rep=1; 1893 for (int s=cur_step-1; s>0; s--) { 1894 if (steps[s].fig1==0) continue; 1895 backstep(s); 1896 boolean eq=true; 1897 for (signed char i=0;i<8;i++) 1898 for (signed char j=0;j<8;j++) 1899 if (pole[j][i]!=pole0[j][i]) 1900 { eq=false; break; } 1901 if (eq) rep++; 1902 if (rep>2) break; 1903 } 1904 if (rep>1) { Serial.print(rep); Serial.println(" repetitions"); } 1905 for (signed char i=0;i<8;i++) 1906 for (signed char j=0;j<8;j++) pole[j][i]=pole0[j][i]; // 1907 if (rep>2) drawn=true; 1908 return drawn; 1909} 1910//**************************** 1911int solve_step() { 1912const int LMIN[6]={2,3,4,5,6,7}; 1913const int LMAX[6]={4,6,8,10,12,14}; 1914boolean check_on; 1915 if (!hidden) { 1916 M5.Lcd.fillRect(240,166,80,20,CBLACK); 1917 M5.Lcd.drawFastHLine(10,237,220,CDARK); 1918 } 1919 starttime=millis(); 1920 isstatus=1; 1921 limittime=starttime+limits[limit]*1000; // 1922 for (signed char i=0;i<8;i++) 1923 for (signed char j=0;j<8;j++) pole0[j][i]=pole[j][i]; // 1924 1925 isbeta=true; 1926 if (hidden) isbeta=false; 1927 else if (cur_step<5) { // FEN 1928 isbeta=false; 1929 for (int i=cur_step-1;i>0;i--) 1930 if (steps[i].fig1!=0) backstep(i); 1931 for (signed char i=0;i<8;i++) 1932 for (signed char j=0;j<8;j++) 1933 if (polestart[j][i]!=pole[j][i]) { isbeta=true; break; } 1934 for (signed char i=0;i<8;i++) 1935 for (signed char j=0;j<8;j++) pole[j][i]=pole0[j][i]; // 1936 } 1937 Serial.print("isbeta="); Serial.println(isbeta); 1938 1939 lastbest.fig1=0; 1940 kingpositions(); 1941 int wei=get_endspiel(); 1942 1943 count=0; 1944 startweight=evaluate(cur_step); 1945 if (!hidden) { 1946 Serial.println(""); 1947 Serial.println(F("---------------")); 1948 if (endspiel) { Serial.print(F("Endspiel: ")); Serial.println(wei); } 1949 if (cur_step%2==1) Serial.print(F("WHITE, ")); else Serial.print(F("BLACK, ")); 1950 Serial.print(F("start Score= ")); Serial.println(startweight); 1951 } 1952 start_var=cur_step+21; 1953 only_action=false; 1954 lastbest.fig1=0; 1955 steps[0].fig1=0; 1956 load_variants(cur_step); 1957 check_on=check_on_table; 1958 if (cur_var==0||is_drawn()) { 1959 beep(500); 1960 M5.Lcd.drawFastHLine(10,237,220,CBLACK); 1961 M5.Lcd.drawFastHLine(10,239,220,CBLACK); 1962 isstatus=0; 1963 solving=false; 1964 if (check_on_table) return -9999; else return 8999; 1965 } 1966 if (cur_var==1) { // 1 1967 M5.Lcd.drawFastHLine(10,237,220,CBLACK); 1968 M5.Lcd.drawFastHLine(10,239,220,CBLACK); 1969 isstatus=0; 1970 solving=false; 1971 steps[cur_step]=steps[cur_step+21]; 1972 return startweight; 1973 } 1974 int vars=cur_var; 1975 int ALPHA=-20000; 1976 int BETA=20000; 1977 int score; 1978 solving=true; 1979 int l=0; 1980 for (signed char i=0;i<MAXCUTS;i++) { cuts[i].weight=0; cuts[i].fig1=0; } // 1981 for (int i=cur_step+21;i<cur_step+21+vars;i++) { // 1982 movestep(i); 1983 steps[i].weight=evaluate(cur_step); 1984 if (steps[i].fig2!=0) steps[i].weight-=steps[i].fig1; 1985 backstep(i); 1986 } 1987 while (l<6) { 1988 cur_level=l+1; 1989 progress=0; 1990 M5.Lcd.drawFastHLine(10,239,220,CDARK); 1991 MINDEPTH=LMIN[l]; 1992 MAXDEPTH=LMAX[l]; 1993 if (!hidden) { 1994 if (l>0) Serial.println(""); Serial.print(F("******* LEVEL=")); Serial.print(l+1); 1995 Serial.print(" "); Serial.print(MINDEPTH); Serial.print("-"); Serial.print(MAXDEPTH); 1996 Serial.print(" "); Serial.print((millis()-starttime)/1000.,1); Serial.println("s"); 1997 } 1998 sort_variants(cur_step+21,cur_step+20+vars); // 1999 cur_var=vars; 2000 check_on_table=check_on; 2001 for (int i=cur_step+21;i<cur_step+21+vars;i++) steps[i].weight=-8000; //// 2002 score=alphaBeta(cur_step+21,cur_step,ALPHA,BETA,MINDEPTH); 2003 if (score>9996) break; 2004 if (score>9000&&limit<2) break; 2005 if (100*(millis()-starttime)/(limittime-starttime)>75-l*8) break; 2006 if (!solving||!isbeta||hidden) break; 2007 //if (hidden||cur_step<5) break; 2008 l++; 2009 } //while l 2010 if (score<-9000) { 2011 if (!hidden) Serial.println(F("GIVE UP!")); 2012 } else { 2013 int ran=random(5,10); //// 2014 while (ran>0&&cur_step<5&&!isbeta) { 2015 for (int i=cur_step+21;i<cur_step+21+vars;i++) 2016 if (steps[i].weight>=score-10) { 2017 ran--; 2018 if (ran==0) { 2019 if (millis()%2==1) 2020 if (steps[cur_step].x1!=steps[i].x1||steps[cur_step].x2!=steps[i].x2|| 2021 steps[cur_step].y1!=steps[i].y1||steps[cur_step].y2!=steps[i].y2) { 2022 steps[cur_step]=steps[i]; 2023 if (!hidden) Serial.println(F("Best step replaced!")); 2024 break; 2025 } 2026 } 2027 } 2028 } //// 2029 if (!hidden) { Serial.print(F("STEP=")); Serial.println(str_step(cur_step)); } 2030 if (score>9000) { 2031 if (!hidden) Serial.print(F("CHECKMATE ")); 2032 if (score<9999) { 2033 if (!hidden) {Serial.print(F("in ")); Serial.print((9999-score)/2+1); Serial.print(F(" steps")); } 2034 } else steps[cur_step].check=2; 2035 if (!hidden) Serial.println(""); 2036 } 2037 } 2038 M5.Lcd.drawFastHLine(10,237,220,CBLACK); 2039 M5.Lcd.drawFastHLine(10,239,220,CBLACK); 2040 progress=0; 2041 solving=0; 2042 isstatus=0; 2043 endtime=millis(); 2044 return score; 2045 2046 2047} 2048//**************************** 2049
ArduinoMegaChess for M5Stack
arduino
1//ArduinoMega Chess 1.0 M5Stack 2//engine 1.4 3//Sergey Urusov, ususovsv@gmail.com 4 5#include <M5Stack.h> 6#include <Preferences.h> 7 8Preferences prefs; 9 10uint16_t CBLACK,CBLUE,CRED,CGREEN,CCYAN,CMAGENTA,CYELLOW,CWHITE,CGRAY,CDARK,CGRAY2,CBLACKF,CWHITEF,CWHITEFIG,CBLACKFIG,CBLACKCONT; 11 12int cycle=0; // 13const signed char fp=1; 14const signed char fn=2; 15const signed char fb=3; 16const signed char fr=4; 17const signed char fq=5; 18const signed char fk=6; 19const int fig_weight[]={0,100,320,330,500,900,0}; 20const char fig_symb[]=" NBRQK"; 21unsigned long count; 22boolean rotate=false; 23const signed char polezero[8][8] PROGMEM={ 24 { 0, 0, 0, 0, 0, 0, 0, 0}, 25 { 0, 0, 0, 0, 0, 0, 0, 0}, 26 { 0, 0, 0, 0, 0, 0, 0, 0}, 27 { 0, 0, 0, 0, 0, 0, 0, 0}, 28 { 0, 0, 0, 0, 0, 0, 0, 0}, 29 { 0, 0, 0, 0, 0, 0, 0, 0}, 30 { 0, 0, 0, 0, 0, 0, 0, 0}, 31 { 0, 0, 0, 0, 0, 0, 0, 0}, 32 }; 33const signed char polestart[8][8] PROGMEM={ 34 {-fr,-fn,-fb,-fq,-fk,-fb,-fn,-fr}, 35 {-fp,-fp,-fp,-fp,-fp,-fp,-fp,-fp}, 36 { 0, 0, 0, 0, 0, 0, 0, 0}, 37 { 0, 0, 0, 0, 0, 0, 0, 0}, 38 { 0, 0, 0, 0, 0, 0, 0, 0}, 39 { 0, 0, 0, 0, 0, 0, 0, 0}, 40 { fp, fp, fp, fp, fp, fp, fp, fp}, 41 { fr, fn, fb, fq, fk, fb, fn, fr}, 42 }; 43 44signed char pole[8][8]={ // 3 45 {-fr,-fn,-fb,-fq,-fk,-fb,-fn,-fr}, 46 {-fp,-fp,-fp,-fp,-fp,-fp,-fp,-fp}, 47 { 0, 0, 0, 0, 0, 0, 0, 0}, 48 { 0, 0, 0, 0, 0, 0, 0, 0}, 49 { 0, 0, 0, 0, 0, 0, 0, 0}, 50 { 0, 0, 0, 0, 0, 0, 0, 0}, 51 { fp, fp, fp, fp, fp, fp, fp, fp}, 52 { fr, fn, fb, fq, fk, fb, fn, fr}, 53 }; 54 55signed char pole0[8][8]; // 56signed char poledisp[8][8]; // 57signed char polechoice[7]; // 58boolean w00,w000,b00,b000; 59signed char blinkstep; 60typedef struct { 61 signed char fig1, fig2; // 62 signed char x1,y1,x2,y2; // 63 signed char check; // 64 signed char type; // 1- ,2- ,3- ,4-5-6-7- ,,, 65 int weight; // , 66} step_type; 67const int MAXSTEPS=1000; //. 68//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 69int MINDEPTH; //. 70int MAXDEPTH; //. 71int LIMDEPTH; //. 72const signed char MAXCUTS=10; //.. - - (10- , 20) 73boolean TRACE=0; 74boolean solving=false; 75boolean choice=false; 76boolean sound=1; 77short cur_step=1; // , 1.... 78short limit=0; // , 0-2; 79//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 80const long limits[3]={4,15,60}; 81// 0 1 2 82step_type steps[MAXSTEPS]; // 83step_type cuts[MAXCUTS]; // - 84step_type lastbest,lastanimatedgreen; 85int lastscore; 86int minbeta,maxalpha; 87int startweight; 88int cur_level; // () 89int start_var; // , 1.... 90int cur_var; // , 1.... 91int current_var; // , 1.... 92int cur_choice; // 93boolean check_on_table; // 94boolean isstatus; 95signed char WKJ=0,WKI=0,BKJ=0,BKI=0; // 96boolean endspiel=false; // 97signed char progress; // 0-100 98boolean only_action=false; // - 99unsigned long starttime,endtime,limittime,quitime=0; 100int menu=0; // 101unsigned long lastpressed,lastpressedleft,lastpressedright,lastpressedany; 102boolean submenu=0; 103boolean movesload=0; 104boolean isbeta=1; 105boolean hidden=false; 106 107const uint8_t fig[6][72] PROGMEM={ 108{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7E, 0x0, 0x0, 0xFF, 0x0, 1090x0, 0xFF, 0x0, 0x0, 0xFF, 0x0, 0x0, 0x7E, 0x0, 0x0, 0x3C, 0x0, 0x1, 0xFF, 0x80, 0x1, 0xFF, 0x80, 1100x0, 0x3C, 0x0, 0x0, 0x3C, 0x0, 0x0, 0x7E, 0x0, 0x0, 0x7E, 0x0, 0x0, 0xFF, 0x0, 0x1, 0xFF, 0x80, 1110x3, 0xFF, 0xC0, 0x7, 0xFF, 0xE0, 0x7, 0xFF, 0xE0, 0x7, 0xFF, 0xE0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 112}, // 113{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0x0, 0x0, 0xFF, 0x0, 0x1, 0xFF, 0x80, 0x3, 0xFF, 0xC0, 1140x7, 0xFF, 0xE0, 0xF, 0xFF, 0xF0, 0x1F, 0xFF, 0xF8, 0x1F, 0x3F, 0xF8, 0x1E, 0x3F, 0xF8, 0xC, 0x7F, 0xF8, 1150x0, 0xFF, 0xF0, 0x1, 0xFF, 0xE0, 0x1, 0xFF, 0xC0, 0x1, 0xFF, 0x80, 0x1, 0xFF, 0x0, 0x0, 0xFE, 0x0, 1160x0, 0x7E, 0x0, 0x7, 0xFF, 0xE0, 0xF, 0xFF, 0xF0, 0xF, 0xFF, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 117}, // 118{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3C, 0x0, 0x0, 0x7E, 0x0, 0x0, 0x7E, 0x0, 0x0, 0x3C, 0x0, 1190x1, 0xFF, 0x80, 0x3, 0xFF, 0xC0, 0x7, 0xFF, 0xE0, 0x7, 0xFF, 0xE0, 0x7, 0xFF, 0xE0, 0x7, 0xFF, 0xE0, 1200x7, 0xFF, 0xE0, 0x7, 0xFF, 0xE0, 0x7, 0xFF, 0xE0, 0x3, 0xFF, 0xC0, 0x1, 0xFF, 0x80, 0x0, 0xFF, 0x0, 1210x8, 0x7E, 0x10, 0x1C, 0x7E, 0x38, 0x3F, 0xFF, 0xFC, 0x3F, 0xFF, 0xFC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 122}, // 123{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xF, 0x3C, 0xF0, 0xF, 0x3C, 0xF0, 0xF, 0xFF, 0xF0, 0xF, 0xFF, 0xF0, 1240x7, 0xFF, 0xE0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 1250x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 1260x3, 0xFF, 0xC0, 0x7, 0xFF, 0xE0, 0xF, 0xFF, 0xF0, 0xF, 0xFF, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 127}, // 128{0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x3, 0x3C, 0xC0, 0x7, 0x99, 0xE0, 0x33, 0x18, 0xCC, 0x7B, 0x18, 0xDE, 1290x33, 0x18, 0xCC, 0x33, 0x18, 0xCC, 0x33, 0x18, 0xCC, 0x33, 0x18, 0xCC, 0x33, 0x18, 0xCC, 0x33, 0xBD, 0xCC, 1300x1B, 0xBD, 0xD8, 0x1F, 0xFF, 0xF8, 0x1F, 0xFF, 0xF8, 0xF, 0xFF, 0xF0, 0xF, 0xFF, 0xF0, 0x7, 0xFF, 0xE0, 1310x3, 0xFF, 0xC0, 0x7, 0xFF, 0xE0, 0xF, 0xFF, 0xF0, 0xF, 0xFF, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 132}, // 133{0x0, 0x0, 0x0, 0x0, 0x3C, 0x0, 0x0, 0x3C, 0x0, 0x0, 0x3C, 0x0, 0xF, 0x3C, 0xF0, 0x1F, 0xFF, 0xF8, 1340x3F, 0xFF, 0xFC, 0x7F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFE, 1350x7F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFE, 0x3F, 0xFF, 0xFC, 0x1F, 0xFF, 0xF8, 0xF, 0xFF, 0xF0, 0x7, 0xFF, 0xE0, 1360x3, 0xFF, 0xC0, 0x7, 0xFF, 0xE0, 0xF, 0xFF, 0xF0, 0xF, 0xFF, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 137} // 138}; 139const uint8_t fig_cont[6][72] PROGMEM={ 140{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7E, 0x0, 0x0, 0x81, 0x0, 0x1, 0x0, 0x80, 1410x1, 0x0, 0x80, 0x1, 0x0, 0x80, 0x0, 0x81, 0x0, 0x3, 0xC3, 0xC0, 0x2, 0x0, 0x40, 0x2, 0x0, 0x40, 1420x3, 0xC3, 0xC0, 0x0, 0x42, 0x0, 0x0, 0x81, 0x0, 0x0, 0x81, 0x0, 0x1, 0x0, 0x80, 0x2, 0x0, 0x40, 1430x4, 0x0, 0x20, 0x8, 0x0, 0x10, 0x8, 0x0, 0x10, 0x8, 0x0, 0x10, 0xF, 0xFF, 0xF0, 0x0, 0x0, 0x0 144}, // 145{0x0, 0x0, 0x0, 0x0, 0x66, 0x0, 0x0, 0x99, 0x0, 0x1, 0x0, 0x80, 0x2, 0xC0, 0x40, 0x4, 0xC0, 0x20, 1460x8, 0x0, 0x10, 0x10, 0x0, 0x8, 0x20, 0x0, 0x4, 0x20, 0xC0, 0x4, 0x21, 0x40, 0x4, 0x12, 0x80, 0x4, 1470xD, 0x0, 0x8, 0x2, 0x0, 0x10, 0x2, 0x0, 0x20, 0x2, 0x0, 0x40, 0x2, 0x0, 0x80, 0x1, 0x1, 0x0, 1480x7, 0x81, 0xE0, 0x8, 0x0, 0x10, 0x10, 0x0, 0x8, 0x10, 0x0, 0x8, 0x1F, 0xFF, 0xF8, 0x0, 0x0, 0x0 149}, // 150{0x0, 0x0, 0x0, 0x0, 0x3C, 0x0, 0x0, 0x42, 0x0, 0x0, 0x81, 0x0, 0x0, 0x81, 0x0, 0x1, 0xC3, 0x80, 1510x2, 0x18, 0x40, 0x4, 0x18, 0x20, 0x8, 0x18, 0x10, 0x8, 0x18, 0x10, 0x9, 0xFF, 0x90, 0x9, 0xFF, 0x90, 1520x8, 0x18, 0x10, 0x8, 0x18, 0x10, 0x8, 0x18, 0x10, 0x4, 0x18, 0x20, 0x2, 0x18, 0x40, 0x9, 0x0, 0x90, 1530x14, 0x81, 0x28, 0x23, 0x81, 0xC4, 0x40, 0x0, 0x2, 0x40, 0x0, 0x2, 0x7F, 0xFF, 0xFE, 0x0, 0x0, 0x0 154}, // 155{0x0, 0x0, 0x0, 0x1F, 0x3C, 0xF8, 0x10, 0xC3, 0x8, 0x10, 0xC3, 0x8, 0x10, 0x0, 0x8, 0x10, 0x0, 0x8, 1560xB, 0xFF, 0xD0, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 1570x4, 0x0, 0x20, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 1580x4, 0x0, 0x20, 0xB, 0xFF, 0xD0, 0x10, 0x0, 0x8, 0x10, 0x0, 0x8, 0x1F, 0xFF, 0xF8, 0x0, 0x0, 0x0 159}, // 160{0x0, 0x18, 0x0, 0x3, 0x24, 0xC0, 0x4, 0xC3, 0x20, 0x38, 0x66, 0x1C, 0x4C, 0xA5, 0x32, 0x84, 0xA5, 0x21, 1610x4C, 0xA5, 0x32, 0x4C, 0xA5, 0x32, 0x4C, 0xA5, 0x32, 0x4C, 0xA5, 0x32, 0x4C, 0xA5, 0x32, 0x4C, 0x42, 0x32, 1620x24, 0x42, 0x24, 0x20, 0x0, 0x4, 0x20, 0x0, 0x4, 0x10, 0x0, 0x8, 0x10, 0x0, 0x8, 0x8, 0x0, 0x10, 1630x4, 0x0, 0x20, 0xF, 0xFF, 0xF0, 0x10, 0x0, 0x8, 0x10, 0x0, 0x8, 0x1F, 0xFF, 0xF8, 0x0, 0x0, 0x0 164}, // 165{0x0, 0x7E, 0x0, 0x0, 0x42, 0x0, 0x0, 0x42, 0x0, 0xF, 0xC3, 0xF0, 0x10, 0xC3, 0x8, 0x20, 0x7E, 0x4, 1660x40, 0x3C, 0x2, 0x80, 0x18, 0x1, 0x80, 0x18, 0x1, 0x80, 0x18, 0x1, 0x80, 0x18, 0x1, 0x80, 0x18, 0x1, 1670x80, 0x18, 0x1, 0x80, 0x18, 0x1, 0x40, 0x18, 0x2, 0x20, 0x18, 0x4, 0x10, 0x18, 0x8, 0x8, 0x18, 0x10, 1680x4, 0x18, 0x20, 0xB, 0xFF, 0xD0, 0x10, 0x0, 0x8, 0x10, 0x0, 0x8, 0x1F, 0xFF, 0xF8, 0x0, 0x0, 0x0 169} // 170}; 171 172 173const int pos[7][8][8] PROGMEM={ 174 {{ 0, 0, 0, 0, 0, 0, 0, 0}, // 175 {100,100,100,100,100,100,100,100}, //{ 50, 50, 50, 50, 50, 50, 50, 50}, 176 { 20, 30, 40, 50, 50, 40, 30, 20}, //{ 10, 10, 20, 30, 30, 20, 10, 10}, 177 { 5, 5, 10, 25, 25, 10, 5, 5}, 178 { 0, 0, 0, 20, 20, 0, 0, 0}, 179 { 5, -5,-10, 0, 0,-10, -5, 5}, 180 { 5, 10, 10,-20,-20, 10, 10, 5}, //{ 5, 10, 10,-20,-20, 10, 10, 5}, 181 { 0, 0, 0, 0, 0, 0, 0, 0}}, 182 183 {{-50,-40,-30,-30,-30,-30,-40,-50}, // 184 {-40,-20, 0, 0, 0, 0,-20,-40}, 185 {-30, 0, 10, 15, 15, 10, 0,-30}, 186 {-30, 5, 15, 20, 20, 15, 5,-30}, 187 {-30, 0, 15, 20, 20, 15, 0,-30}, 188 {-30, 5, 10, 15, 15, 10, 5,-30}, 189 {-40,-20, 0, 5, 5, 0,-20,-40}, 190 {-50,-40,-30,-30,-30,-30,-40,-50}}, 191 192 {{-20,-10,-10,-10,-10,-10,-10,-20}, // 193 {-10, 0, 0, 0, 0, 0, 0,-10}, 194 {-10, 0, 5, 10, 10, 5, 0,-10}, 195 {-10, 5, 5, 10, 10, 5, 5,-10}, 196 {-10, 0, 10, 10, 10, 10, 0,-10}, 197 {-10, 10, 10, 10, 10, 10, 10,-10}, 198 {-10, 5, 0, 0, 0, 0, 5,-10}, 199 {-20,-10,-10,-10,-10,-10,-10,-20}}, 200 201 {{ 0, 0, 0, 0, 0, 0, 0, 0}, // 202 { 5, 10, 10, 10, 10, 10, 10, 5}, 203 { -5, 0, 0, 0, 0, 0, 0, -5}, 204 { -5, 0, 0, 0, 0, 0, 0, -5}, 205 { -5, 0, 0, 0, 0, 0, 0, -5}, 206 { -5, 0, 0, 0, 0, 0, 0, -5}, 207 { -5, 0, 0, 0, 0, 0, 0, -5}, 208 { 0, 0, 0, 5, 5, 0, 0, 0}}, 209 210 {{-20,-10,-10, -5, -5,-10,-10,-20}, // 211 {-10, 0, 0, 0, 0, 0, 0,-10}, 212 {-10, 0, 5, 5, 5, 5, 0,-10}, 213 { -5, 0, 5, 5, 5, 5, 0, -5}, 214 { 0, 0, 5, 5, 5, 5, 0, -5}, 215 {-10, 5, 5, 5, 5, 5, 0,-10}, 216 {-10, 0, 5, 0, 0, 0, 0,-10}, 217 {-20,-10,-10, -5, -5,-10,-10,-20}}, 218 219 {{-30,-40,-40,-50,-50,-40,-40,-30}, // 220 {-30,-40,-40,-50,-50,-40,-40,-30}, 221 {-30,-40,-40,-50,-50,-40,-40,-30}, 222 {-30,-40,-40,-50,-50,-40,-40,-30}, 223 {-20,-30,-30,-40,-40,-30,-30,-20}, 224 {-10,-20,-20,-20,-20,-20,-20,-10}, 225 { 10, 10,-10,-10,-10,-10, 10, 10}, //{ 20, 20, 0, 0, 0, 0, 20, 20}, 226 { 10, 40, 30, 0, 0, 0, 50, 10}}, //{ 20, 30, 10, 0, 0, 10, 30, 20}}, 227 228 {{-50,-40,-30,-20,-20,-30,-40,-50}, // 229 {-30,-20,-10, 0, 0,-10,-20,-30}, 230 {-30,-10, 20, 30, 30, 20,-10,-30}, 231 {-30,-10, 30, 40, 40, 30,-10,-30}, 232 {-30,-10, 30, 40, 40, 30,-10,-30}, 233 {-30,-10, 20, 30, 30, 20,-10,-30}, 234 {-30,-30, 0, 0, 0, 0,-30,-30}, 235 {-50,-30,-30,-30,-30,-30,-30,-50}} 236}; 237 238//********************************** 239void drawBitmap(int16_t x, int16_t y, 240 const uint8_t *bitmap, int16_t w, int16_t h, 241 uint16_t color) { 242 int16_t i, j, byteWidth = (w + 7) / 8; 243 for(j=0; j<h; j++) { 244 for(i=0; i<w; i++ ) { 245 if(pgm_read_byte(bitmap + j * byteWidth + i / 8) & (128 >> (i & 7))) { 246 M5.Lcd.drawPixel(x+i, y+j, color); 247 } 248 } 249 } 250} 251//**************************** 252uint8_t music[1000]; 253void tone_volume(uint16_t frequency, uint32_t duration) { 254 float interval=0.001257*float(frequency); 255 float phase=0; 256 for (int i=0;i<1000;i++) { 257 music[i]=127+126*sin(phase); 258 phase+=interval; 259 } 260 music[999]=0; 261 int remains=duration; 262 for (int i=0;i<duration;i+=200) { 263 if (remains<200) { 264 music[remains*999/200]=0; 265 } 266 M5.Speaker.playMusic(music,5000); 267 remains-=200; 268 } 269} 270//**************************** 271void beep(int leng) { 272 if (sound) M5.Speaker.setVolume(1); else M5.Speaker.setVolume(0); 273 tone_volume(1000,leng); 274} 275//**************************** 276void definecolors() { 277 CBLACK =0x0000; 278 CBLUE =0x07FF; //0x001F; 279 CRED =0xF800; 280 CGREEN =0x07E0; 281 CCYAN =0x07FF; 282 CMAGENTA=0xF81F; 283 CYELLOW =0xFFE0; 284 CWHITE =0xFFFF; 285 CWHITEFIG =getColor(200,200,140); 286 CGRAY =0x7BEF; 287 CDARK =getColor(32,32,32); 288 CGRAY2 =getColor(16,16,16); 289 CBLACKF =getColor(114,75,0); 290 CWHITEF =getColor(180,114,0); 291 CBLACKFIG =getColor(15,24,8); 292 CBLACKCONT =getColor(160,160,120); 293} 294//**************************** 295uint16_t getColor(uint8_t red, uint8_t green, uint8_t blue) 296{ 297 red >>= 3; 298 green >>= 2; 299 blue >>= 3; 300 return (red << 11) | (green << 5) | blue; 301} 302//**************************** 303void clearstatus() { 304 M5.Lcd.fillRect(240,166,80,20,BLACK); 305 M5.Lcd.drawFastHLine(10,237,220,BLACK); 306 M5.Lcd.drawFastHLine(10,239,220,BLACK); 307} 308//**************************** 309void setup() { 310 Serial.begin(115200); 311 Serial.flush(); 312 Serial.println(F("Start")); 313 M5.begin(); 314 315 prefs.begin("AM_Chess", false); 316 317 M5.Lcd.setBrightness(200); // BRIGHTNESS = MAX 255 318 M5.Lcd.fillScreen(BLACK); // CLEAR SCREEN 319 M5.Lcd.setRotation(0); // SCREEN ROTATION = 0 320 definecolors(); 321 beep(100); 322 for (int i=0;i<MAXSTEPS;i++) { 323 steps[i].x1=0; steps[i].y1=0; 324 steps[i].x2=0; steps[i].y2=0; 325 steps[i].fig1=0; steps[i].fig2=0; 326 steps[i].check=0; 327 steps[i].type=0; 328 steps[i].weight=0; 329 } 330 M5.Lcd.setTextColor(getColor(230,230,200)); 331 M5.Lcd.setTextSize(2); 332 M5.Lcd.setCursor(50,30); M5.Lcd.print("Arduino Mega Chess"); 333 M5.Lcd.setCursor(88,50); M5.Lcd.print("for M5Stack"); 334 M5.Lcd.setTextColor(CGRAY); 335 M5.Lcd.setCursor(62,70); M5.Lcd.print("by Sergey Urusov"); 336 M5.Lcd.setTextSize(1); 337 M5.Lcd.setCursor(100,95); M5.Lcd.print("urusovsv@gmail.com"); 338 M5.Lcd.setCursor(85,110); M5.Lcd.print("version 1.0, engine 1.4"); 339 M5.Lcd.setCursor(80,220); M5.Lcd.print("press any key to READ this"); 340 M5.Lcd.setTextColor(CWHITEFIG); 341 M5.Lcd.drawRect(38,150,60,30,CGRAY); 342 M5.Lcd.drawRect(130,150,60,30,CGRAY); 343 M5.Lcd.drawRect(225,150,60,30,CGRAY); 344 M5.Lcd.setTextSize(1); 345 M5.Lcd.setCursor(57,162); M5.Lcd.print("Left"); 346 M5.Lcd.setCursor(143,162); M5.Lcd.print("Choice"); 347 M5.Lcd.setCursor(240,162); M5.Lcd.print("Right"); 348 M5.Lcd.setCursor(110,190); M5.Lcd.print("long press - menu"); 349 M5.Lcd.setCursor(110,200); M5.Lcd.print("or exit from menu"); 350 351 uint32_t tim=millis(); 352 while (millis()-tim<1500) { 353 M5.update(); 354 if (M5.BtnA.wasPressed()||M5.BtnB.wasPressed()||M5.BtnC.wasPressed()) { 355 beep(100); 356 M5.Lcd.fillRect(75,220,180,12,CBLACK); 357 M5.Lcd.setTextColor(CGRAY); 358 M5.Lcd.setCursor(77,220); M5.Lcd.print("press any key to ENTER game"); 359 while (millis()-tim<30000) { 360 M5.update(); 361 if (M5.BtnA.wasPressed()||M5.BtnB.wasPressed()||M5.BtnC.wasPressed()) break; 362 } 363 break; 364 } 365 } 366 beep(100); 367 M5.Lcd.fillScreen(BLACK); // CLEAR SCREEN 368 initboard(); 369} 370//**************************** 371void initboard() { 372 for (int i=0;i<8;i++) 373 for (int j=0;j<8;j++) poledisp[j][i]=-100; // 374 M5.Lcd.fillScreen(CBLACK); 375 M5.Lcd.setTextColor(CGRAY); 376 M5.Lcd.setTextSize(1); 377 for (int j=1;j<9;j++) { 378 M5.Lcd.setCursor(0,j*28-17); 379 if (rotate) M5.Lcd.print(j); else M5.Lcd.print(9-j); 380 } 381 for (byte i=1;i<9;i++) { 382 M5.Lcd.setCursor(i*28-9,227); 383 if (rotate) M5.Lcd.print(char(96+9-i)); else M5.Lcd.print(char(96+i)); 384 } 385 initscreen(); 386} 387//**************************** 388void initscreen() { 389 show_board(); 390 show_steps(); 391} 392//**************************** 393void loop() { 394 gui(); 395 if (solving) { 396 for (int i=1;i<3;i++) { tone_volume(400+400*i,100); delay(70); } 397 hidden=false; 398 lastscore=solve_step(); 399 float tim=float(millis()-starttime)/1000; 400 for (int i=2;i>=1;i--) { tone_volume(400+400*i,100); delay(70); } 401 if (lastscore>-9000&&lastscore!=8999) { 402 movestep(cur_step); 403 cur_step++; steps[cur_step].fig1=0; 404 } 405 initscreen(); 406 animate_step(cur_step-1,false); 407 clearstatus(); 408 if (lastscore>9000) { 409 M5.Lcd.setTextSize(1); 410 M5.Lcd.setTextColor(CGREEN,CBLACK); 411 M5.Lcd.setCursor(260,176); 412 if (lastscore<9999) { 413 M5.Lcd.print("# in "); 414 M5.Lcd.print((9999-lastscore)/2+1); M5.Lcd.print(F(" st")); 415 } else M5.Lcd.print("Checkmate"); 416 } else if (lastscore<-9000) { 417 M5.Lcd.setTextSize(1); 418 M5.Lcd.setTextColor(CRED,CBLACK); 419 M5.Lcd.setCursor(260,176); 420 steps[cur_step].fig1=0; 421 M5.Lcd.print("GIVE UP!"); 422 show_steps(); 423 } else if (lastscore==8999) { //Draw 424 M5.Lcd.setTextSize(1); 425 M5.Lcd.setTextColor(CYELLOW); 426 M5.Lcd.setCursor(260,176); 427 M5.Lcd.print("Draw"); 428 } 429 M5.Lcd.setTextSize(1); 430 M5.Lcd.setTextColor(CGRAY); 431 M5.Lcd.setCursor(240,176); 432 M5.Lcd.print(tim,0); 433 M5.Lcd.print("s "); 434 if (abs(lastscore)<5000) { 435 M5.Lcd.print(lastscore); 436 } 437 M5.Lcd.setCursor(240,166); 438 M5.Lcd.print(count); 439 M5.Lcd.print("pos"); 440 Serial.print(F("Positions estimated=")); Serial.println(count); 441 Serial.print(F("Time=")); Serial.print(tim,1); Serial.println("s"); 442 Serial.print(F("Speed=")); Serial.print(count/tim,1); Serial.println("nps"); 443 lastpressedany=millis(); 444 } 445 delay(10); 446 447 448} 449//**************************** 450void load_moves() { 451 start_var=cur_step+21; 452 only_action=false; 453 lastbest.fig1=0; 454 steps[0].fig1=0; 455 load_variants(cur_step); 456 current_var=start_var; 457 int cv=cur_var; 458 hidden=true; 459 uint32_t tim=millis(); 460 solve_step(); 461 if (millis()-tim<1000) delay(millis()-tim); 462 cur_var=cv; 463 sort_variants(cur_step+21,cur_step+20+cur_var); 464 465} 466//********************************** 467void gui() { 468 if (isstatus) { 469 if (millis()-quitime>1000) { 470 if (isstatus) show_status(); 471 quitime=millis(); 472 } 473 } 474 M5.update(); 475 if (M5.BtnB.wasPressed()) 476 if (lastpressed==0) lastpressed=millis(); // 477 if (M5.BtnA.wasPressed()) 478 if (lastpressedleft==0) lastpressedleft=millis(); // 479 if (M5.BtnC.wasPressed()) 480 if (lastpressedright==0) lastpressedright=millis(); // 481 482 lastpressedany=max(max(max(lastpressed,lastpressedleft),lastpressedright),lastpressedany); 483 484 if (!menu&&!isstatus&&rotate==cur_step%2) { // AI 485 if (millis()>lastpressedany+3000) { 486 delay(100); 487 solving=true; 488 Serial.println(F("\ 489Autostart solving!")); 490 return; 491 } 492 float angle=3.1416-6.2832*(millis()-lastpressedany)/3000; 493 M5.Lcd.drawLine(308,175,308+9*sin(angle),175+9*cos(angle),CGRAY); 494 delay(200); 495 } 496 497 if (!menu&&!isstatus&&rotate!=cur_step%2) { // 498 if (!movesload) { 499 load_moves(); 500 movesload=1; 501 animate_step(cur_step-1,true); 502 } 503 animategreen_step(current_var,false); 504 delay(100); 505 } 506 507 if (M5.BtnB.isReleased()&&lastpressed) 508 if (millis()-lastpressed>500) { // 509 if (!isstatus) { 510 if (movesload) animategreen_step(current_var,true); 511 movesload=0; 512 lastpressed=0; 513 beep(50); 514 if (menu==0) menu=1; else menu=0; 515 submenu=0; 516 show_menu(); 517 } 518 return; 519 } else { 520 if (movesload&&cur_var>0) animategreen_step(current_var,true); 521 beep(5); 522 lastpressed=0; 523 switch (menu) { 524 case 0: // 525 if (solving) { // 526 beep(100); 527 solving=false; 528 } else { // AI 529 if (movesload) { 530 movesload=0; 531 float tim=float(millis()-starttime)/1000; 532 tone_volume(600,100); 533 steps[cur_step]=steps[current_var]; 534 movestep(cur_step); 535 cur_step++; steps[cur_step].fig1=0; 536 initscreen(); 537 animate_step(cur_step-1,false); 538 clearstatus(); 539 } else { 540 delay(100); 541 solving=1; 542 animate_step(cur_step,false); 543 } 544 } 545 return; 546 case 1: 547 if (submenu) { //new game 548 beep(200); 549 cur_step=1; 550 steps[1].fig1=0; 551 for (int i=0;i<8;i++) 552 for (int j=0;j<8;j++) pole[j][i]=(signed char)pgm_read_byte(&polestart[j][i]); 553 lastanimatedgreen.x1==99; 554 kingpositions(); 555 initboard(); 556 clearstatus(); 557 menu=0; 558 initscreen(); 559 show_menu(); 560 } else if (cur_step>1) { // 561 beep(100); 562 cur_step--; 563 animate_step(cur_step,true); 564 lastscore=0; 565 backstep(cur_step); 566 steps[cur_step].fig1=0; 567 lastscore=0; 568 show_board(); 569 menu=0; 570 show_steps(); 571 clearstatus(); 572 return; 573 } break; 574 case 2: 575 if (submenu) { //load game 576 short cur_step_=prefs.getShort("cur_step"); 577 short limit_=prefs.getShort("limit"); 578 if (cur_step>0&&cur_step<1000&&limit>=0&&limit<3) { 579 initboard(); 580 cur_step=cur_step_; limit=limit_; 581 sound=prefs.getBool("sound"); 582 rotate=prefs.getBool("rotate"); 583 prefs.getBytes("pole",pole,sizeof(pole)); 584 prefs.getBytes("steps",steps,sizeof(step_type)*cur_step); 585 beep(100); 586 } else { 587 beep(1000); sound=1; rotate=0; limit=0; cur_step=1; 588 } 589 //File file = SD.open("/AM_Chess.sav"); 590 //if (file) { 591 // Serial.println("file open"); 592 // file.read((uint8_t*)pole,64); 593 // uint8_t c[sizeof(step_type)]; 594 // file.read(c,sizeof(cur_step)); memcpy(&cur_step,c,sizeof(cur_step)); 595 // file.read(c,sizeof(limit)); memcpy(&limit,c,sizeof(limit)); 596 // file.read(c,sizeof(sound)); memcpy(&sound,c,sizeof(sound)); 597 // step_type t; 598 // for (int i=1;i<cur_step;i++) { 599 // t=steps[i]; 600 // file.read(c,sizeof(step_type)); 601 // memcpy(&t,c,sizeof(step_type)); 602 // } 603 // file.close(); 604 // beep(100); 605 //} else { beep(1000); Serial.println("SD card error!"); } 606 steps[0].fig1=0; 607 steps[cur_step].fig1=0; 608 lastanimatedgreen.x1==99; 609 initboard(); 610 kingpositions(); 611 clearstatus(); 612 menu=0; 613 show_menu(); 614 initscreen(); 615 return; 616 } else { // 617 beep(100); 618 rotate=!rotate; 619 initboard(); 620 return; 621 } break; 622 case 3: 623 if (submenu) { //save game 624 prefs.putShort("cur_step",cur_step); 625 prefs.putShort("limit",limit); 626 prefs.putBool("sound",sound); 627 prefs.putBool("rotate",rotate); 628 prefs.putBytes("pole",pole,sizeof(pole)); 629 prefs.putBytes("steps",steps,sizeof(step_type)*cur_step); 630 beep(50); delay(50); beep(50); delay(50); beep(50); 631 //File file = SD.open("/AM_Chess.sav", FILE_WRITE); 632 //if (file) { 633 // Serial.println("file open for write"); 634 // file.write((const uint8_t*)pole,64); 635 // uint8_t c[sizeof(step_type)]; 636 // memcpy(c,&cur_step,sizeof(cur_step)); file.write(c,sizeof(cur_step)); 637 // memcpy(c,&limit,sizeof(limit)); file.write(c,sizeof(limit)); 638 // memcpy(c,&sound,sizeof(sound)); file.write(c,sizeof(sound)); 639 // step_type t; 640 // for (int i=1;i<cur_step;i++) { 641 // t=steps[i]; 642 // memcpy(c,&t,sizeof(step_type)); 643 // file.write(c,sizeof(step_type)); 644 // } 645 // file.close(); 646 // beep(100); 647 //} else { beep(1000); Serial.println("SD card error!"); } 648 menu=0; 649 show_menu(); 650 return; 651 } else { // Game 652 submenu=1; menu=1; 653 show_menu(); 654 } break; 655 case 4: 656 if (submenu) { // USB 657 if (!load_usb()) return; 658 limit=2; 659 beep(200); 660 menu=0; 661 initboard(); 662 kingpositions(); 663 clearstatus(); 664 initscreen(); 665 return; 666 } else { // 667 beep(100); 668 limit++; if (limit>2) limit=0; 669 show_menu(); 670 return; 671 } 672 case 5: // 673 if (sound==1) { beep(100); sound=0; } else { sound=1; beep(200); } 674 show_menu(); 675 return; 676 } //switch 677 678 } 679 if (M5.BtnA.wasPressed()) { 680 lastpressedleft=0; 681 if (menu==0) { 682 if (movesload&&cur_var>0) { 683 animategreen_step(current_var,true); 684 current_var--; 685 if (current_var<cur_step+21) current_var=cur_step+21+cur_var-1; 686 } 687 } else { 688 beep(100); 689 menu--; 690 if (menu<1) 691 if (submenu) menu=4; else menu=5; 692 show_menu(); 693 delay(200); 694 } 695 } 696 if (M5.BtnC.wasPressed()) { 697 lastpressedright=0; 698 if (menu==0) { 699 if (movesload&&cur_var>0) { 700 animategreen_step(current_var,true); 701 current_var++; 702 if (current_var>=cur_step+21+cur_var) current_var=cur_step+21; 703 } 704 } else { 705 beep(100); 706 menu++; if (menu>5) menu=1; 707 if (submenu&&menu>4) menu=1; 708 show_menu(); 709 delay(200); 710 } 711 } 712 713 714} 715//********************************** 716void animategreen_step(int nstep, boolean hide) { 717 if (cur_var==0) return; 718 int j=steps[nstep].x1; 719 int j2=steps[nstep].x2; 720 int dj=j2-j; 721 int i=steps[nstep].y1; 722 int i2=steps[nstep].y2; 723 int di=i2-i; 724 if (di!=0) di=di/abs(di); 725 if (dj!=0) dj=dj/abs(dj); 726 if (lastanimatedgreen.x1==steps[nstep].x1&&lastanimatedgreen.y1==steps[nstep].y1&& 727 lastanimatedgreen.x2==steps[nstep].x2&&lastanimatedgreen.y2==steps[nstep].y2&& 728 lastanimatedgreen.fig1==steps[nstep].fig1&&!hide) { 729 int show=(millis()/500)%2; 730 movestep(nstep); 731 if (show) show_cont(i2,j2); 732 backstep(nstep); 733 if (!show) show_fig(i2,j2); 734 if (!rotate) M5.Lcd.drawRect(i2*28+8,j2*28+1,27,27,CGREEN); 735 else M5.Lcd.drawRect((7-i2)*28+8,(7-j2)*28+1,27,27,CGREEN); 736 return; 737 } 738 lastanimatedgreen=steps[nstep]; 739 if (hide) show_fig(i,j); 740 while (j!=steps[nstep].x2||i!=steps[nstep].y2) { 741 show_fig(i,j); 742 if (!hide) 743 if (!rotate) M5.Lcd.drawRect(i*28+8,j*28+1,27,27,CGREEN); 744 else M5.Lcd.drawRect((7-i)*28+8,(7-j)*28+1,27,27,CGREEN); 745 int mj=0; 746 if (j!=steps[nstep].x2) { j+=dj; mj=1; } 747 if (abs(steps[nstep].fig1)==fn&&mj==1) continue; 748 if (i!=steps[nstep].y2) i+=di; 749 } 750 if (hide) { show_fig(i,j); lastanimatedgreen.x1=99; } 751 752} 753//**************************** 754void show_cont(int i,int j) { 755uint16_t color,color_cont; 756 color=CBLACKF; 757 if ((i+j+2)%2==0) color=CWHITEF; 758 int jj=j, ii=i; 759 if (rotate) { jj=7-j; ii=7-i; } 760 M5.Lcd.fillRect(ii*28+7,jj*28,29,29,color); 761 //M5.Lcd.drawRect(ii*28+7,jj*28,29,29,CGREEN); 762 color=CBLACK; 763 if (pole[j][i]>0) color=CWHITE; 764 if (pole[j][i]!=0) { 765 drawBitmap(ii*28+10, jj*28+3,&fig_cont[abs(pole[j][i])-1][0], 24, 24,color); 766 } 767} 768//********************************** 769void animate_step(int nstep, boolean hide) { 770uint16_t color=getColor(220,220,200); 771 if (!hide&&nstep-1>0&&steps[nstep-1].fig1!=0) animate_step(nstep-1,true); 772 if (nstep<1||steps[nstep].fig1==0) return; 773 int j=steps[nstep].x1; 774 int dj=steps[nstep].x2-steps[nstep].x1; 775 int i=steps[nstep].y1; 776 int di=steps[nstep].y2-steps[nstep].y1; 777 if (di!=0) di=di/abs(di); 778 if (dj!=0) dj=dj/abs(dj); 779 if (hide) show_fig(i,j); 780 while (j!=steps[nstep].x2||i!=steps[nstep].y2) { 781 show_fig(i,j); 782 if (!hide) 783 if (!rotate) M5.Lcd.drawRect(i*28+8,j*28+1,27,27,color); 784 else M5.Lcd.drawRect((7-i)*28+8,(7-j)*28+1,27,27,color); 785 int mj=0; 786 if (j!=steps[nstep].x2) { j+=dj; mj=1; } 787 if (abs(steps[nstep].fig1)==fn&&mj==1) continue; 788 if (i!=steps[nstep].y2) i+=di; 789 } 790 show_fig(i,j); 791 if (!hide) 792 if (!rotate) M5.Lcd.drawRect(i*28+8,j*28+1,27,27,color); 793 else M5.Lcd.drawRect((7-i)*28+8,(7-j)*28+1,27,27,color); 794} 795//********************************** 796void show_status() { 797 if (rotate!=cur_step%2) return; 798 int tim=(millis()-starttime)/1000; 799 int cur=220000*tim/(limittime-starttime); 800 if (cur>220) { cur=220; solving=false; } 801 M5.Lcd.drawFastHLine(10,237,cur,CGRAY); 802 M5.Lcd.drawFastHLine(10,239,progress*2,CGRAY); 803 int m=tim/60; 804 int s=tim%60; 805 M5.Lcd.setTextWrap(1); 806 M5.Lcd.setTextColor(CGRAY); 807 M5.Lcd.setTextSize(1); 808 M5.Lcd.fillRect(240,166,80,10,CBLACK); 809 M5.Lcd.setCursor(242,166); 810 if (m>0) { M5.Lcd.print(m); M5.Lcd.print(":"); } 811 if (s>0) { 812 if (s<10&&m>0) M5.Lcd.print("0"); 813 M5.Lcd.print(s); 814 } else if (m>0) M5.Lcd.print("00"); else M5.Lcd.print("0"); 815 M5.Lcd.setCursor(280,166); 816 M5.Lcd.print(cur_level); 817 M5.Lcd.setCursor(242,176); 818 if (cur_step%2==1) M5.Lcd.setTextColor(CWHITE); else M5.Lcd.setTextColor(CGRAY); 819 if (lastbest.fig1!=steps[0].fig1||lastbest.x1!=steps[0].x1||lastbest.y1!=steps[0].y1|| 820 lastbest.x2!=steps[0].x2||lastbest.y2!=steps[0].y2) { 821 lastbest=steps[0]; 822 M5.Lcd.fillRect(240,176,80,10,CBLACK); 823 M5.Lcd.setCursor(242,176); 824 M5.Lcd.setTextColor(CGRAY); 825 M5.Lcd.print(str_step(0)); 826 blinkstep=0; 827 } 828 if (steps[0].fig1!=0&&blinkstep==0&&tim>5) { 829 signed char poleb[8][8]; 830 for (int i=0;i<8;i++) 831 for (int j=0;j<8;j++) { poleb[j][i]=pole[j][i]; pole[j][i]=pole0[j][i]; } 832 movestep(0); 833 show_board(); 834 delay(100); 835 backstep(0); 836 show_board(); 837 for (int i=0;i<8;i++) 838 for (int j=0;j<8;j++) pole[j][i]=poleb[j][i]; 839 kingpositions(); 840 } 841 blinkstep++; 842 if (blinkstep>2) blinkstep=0; 843} 844//**************************** 845void show_fig(int i,int j) { 846uint16_t color,color_cont; 847 color=CBLACKF; 848 if ((i+j+2)%2==0) color=CWHITEF; 849 int jj=j, ii=i; 850 if (rotate) { jj=7-j; ii=7-i; } 851 M5.Lcd.fillRect(ii*28+7,jj*28,29,29,color); 852 M5.Lcd.drawRect(ii*28+7,jj*28,29,29,CGRAY); 853 color=CBLACKFIG; color_cont=CBLACKCONT; //CGRAY; 854 if (pole[j][i]>0) { color=CWHITEFIG; color_cont=CBLACK; } 855 if (pole[j][i]!=0) { 856 drawBitmap(ii*28+10, jj*28+3,&fig[abs(pole[j][i])-1][0], 24, 24,color); 857 drawBitmap(ii*28+10, jj*28+3,&fig_cont[abs(pole[j][i])-1][0], 24, 24,color_cont); 858 } 859} 860//**************************** 861void show_board() { 862 for (int i=0;i<8;i++) 863 for (int j=0;j<8;j++) { 864 if (poledisp[j][i]!=pole[j][i]) show_fig(i,j); 865 poledisp[j][i]=pole[j][i]; 866 } 867} 868//********************************** 869boolean load_usb() { 870char s='x',i=0,j=0; boolean load=false; 871 Serial.println(F("Wait for FEN position")); 872 for (int i=0;i<8;i++) 873 for (int j=0;j<8;j++) { 874 pole0[j][i]=pole[j][i]; 875 pole[j][i]=(char)pgm_read_byte(&polezero[j][i]); 876 } 877 while (s!=' ') { 878 s=Serial.read(); 879 if (i>7) { i=0; j++; } 880 if (!getpole(j,i)) break; 881 switch (s) { 882 case '/': i=0; break; 883 case 'p': pole[j][i]=-fp; i++; break; 884 case 'P': pole[j][i]=fp; i++; break; 885 case 'n': pole[j][i]=-fn; i++; break; 886 case 'N': pole[j][i]=fn; i++; break; 887 case 'b': pole[j][i]=-fb; i++; break; 888 case 'B': pole[j][i]=fb; i++; break; 889 case 'r': pole[j][i]=-fr; i++; break; 890 case 'R': pole[j][i]=fr; i++; break; 891 case 'q': pole[j][i]=-fq; i++; break; 892 case 'Q': pole[j][i]=fq; i++; break; 893 case 'k': pole[j][i]=-fk; i++; break; 894 case 'K': pole[j][i]=fk; i++; break; 895 case '1': i++; break; 896 case '2': i+=2; break; 897 case '3': i+=3; break; 898 case '4': i+=4; break; 899 case '5': i+=5; break; 900 case '6': i+=6; break; 901 case '7': i+=7; break; 902 case '8': i=0; j++; break; 903 case ' ': break; 904 } 905 delay(20); 906 if (i+j>0&&Serial.available()==0) break; 907 } 908 s=0; 909 if (Serial.available()>0) s=Serial.read(); 910 while (Serial.available()>0) Serial.read(); 911 if (s=='w'||s==0) { cur_step=1; load=true; rotate=1; } 912 else if (s=='b') { cur_step=2; load=true; rotate=0; } 913 else load=false; 914 if (load) { 915 steps[1].fig1=0; steps[2].fig1=0; 916 Serial.println(F("Position loaded")); 917 } else { 918 for (int i=0;i<8;i++) 919 for (int j=0;j<8;j++) 920 pole[j][i]=pole0[j][i]; 921 } 922 return load; 923} 924//********************************** 925String str_step(int i) { 926 String s=""; 927 if (steps[i].fig1==0) return s; 928 if (steps[i].type==2) s="0-0"; 929 else if (steps[i].type==3) s="0-0-0"; 930 else { 931 if (abs(steps[i].fig1)>1) s=fig_symb[abs(steps[i].fig1)]; 932 if (abs(steps[i].fig1<5)) { 933 s=s+char(97+steps[i].y1); 934 s=s+String(8-steps[i].x1); 935 if (steps[i].fig2==0) s=s+"-"; 936 } 937 if (steps[i].fig2!=0) { 938 s=s+"x"; 939 if (abs(steps[i].fig2)>1) s=s+fig_symb[abs(steps[i].fig2)]; 940 } 941 s=s+char(97+steps[i].y2); 942 s=s+String(8-steps[i].x2); 943 } 944 if (steps[i].type>3) s=s+fig_symb[steps[i].type-2]; 945 if (steps[i].check==1) s=s+"+"; else 946 if (steps[i].check==2) s=s+"#"; 947 return s; 948} 949//**************************** 950void show_steps() { 951uint16_t color=getColor(200,200,180); 952 M5.Lcd.fillRect(234,0,90,160,getColor(8,8,8)); 953 M5.Lcd.fillRect(234,0,90,24,CDARK); 954 M5.Lcd.setTextSize(1); 955 M5.Lcd.setTextColor(getColor(160,160,140),CDARK); 956 M5.Lcd.setCursor(241,2); 957 M5.Lcd.print(" ArduinoMega"); 958 M5.Lcd.setCursor(240,14); 959 M5.Lcd.print("Chess M5Stack"); 960 int i=1; int y=27; 961 int cur=(cur_step+1)/2; // 962 int lim_step=cur_step; 963 if (cur>6) i=cur-5; 964 while (i<=cur&&y<140) { // 965 M5.Lcd.setCursor(240,y); 966 M5.Lcd.setTextColor(CGRAY); 967 M5.Lcd.print(i); 968 M5.Lcd.print(". "); 969 if (i*2-1==cur_step-1) M5.Lcd.setTextColor(color); 970 if (steps[i*2-1].fig1!=0) M5.Lcd.print(str_step(i*2-1)); 971 if (steps[i*2].fig1==0||i*2>lim_step) break; 972 M5.Lcd.setTextColor(CBLACK); 973 M5.Lcd.setCursor(240,y+10); 974 M5.Lcd.print(i); 975 M5.Lcd.print(" "); 976 M5.Lcd.setTextColor(CGRAY); 977 if (i*2==cur_step-1) M5.Lcd.setTextColor(color); 978 M5.Lcd.print(str_step(i*2)); 979 i++; y+=22; 980 } 981 show_menu(); 982} 983//**************************** 984void show_menu() { 985uint16_t color=getColor(220,220,200); 986 if (menu==0) submenu=0; else animategreen_step(current_var,true); 987 988 M5.Lcd.fillRect(233,190,86,50,CBLACK); 989 M5.Lcd.setTextSize(1); 990 if (menu==1) M5.Lcd.setTextColor(CBLACK,CBLUE); else M5.Lcd.setTextColor(color,CGRAY2); 991 if (submenu) { 992 M5.Lcd.setCursor(242,190); M5.Lcd.print(" New Game "); 993 } else { 994 M5.Lcd.setCursor(233,190); M5.Lcd.print(" Back "); 995 } 996 if (menu==2) M5.Lcd.setTextColor(CBLACK,CBLUE); else M5.Lcd.setTextColor(color,CGRAY2); 997 if (submenu) { 998 M5.Lcd.setCursor(242,203); M5.Lcd.print(" Load Game "); 999 } else { 1000 M5.Lcd.setCursor(271,190); M5.Lcd.print(" Rotate "); 1001 } 1002 if (menu==3) M5.Lcd.setTextColor(CBLACK,CBLUE); else M5.Lcd.setTextColor(color,CGRAY2); 1003 if (submenu) { 1004 M5.Lcd.setCursor(242,216); M5.Lcd.print(" Save Game "); 1005 } else { 1006 M5.Lcd.setCursor(242,203); M5.Lcd.print(" Game menu "); 1007 } 1008 if (menu==4) M5.Lcd.setTextColor(CBLACK,CBLUE); else M5.Lcd.setTextColor(color,CGRAY2); 1009 if (submenu) { 1010 M5.Lcd.setCursor(242,229); M5.Lcd.print(" USB FEN "); 1011 } else { 1012 M5.Lcd.setCursor(242,216); M5.Lcd.print(" Level "); 1013 switch (limit) { 1014 case 0: M5.Lcd.print("LOW "); break; 1015 case 1: M5.Lcd.print("MED "); break; 1016 case 2: M5.Lcd.print("HIGH"); break; 1017 } 1018 } 1019 if (menu==5) M5.Lcd.setTextColor(CBLACK,CBLUE); else M5.Lcd.setTextColor(color,CGRAY2); 1020 if (submenu) { 1021 } else { 1022 M5.Lcd.setCursor(242,227); M5.Lcd.print(" Sound "); 1023 if (sound) M5.Lcd.print("ON "); else M5.Lcd.print("OFF "); 1024 } 1025} 1026 1027//**************************** 1028boolean getdiagrowcheckw(signed char dj,signed char di) { // 1029signed char d,j1,i1; 1030 j1=WKJ; i1=WKI; 1031 for (d=1;d<8;d++) { 1032 j1+=dj; i1+=di; 1033 if (getpole(j1,i1)) { 1034 if (pole[j1][i1]==-fq||pole[j1][i1]==-fb) return true; 1035 if (pole[j1][i1]!=0) break; 1036 } else break; 1037 } 1038 return false; 1039} 1040//**************************** 1041boolean getdiagrowcheckb(signed char dj,signed char di) { // 1042signed char d,j1,i1; 1043 j1=BKJ; i1=BKI; 1044 for (d=1;d<8;d++) { 1045 j1+=dj; i1+=di; 1046 if (getpole(j1,i1)) { 1047 if (pole[j1][i1]==fq||pole[j1][i1]==fb) return true; 1048 if (pole[j1][i1]!=0) break; 1049 } else break; 1050 } 1051 return false; 1052} 1053//**************************** 1054boolean getstreightrowcheckw(signed char dj,signed char di) { // - 1055signed char d,j1,i1; 1056 j1=WKJ; i1=WKI; 1057 for (d=1;d<8;d++) { 1058 j1+=dj; i1+=di; 1059 if (getpole(j1,i1)) { 1060 if (pole[j1][i1]==-fq||pole[j1][i1]==-fr) return true; 1061 if (pole[j1][i1]!=0) break; 1062 } else break; 1063 } 1064 return false; 1065} 1066//**************************** 1067boolean getstreightrowcheckb(signed char dj,signed char di) { // - 1068signed char d,j1,i1; 1069 j1=BKJ; i1=BKI; 1070 for (d=1;d<8;d++) { 1071 j1+=dj; i1+=di; 1072 if (getpole(j1,i1)) { 1073 if (pole[j1][i1]==fq||pole[j1][i1]==fr) return true; 1074 if (pole[j1][i1]!=0) break; 1075 } else break; 1076 } 1077 return false; 1078} 1079//**************************** 1080boolean get_check(signed char king) { // 1081 if (king==fk) { // 1082 if (getdiagrowcheckw(-1, 1)) return true; 1083 if (getdiagrowcheckw(-1,-1)) return true; 1084 if (getdiagrowcheckw( 1,-1)) return true; 1085 if (getdiagrowcheckw( 1, 1)) return true; 1086 if (getstreightrowcheckw(-1, 0)) return true; 1087 if (getstreightrowcheckw( 0, 1)) return true; 1088 if (getstreightrowcheckw( 0,-1)) return true; 1089 if (getstreightrowcheckw( 1, 0)) return true; 1090 if (getpole(WKJ-2,WKI-1)&&pole[WKJ-2][WKI-1]==-fn) return true; 1091 if (getpole(WKJ-2,WKI+1)&&pole[WKJ-2][WKI+1]==-fn) return true; 1092 if (getpole(WKJ-1,WKI-2)&&pole[WKJ-1][WKI-2]==-fn) return true; 1093 if (getpole(WKJ-1,WKI+2)&&pole[WKJ-1][WKI+2]==-fn) return true; 1094 if (getpole(WKJ+1,WKI-2)&&pole[WKJ+1][WKI-2]==-fn) return true; 1095 if (getpole(WKJ+1,WKI+2)&&pole[WKJ+1][WKI+2]==-fn) return true; 1096 if (getpole(WKJ+2,WKI-1)&&pole[WKJ+2][WKI-1]==-fn) return true; 1097 if (getpole(WKJ+2,WKI+1)&&pole[WKJ+2][WKI+1]==-fn) return true; 1098 if (getpole(WKJ-1,WKI-1)&&pole[WKJ-1][WKI-1]==-fp) return true; 1099 if (getpole(WKJ-1,WKI+1)&&pole[WKJ-1][WKI+1]==-fp) return true; 1100 } else { // 1101 if (getdiagrowcheckb( 1,-1)) return true; 1102 if (getdiagrowcheckb( 1, 1)) return true; 1103 if (getdiagrowcheckb(-1, 1)) return true; 1104 if (getdiagrowcheckb(-1,-1)) return true; 1105 if (getstreightrowcheckb( 1, 0)) return true; 1106 if (getstreightrowcheckb( 0, 1)) return true; 1107 if (getstreightrowcheckb( 0,-1)) return true; 1108 if (getstreightrowcheckb(-1, 0)) return true; 1109 if (getpole(BKJ+2,BKI-1)&&pole[BKJ+2][BKI-1]==fn) return true; 1110 if (getpole(BKJ+2,BKI+1)&&pole[BKJ+2][BKI+1]==fn) return true; 1111 if (getpole(BKJ+1,BKI-2)&&pole[BKJ+1][BKI-2]==fn) return true; 1112 if (getpole(BKJ+1,BKI+2)&&pole[BKJ+1][BKI+2]==fn) return true; 1113 if (getpole(BKJ-1,BKI-2)&&pole[BKJ-1][BKI-2]==fn) return true; 1114 if (getpole(BKJ-1,BKI+2)&&pole[BKJ-1][BKI+2]==fn) return true; 1115 if (getpole(BKJ-2,BKI-1)&&pole[BKJ-2][BKI-1]==fn) return true; 1116 if (getpole(BKJ-2,BKI+1)&&pole[BKJ-2][BKI+1]==fn) return true; 1117 if (getpole(BKJ+1,BKI-1)&&pole[BKJ+1][BKI-1]==fp) return true; 1118 if (getpole(BKJ+1,BKI+1)&&pole[BKJ+1][BKI+1]==fp) return true; 1119 } 1120 if (abs(BKJ-WKJ)<=1&&abs(BKI-WKI)<=1) return true; // 1121 return false; 1122} 1123//**************************** 1124boolean getpole(signed char j,signed char i) { // 1125 if (j>=0&&j<8&&i>=0&&i<8) return true; 1126 return false; 1127} 1128//**************************** 1129void addstep(signed char j1,signed char i1,signed char j2,signed char i2,signed char type) { 1130 int st=start_var+cur_var; 1131 steps[st].x1=j1; 1132 steps[st].x2=j2; 1133 steps[st].y1=i1; 1134 steps[st].y2=i2; 1135 steps[st].fig1=pole[j1][i1]; 1136 steps[st].fig2=pole[j2][i2]; 1137 if (type==1) { // 1138 steps[st].fig2=-steps[st].fig1; 1139 } 1140 steps[st].type=type; 1141 signed char ko=-fk; // 1142 if (steps[st].fig1>0) ko=fk; 1143 movestep(st); 1144 if (get_check(ko)) { backstep(st); return; } // - 1145 boolean che=get_check(-ko); // 1146 backstep(st); 1147 steps[st].weight=abs(steps[st].fig2)-abs(steps[st].fig1); 1148 if (type>3) steps[st].weight+=fig_weight[type-2]; 1149 if (endspiel&&steps[st].fig1==ko) steps[st].weight+=10; // - 1150 steps[st].check=che; 1151 if (che) steps[st].weight+=10; 1152 if (only_action) { 1153 if (steps[st].fig1==fp&&steps[st].x2==1||steps[st].fig1==-fp&&steps[st].x2==6) // 1154 { cur_var++; return; } 1155 if (steps[st].fig2==0&&steps[st].type<4&&!che&&!check_on_table) return; 1156 } 1157 1158 cur_var++; 1159} 1160//**************************** 1161void getrowstepsw(signed char j,signed char i,signed char dj,signed char di) { // 1162signed char d,j1,i1; 1163 j1=j; i1=i; 1164 for (d=1;d<8;d++) { 1165 j1+=dj; i1+=di; 1166 if (getpole(j1,i1)) { 1167 if (pole[j1][i1]<=0) addstep(j,i,j1,i1,0); 1168 if (pole[j1][i1]!=0) break; 1169 } else break; 1170 } 1171} 1172//**************************** 1173void getrowstepsb(signed char j,signed char i,signed char dj,signed char di) { // 1174signed char d,j1,i1; 1175 j1=j; i1=i; 1176 for (d=1;d<8;d++) { 1177 j1+=dj; i1+=di; 1178 if (getpole(j1,i1)) { 1179 if (pole[j1][i1]>=0) addstep(j,i,j1,i1,0); 1180 if (pole[j1][i1]!=0) break; 1181 } else break; 1182 } 1183} 1184//**************************** 1185void getonestepw(signed char j,signed char i,signed char dj,signed char di) { // 1186signed char j1,i1; 1187 j1=j+dj; i1=i+di; 1188 if (getpole(j1,i1)) 1189 if (pole[j1][i1]<=0) addstep(j,i,j1,i1,0); 1190} 1191//**************************** 1192void getonestepb(signed char j,signed char i,signed char dj,signed char di) { // 1193signed char j1,i1; 1194 j1=j+dj; i1=i+di; 1195 if (getpole(j1,i1)) 1196 if (pole[j1][i1]>=0) addstep(j,i,j1,i1,0); 1197} 1198//**************************** 1199void sort_variants(int from, int to) { // 1200 while (1) { 1201 int mov=0; 1202 for (int i=from;i<to;i++) // 1203 if (steps[i].weight<steps[i+1].weight) { 1204 mov++; 1205 step_type buf=steps[i]; 1206 steps[i]=steps[i+1]; 1207 steps[i+1]=buf; 1208 } 1209 if (mov==0) break; 1210 } 1211} 1212//**************************** 1213void load_variants(int nstep) { // nstep 1214 cur_var=0; 1215 if (pole[WKJ][WKI]!=fk||pole[BKJ][BKI]!=-fk) kingpositions(); 1216 if (nstep%2==1) check_on_table=get_check(fk); 1217 else check_on_table=get_check(-fk); // 1218 for (signed char i=0;i<8;i++) 1219 for (signed char j=0;j<8;j++) 1220 if (pole[j][i]>0&&nstep%2==1||pole[j][i]<0&&nstep%2==0) { 1221 switch (pole[j][i]) { 1222 case fp: // 1223 if (getpole(j-1,i)&&pole[j-1][i]==0) 1224 if (j!=1) addstep(j,i,j-1,i,0); else 1225 for (signed char t=4;t<8;t++) addstep(1,i,0,i,t); //-... 1226 if (j==6&&pole[j-1][i]==0&&pole[j-2][i]==0) addstep(j,i,j-2,i,0); 1227 if (getpole(j-1,i-1)&&pole[j-1][i-1]<0) 1228 if (j!=1) addstep(j,i,j-1,i-1,0); else 1229 for (signed char t=4;t<8;t++) addstep(j,i,j-1,i-1,t); //-... 1230 if (getpole(j-1,i+1)&&pole[j-1][i+1]<0) 1231 if (j!=1) addstep(j,i,j-1,i+1,0); else 1232 for (signed char t=4;t<8;t++) addstep(j,i,j-1,i+1,t); //-... 1233 if (j==3&&steps[nstep-1].fig1==-fp&&steps[nstep-1].x2==3&&steps[nstep-1].x1==1) { 1234 if (steps[nstep-1].y2-i==1) { // 1235 addstep(j,i,j-1,i+1,1); 1236 } else if (steps[nstep-1].y2-i==-1) { // 1237 addstep(j,i,j-1,i-1,1); 1238 } 1239 } 1240 break; 1241 case -fp: // 1242 if (getpole(j+1,i)&&pole[j+1][i]==0) 1243 if (j!=6) addstep(j,i,j+1,i,0); else 1244 for (signed char t=4;t<8;t++) addstep(j,i,j+1,i,t); //-... 1245 if (j==1&&pole[j+1][i]==0&&pole[j+2][i]==0) addstep(j,i,j+2,i,0); 1246 if (getpole(j+1,i-1)&&pole[j+1][i-1]>0) 1247 if (j!=6) addstep(j,i,j+1,i-1,0); else 1248 for (signed char t=4;t<8;t++) addstep(j,i,j+1,i-1,t); //-... 1249 if (getpole(j+1,i+1)&&pole[j+1][i+1]>0) 1250 if (j!=6) addstep(j,i,j+1,i+1,0); else 1251 for (signed char t=4;t<8;t++) addstep(j,i,j+1,i+1,t); //-... 1252 if (j==4&&steps[nstep-1].fig1==fp&&steps[nstep-1].x2==4&&steps[nstep-1].x1==6) { 1253 if (steps[nstep-1].y2-i==1) { // 1254 addstep(j,i,j+1,i+1,1); 1255 } else if (steps[nstep-1].y2-i==-1) { // 1256 addstep(j,i,j+1,i-1,1); 1257 } 1258 } 1259 break; 1260 case fn: // 1261 getonestepw(j,i,-2,-1); 1262 getonestepw(j,i,-2,1); 1263 getonestepw(j,i,-1,-2); 1264 getonestepw(j,i,-1,2); 1265 getonestepw(j,i,2,-1); 1266 getonestepw(j,i,2,1); 1267 getonestepw(j,i,1,-2); 1268 getonestepw(j,i,1,2); 1269 break; 1270 case -fn: // 1271 getonestepb(j,i,-2,-1); 1272 getonestepb(j,i,-2,1); 1273 getonestepb(j,i,-1,-2); 1274 getonestepb(j,i,-1,2); 1275 getonestepb(j,i,2,-1); 1276 getonestepb(j,i,2,1); 1277 getonestepb(j,i,1,-2); 1278 getonestepb(j,i,1,2); 1279 break; 1280 case fb: // 1281 getrowstepsw(j,i,1,1); 1282 getrowstepsw(j,i,-1,-1); 1283 getrowstepsw(j,i,1,-1); 1284 getrowstepsw(j,i,-1,1); 1285 break; 1286 case -fb: // 1287 getrowstepsb(j,i,1,1); 1288 getrowstepsb(j,i,-1,-1); 1289 getrowstepsb(j,i,1,-1); 1290 getrowstepsb(j,i,-1,1); 1291 break; 1292 case fr: // 1293 getrowstepsw(j,i,1,0); 1294 getrowstepsw(j,i,-1,0); 1295 getrowstepsw(j,i,0,1); 1296 getrowstepsw(j,i,0,-1); 1297 break; 1298 case -fr: // 1299 getrowstepsb(j,i,1,0); 1300 getrowstepsb(j,i,-1,0); 1301 getrowstepsb(j,i,0,1); 1302 getrowstepsb(j,i,0,-1); 1303 break; 1304 case fq: // 1305 getrowstepsw(j,i,1,1); 1306 getrowstepsw(j,i,-1,-1); 1307 getrowstepsw(j,i,1,-1); 1308 getrowstepsw(j,i,-1,1); 1309 getrowstepsw(j,i,1,0); 1310 getrowstepsw(j,i,-1,0); 1311 getrowstepsw(j,i,0,1); 1312 getrowstepsw(j,i,0,-1); 1313 break; 1314 case -fq: // 1315 getrowstepsb(j,i,1,1); 1316 getrowstepsb(j,i,-1,-1); 1317 getrowstepsb(j,i,1,-1); 1318 getrowstepsb(j,i,-1,1); 1319 getrowstepsb(j,i,1,0); 1320 getrowstepsb(j,i,-1,0); 1321 getrowstepsb(j,i,0,1); 1322 getrowstepsb(j,i,0,-1); 1323 break; 1324 case fk: // 1325 getonestepw(j,i, 1,-1); 1326 getonestepw(j,i, 1, 0); 1327 getonestepw(j,i, 1, 1); 1328 getonestepw(j,i, 0,-1); 1329 getonestepw(j,i, 0, 1); 1330 getonestepw(j,i,-1,-1); 1331 getonestepw(j,i,-1, 0); 1332 getonestepw(j,i,-1, 1); 1333 if (!check_on_table) add_rok(j,i,nstep); 1334 break; 1335 case -fk: // 1336 getonestepb(j,i, 1,-1); 1337 getonestepb(j,i, 1, 0); 1338 getonestepb(j,i, 1, 1); 1339 getonestepb(j,i, 0,-1); 1340 getonestepb(j,i, 0, 1); 1341 getonestepb(j,i,-1,-1); 1342 getonestepb(j,i,-1, 0); 1343 getonestepb(j,i,-1, 1); 1344 if (!check_on_table) add_rok(j,i,nstep); 1345 break; 1346 } //switch 1347 } //if 1348 1349 if (nstep>cur_step) { 1350 for (int i=start_var;i<start_var+cur_var;i++) { // 1351 for (signed char j=0;j<MAXCUTS;j++) 1352 if (cuts[j].fig1==steps[i].fig1&& 1353 cuts[j].x1==steps[i].x1&&cuts[j].y1==steps[i].y1&& 1354 cuts[j].x2==steps[i].x2&&cuts[j].y2==steps[i].y2) { 1355 steps[i].weight+=100+cuts[j].weight; 1356 break; 1357 } 1358 if (nstep>1&&steps[nstep-1].fig2!=0) // - 1359 if (steps[nstep-1].x2==steps[i].x2&&steps[nstep-1].y2==steps[i].y2) 1360 steps[i].weight+=1000; 1361 } 1362 } 1363 1364 sort_variants(start_var,start_var+cur_var-1); 1365 1366 } 1367//**************************** 1368void movestep(int nstep) { 1369 pole[steps[nstep].x1][steps[nstep].y1]=0; 1370 pole[steps[nstep].x2][steps[nstep].y2]=steps[nstep].fig1; 1371 if (steps[nstep].fig1==fk) { 1372 WKJ=steps[nstep].x2; WKI=steps[nstep].y2; 1373 } else if (steps[nstep].fig1==-fk) { 1374 BKJ=steps[nstep].x2; BKI=steps[nstep].y2; 1375 } 1376 if (steps[nstep].type==0) return; 1377 if (steps[nstep].type==1) // 1378 if (steps[nstep].fig1>0) 1379 pole[steps[nstep].x2+1][steps[nstep].y2]=0; 1380 else 1381 pole[steps[nstep].x2-1][steps[nstep].y2]=0; 1382 else if (steps[nstep].type==2) // 1383 if (steps[nstep].fig1>0) { // 1384 pole[7][4]=0; pole[7][5]=fr; pole[7][6]=fk; pole[7][7]=0; //show_board(); delay(3000); 1385 } else { // 1386 pole[0][4]=0; pole[0][5]=-fr; pole[0][6]=-fk; pole[0][7]=0; //show_board(); delay(3000); 1387 } 1388 else if (steps[nstep].type==3) // 1389 if (steps[nstep].fig1>0) { // 1390 pole[7][0]=0; pole[7][1]=0; pole[7][2]=fk; pole[7][3]=fr; pole[7][4]=0; 1391 } else { // 1392 pole[0][0]=0; pole[0][1]=0; pole[0][2]=-fk; pole[0][3]=-fr; pole[0][4]=0; 1393 } 1394 else if (steps[nstep].type>3) //-.... 1395 if (steps[nstep].fig1>0) pole[steps[nstep].x2][steps[nstep].y2]=steps[nstep].type-2; 1396 else pole[steps[nstep].x2][steps[nstep].y2]=2-steps[nstep].type; 1397} 1398//**************************** 1399void backstep(int nstep) { 1400 pole[steps[nstep].x1][steps[nstep].y1]=steps[nstep].fig1; 1401 pole[steps[nstep].x2][steps[nstep].y2]=steps[nstep].fig2; 1402 if (steps[nstep].fig1==fk) { 1403 WKJ=steps[nstep].x1; WKI=steps[nstep].y1; 1404 } else if (steps[nstep].fig1==-fk) { 1405 BKJ=steps[nstep].x1; BKI=steps[nstep].y1; 1406 } 1407 if (steps[nstep].type==0) return; 1408 if (steps[nstep].type==1) { // 1409 pole[steps[nstep].x2][steps[nstep].y2]=0; 1410 if (steps[nstep].fig1>0) 1411 pole[steps[nstep].x2+1][steps[nstep].y2]=-fp; 1412 else 1413 pole[steps[nstep].x2-1][steps[nstep].y2]=fp; 1414 } else if (steps[nstep].type==2) // 1415 if (steps[nstep].fig1>0) { // 1416 pole[7][4]=fk; pole[7][5]=0; pole[7][6]=0; pole[7][7]=fr; 1417 } else { // 1418 pole[0][4]=-fk; pole[0][5]=0; pole[0][6]=0; pole[0][7]=-fr; // show_board(); delay(3000); 1419 } 1420 else if (steps[nstep].type==3) // 1421 if (steps[nstep].fig1>0) { // 1422 pole[7][0]=fr; pole[7][1]=0; pole[7][2]=0; pole[7][3]=0; pole[7][4]=fk; 1423 } else { // 1424 pole[0][0]=-fr; pole[0][1]=0; pole[0][2]=0; pole[0][3]=0; pole[0][4]=-fk; 1425 } 1426 1427} 1428//**************************** 1429void get_wrocks(int nstep) { 1430 w00=true; w000=true; 1431 for (int i=1;i<nstep;i++) { 1432 if (steps[i].fig1==fk) { w00=false; w000=false; return; } 1433 if (steps[i].fig1==fr) 1434 if (steps[i].x1==7&&steps[i].y1==7) w00=false; 1435 else if (steps[i].x1==7&&steps[i].y1==0) w000=false; 1436 } 1437} 1438//**************************** 1439void get_brocks(int nstep) { 1440 b00=true; b000=true; 1441 for (int i=1;i<nstep;i++) { 1442 if (steps[i].fig1==-fk) { b00=false; b000=false; return; } 1443 if (steps[i].fig1==-fr) 1444 if (steps[i].x1==0&&steps[i].y1==7) b00=false; 1445 else if (steps[i].x1==0&&steps[i].y1==0) b000=false; 1446 } 1447} 1448//**************************** 1449void add_rok(signed char j,signed char i,int nstep) { // 1450boolean che1,che2; 1451 if (nstep%2==1) { // 1452 if (j!=7||i!=4) return; 1453 if (pole[7][5]==0&&pole[7][6]==0&&pole[7][7]==fr) { // 1454 pole[7][4]=0; 1455 WKI=5; che1=get_check(fk); 1456 WKI=6; che2=get_check(fk); 1457 WKI=4; pole[7][4]=fk; 1458 get_wrocks(nstep); 1459 if (!che1&&!che2&&w00) addstep(7,4,7,6,2); 1460 } 1461 if (pole[7][0]==fr&&pole[7][1]==0&&pole[7][2]==0&&pole[7][3]==0) { // 1462 pole[7][4]=0; 1463 WKI=2; che1=get_check(fk); 1464 WKI=3; che2=get_check(fk); 1465 WKI=4; pole[7][4]=fk; 1466 get_wrocks(nstep); 1467 if (!che1&&!che2&&w000) addstep(7,4,7,2,3); 1468 } 1469 } else { // 1470 if (j!=0||i!=4) return; 1471 if (pole[0][5]==0&&pole[0][6]==0&&pole[0][7]==-fr) { // 1472 pole[0][4]=0; 1473 BKI=5; che1=get_check(-fk); 1474 BKI=6; che2=get_check(-fk); 1475 BKI=4; pole[0][4]=-fk; 1476 get_brocks(nstep); 1477 if (!che1&&!che2&&b00) addstep(0,4,0,6,2); 1478 } 1479 if (pole[0][0]==-fr&&pole[0][1]==0&&pole[0][2]==0&&pole[0][3]==0) { // 1480 pole[0][4]=0; 1481 BKI=2; che1=get_check(-fk); 1482 BKI=3; che2=get_check(-fk); 1483 BKI=4; pole[0][4]=-fk; 1484 get_brocks(nstep); 1485 if (!che1&&!che2&&b000) addstep(0,4,0,2,3); 1486 } 1487 1488 } 1489} 1490//**************************** 1491int addrowstepsw(signed char j,signed char i,signed char dj,signed char di,signed char dc) { // 1492signed char d,j1,i1; int c=0; 1493 j1=j; i1=i; 1494 for (d=1;d<8;d++) { 1495 j1+=dj; i1+=di; 1496 if (getpole(j1,i1)) { 1497 if (pole[j1][i1]==0) c+=dc; 1498 else if (pole[j1][i1]>0) { // 1499 c+=1; break; 1500 } else { 1501 if (cur_step>6) c+=-pole[j1][i1]; // 1502 break; 1503 } 1504 } else break; 1505 } 1506 return c; 1507} 1508//**************************** 1509int addrowstepsb(signed char j,signed char i,signed char dj,signed char di,signed char dc) { // 1510signed char d,j1,i1; int c=0; 1511 j1=j; i1=i; 1512 for (d=1;d<8;d++) { 1513 j1+=dj; i1+=di; 1514 if (getpole(j1,i1)) { 1515 if (pole[j1][i1]==0) c-=dc; 1516 else if (pole[j1][i1]<0) { // 1517 c-=1; break; 1518 } else { 1519 if (cur_step>6) c-=pole[j1][i1]; // 1520 break; 1521 } 1522 } else break; 1523 } 1524 return c; 1525} 1526//**************************** 1527int addonestepw(signed char j,signed char i,signed char dj,signed char di) { // 1528signed char j1,i1; 1529 j1=j+dj; i1=i+di; 1530 if (getpole(j1,i1)) 1531 if (pole[j1][i1]==0) return 2; 1532 else if (pole[j1][i1]>0) return 1; 1533 else return -pole[j1][i1]; 1534 return 0; 1535} 1536//**************************** 1537int addonestepb(signed char j,signed char i,signed char dj,signed char di) { // 1538signed char j1,i1; 1539 j1=j+dj; i1=i+di; 1540 if (getpole(j1,i1)) 1541 if (pole[j1][i1]==0) return -2; 1542 else if (pole[j1][i1]<0) return -1; 1543 else return -pole[j1][i1]; 1544 return 0; 1545} 1546//**************************** 1547int activity() { // - + 1548int c=0; 1549signed char pwj[8],pwi[8],pbj[8],pbi[8],ipw=0,ipb=0,nbw=0,nbb=0; 1550 for (signed char i=0;i<8;i++) 1551 for (signed char j=0;j<8;j++) 1552 if (pole[j][i]!=0) { 1553 switch (pole[j][i]) { 1554 case fp: // 1555 if (getpole(j,i+1)&&pole[j][i+1]==fp) c+=2; // 1556 if (getpole(j-1,i)&&pole[j-1][i]==fp) c-=20; // 1557 pwj[ipw]=j; pwi[ipw]=i; ipw++; 1558 break; 1559 case -fp: // 1560 if (getpole(j,i-1)&&pole[j][i-1]==-fp) c-=2; // 1561 if (getpole(j+1,i)&&pole[j+1][i]==-fp) c+=20; // 1562 pbj[ipb]=j; pbi[ipb]=i; ipb++; 1563 break; 1564 case fn: // 1565 c+=addonestepw(j,i,-2,-1); 1566 c+=addonestepw(j,i,-2,1); 1567 c+=addonestepw(j,i,-1,-2); 1568 c+=addonestepw(j,i,-1,2); 1569 c+=addonestepw(j,i,2,-1); 1570 c+=addonestepw(j,i,2,1); 1571 c+=addonestepw(j,i,1,-2); 1572 c+=addonestepw(j,i,1,2); 1573 break; 1574 case -fn: // 1575 c+=addonestepb(j,i,-2,-1); 1576 c+=addonestepb(j,i,-2,1); 1577 c+=addonestepb(j,i,-1,-2); 1578 c+=addonestepb(j,i,-1,2); 1579 c+=addonestepb(j,i,2,-1); 1580 c+=addonestepb(j,i,2,1); 1581 c+=addonestepb(j,i,1,-2); 1582 c+=addonestepb(j,i,1,2); 1583 break; 1584 case fb: // 1585 c+=addrowstepsw(j,i,1,1,2); //!! 1.4 1586 c+=addrowstepsw(j,i,-1,-1,3);//!! 1587 c+=addrowstepsw(j,i,1,-1,2); //!! 1588 c+=addrowstepsw(j,i,-1,1,3); //!! 1589 nbw++; 1590 break; 1591 case -fb: // 1592 c+=addrowstepsb(j,i,1,1,3); //!! 1.4 1593 c+=addrowstepsb(j,i,-1,-1,2);//!! 1594 c+=addrowstepsb(j,i,1,-1,3); //!! 1595 c+=addrowstepsb(j,i,-1,1,2); //!! 1596 nbb++; 1597 break; 1598 case fr: // 1599 c+=addrowstepsw(j,i,1,0,2); // 1600 c+=addrowstepsw(j,i,-1,0,2); 1601 c+=addrowstepsw(j,i,0,1,1); 1602 c+=addrowstepsw(j,i,0,-1,1); 1603 break; 1604 case -fr: // 1605 c+=addrowstepsb(j,i,1,0,2); // 1606 c+=addrowstepsb(j,i,-1,0,2); 1607 c+=addrowstepsb(j,i,0,1,1); 1608 c+=addrowstepsb(j,i,0,-1,1); 1609 break; 1610 case fq: // 1611 if (cur_step>10) { 1612 c+=addrowstepsw(j,i,1,1,1); 1613 c+=addrowstepsw(j,i,-1,-1,2); 1614 c+=addrowstepsw(j,i,1,-1,1); 1615 c+=addrowstepsw(j,i,-1,1,2); 1616 c+=addrowstepsw(j,i,1,0,1); 1617 c+=addrowstepsw(j,i,-1,0,2); 1618 c+=addrowstepsw(j,i,0,1,1); 1619 c+=addrowstepsw(j,i,0,-1,1); 1620 } 1621 break; 1622 case -fq: // 1623 if (cur_step>10) { 1624 c+=addrowstepsb(j,i,1,1,2); 1625 c+=addrowstepsb(j,i,-1,-1,1); 1626 c+=addrowstepsb(j,i,1,-1,2); 1627 c+=addrowstepsb(j,i,-1,1,1); 1628 c+=addrowstepsb(j,i,1,0,2); 1629 c+=addrowstepsb(j,i,-1,0,1); 1630 c+=addrowstepsb(j,i,0,1,1); 1631 c+=addrowstepsb(j,i,0,-1,1); 1632 } 1633 break; 1634 } //switch 1635 if (cur_step>6) { 1636 if (pole[j][i]>0) { // 1637 if (abs(WKJ-j)<2&&abs(WKI-i)<2) c+=3; 1638 if (abs(BKJ-j)<2&&abs(BKI-i)<2) c+=3; 1639 if (abs(WKJ-j)<3&&abs(WKI-i)<3) c+=2; 1640 if (abs(BKJ-j)<3&&abs(BKI-i)<3) c+=2; 1641 } else { // 1642 if (abs(WKJ-j)<2&&abs(WKI-i)<2) c-=3; 1643 if (abs(BKJ-j)<2&&abs(BKI-i)<2) c-=3; 1644 if (abs(WKJ-j)<3&&abs(WKI-i)<3) c-=2; 1645 if (abs(BKJ-j)<3&&abs(BKI-i)<3) c-=2; 1646 } 1647 } 1648 } 1649 if (nbw>1) c+=30; // 1650 if (nbb>1) c-=30; 1651 for (signed char w=0;w<ipw;w++) { // 1652 boolean pass=1; 1653 for (signed char b=0;b<ipb;b++) { 1654 if (pwi[w]>0&&pbi[b]==pwi[w]-1&&pbj[b]<pwj[w]) pass=0; // 1655 if (pbi[b]==pwi[w]&&pbj[b]<pwj[w]) pass=0; // 1656 if ( pwi[w]<7&&pbi[b]==pwi[w]+1&&pbj[b]<pwj[w]) pass=0; // 1657 if (!pass) break; 1658 } 1659 if (pass) { 1660 c+=50; 1661 if (!endspiel) break; // 1662 } 1663 } 1664 for (signed char b=0;b<ipb;b++) { // 1665 boolean pass=1; 1666 for (signed char w=0;w<ipw;w++) { 1667 if (pbi[b]>0&&pwi[w]==pbi[b]-1&&pwj[w]>pbj[b]) pass=0; // 1668 if (pwi[w]==pbi[b]&&pwj[w]>pbj[b]) pass=0; // 1669 if (pbi[b]<7&&pwi[w]==pbi[b]+1&&pwj[w]>pbj[b]) pass=0; // 1670 if (!pass) break; 1671 } 1672 if (pass) { 1673 c-=50; 1674 if (!endspiel) break; // 1675 } 1676 } 1677 return c; 1678} 1679//**************************** 1680int evaluate(int nstep) { // 1681 long ww=0, wb=0; 1682 for (signed char i=0;i<8;i++) 1683 for (signed char j=0;j<8;j++) 1684 if (pole[j][i]<0) { 1685 wb+=fig_weight[-pole[j][i]]+(short)pgm_read_word(&pos[-pole[j][i]-1][7-j][i]); 1686 } 1687 else if (pole[j][i]>0) { 1688 ww+=fig_weight[pole[j][i]]+(short)pgm_read_word(&pos[pole[j][i]-1][j][i]); 1689 } 1690 count++; // 1691 long str=activity(); 1692 if (endspiel) { // 1693 wb+=(short)pgm_read_word(&pos[6][7-BKJ][BKI])-(short)pgm_read_word(&pos[5][7-BKJ][BKI]); 1694 ww+=(short)pgm_read_word(&pos[6][WKJ][WKI])-(short)pgm_read_word(&pos[5][WKJ][WKI]); 1695 if (wb<450&&ww>450) { // - - 1696 str-=(abs(WKJ-BKJ)+abs(WKI-BKI))*30; 1697 } else if (ww<450&&wb>450) { // 1698 str+=(abs(WKJ-BKJ)+abs(WKI-BKI))*30; 1699 } 1700 } 1701 if (nstep>8) { // 1702 if (steps[nstep-1].fig1==steps[nstep-5].fig1&&steps[nstep-2].fig1==steps[nstep-6].fig1&& 1703 steps[nstep-3].fig1==steps[nstep-7].fig1&&steps[nstep-4].fig1==steps[nstep-8].fig1) 1704 if (steps[nstep-1].x1==steps[nstep-5].x1&&steps[nstep-2].x1==steps[nstep-6].x1&& 1705 steps[nstep-3].x1==steps[nstep-7].x1&&steps[nstep-4].x1==steps[nstep-8].x1) 1706 if (steps[nstep-1].x2==steps[nstep-5].x2&&steps[nstep-2].x2==steps[nstep-6].x2&& 1707 steps[nstep-3].x2==steps[nstep-7].x2&&steps[nstep-4].x2==steps[nstep-8].x2) 1708 if (steps[nstep-1].y1==steps[nstep-5].y1&&steps[nstep-2].y1==steps[nstep-6].y1&& 1709 steps[nstep-3].y1==steps[nstep-7].y1&&steps[nstep-4].y1==steps[nstep-8].x1) 1710 if (steps[nstep-1].y2==steps[nstep-5].y2&&steps[nstep-2].y2==steps[nstep-6].y2&& 1711 steps[nstep-3].y2==steps[nstep-7].y2&&steps[nstep-4].y2==steps[nstep-8].y2) 1712 { 1713 //Serial.println(F(" Draw - 3 repeat")); 1714 return 0; 1715 } 1716 } 1717 if (nstep%2==1) return 5000*(ww-wb)/(ww+wb+2000)+str; else return 5000*(wb-ww)/(ww+wb+2000)-str; 1718} 1719//**************************** 1720void add_cut(int ind) {// ind 1721 int minbeta=30000, minindex=MAXCUTS-1; 1722 for (signed char i=0;i<MAXCUTS;i++) { 1723 if (cuts[i].weight==0) { minindex=i; break; }// 1724 if (cuts[i].fig1==steps[ind].fig1&& 1725 cuts[i].x1==steps[ind].x1&&cuts[i].y1==steps[ind].y1&& 1726 cuts[i].x2==steps[ind].x2&&cuts[i].y2==steps[ind].y2) { 1727 cuts[i].weight++; return; // - 1 1728 } 1729 if (cuts[i].weight<minbeta) { // 1730 minbeta=cuts[i].weight; 1731 minindex=i; 1732 } 1733 } 1734 cuts[minindex]=steps[ind]; 1735 cuts[minindex].weight=1; //1 1736} 1737//**************************** 1738int quiescence(int start, int nstep, int alpha, int beta ) { 1739 if (nstep-cur_step>=LIMDEPTH||start>MAXSTEPS-100) return evaluate(nstep); 1740 if (!solving&&progress==0) return -5000; 1741 int score=-20000; 1742 start_var=start; 1743 only_action=true; 1744 load_variants(nstep); 1745 if (!check_on_table) { 1746 int stand_pat = evaluate(nstep); 1747 if (stand_pat >= score) score=stand_pat; 1748 if (score>alpha) alpha=score; 1749 if (alpha>=beta&&isbeta) return alpha; 1750 } 1751 if (cur_var==0) { 1752 if (check_on_table) { 1753 if (TRACE) Serial.println(F("checkmate?")); 1754 return -10000+nstep-cur_step; 1755 } else return evaluate(nstep); 1756 } 1757 int j=start+cur_var; 1758 for (int i=start;i<j;i++) { // 1759 if (TRACE) { //***** 1760 for (int u=0;u<nstep-cur_step;u++) Serial.print(F(" . ")); 1761 Serial.println(str_step(i)); 1762 } 1763 movestep(i); 1764 steps[nstep]=steps[i]; 1765 int tmp=-quiescence(j+1,nstep+1,-beta,-alpha); 1766 backstep(i); 1767 if (tmp>score) score=tmp; 1768 if (score>alpha) alpha=score; 1769 if (alpha>=beta&&isbeta) { 1770 add_cut(nstep); 1771 return alpha; 1772 } 1773 gui(); 1774 } 1775 return score; 1776} 1777//**************************** 1778int alphaBeta(int start, int nstep, int alpha, int beta, int depthleft) { 1779//start - 1780//nstep - 1781int score=-20000,best; 1782 if( depthleft==0) return quiescence(start,nstep,alpha,beta) ; 1783 if (start>MAXSTEPS-100) return evaluate(nstep); 1784 start_var=start; 1785 only_action=false; 1786 if (nstep!=cur_step) load_variants(nstep); 1787 if (cur_var==0) { 1788 if (check_on_table) { 1789 if (TRACE) Serial.println(F("checkmate!")); 1790 return -10000+nstep-cur_step; 1791 } 1792 return 0; 1793 } 1794 int j=start+cur_var; 1795 best=start; 1796 for (int i=start;i<j;i++) { // 1797 if (nstep==cur_step) { 1798 if (!hidden) { 1799 Serial.print(str_step(i)); Serial.print(" "); 1800 Serial.print(i-start+1); Serial.print("/"); Serial.print(j-start); 1801 } 1802 if (steps[i].weight<-9000) { Serial.println(F(" checkmate")); continue; } 1803 if (steps[i].fig2!=0||steps[i].check||(alpha<-100&&isbeta)) 1804 // , , -100 1805 { LIMDEPTH=MAXDEPTH+2; if (!hidden) Serial.print(F("+2")); } else LIMDEPTH=MAXDEPTH; 1806 } else { 1807 if (TRACE) { //***** 1808 for (int u=0;u<nstep-cur_step;u++) Serial.print(F(" ")); 1809 Serial.println(str_step(i)); 1810 } 1811 } 1812 movestep(i); 1813 steps[nstep]=steps[i]; 1814 int tmp=-alphaBeta(j+1,nstep+1,-beta,-alpha,depthleft-1); 1815 backstep(i); 1816 steps[i].weight=tmp; 1817 if (tmp>score) score=tmp; 1818 if (score>alpha) { 1819 alpha=score; 1820 if (nstep>cur_step) add_cut(nstep); // 1821 if (TRACE) { Serial.print(F("ALPHA+:")); Serial.println(score); } 1822 best=i; 1823 if (nstep==cur_step) { 1824 steps[0]=steps[best]; 1825 if (!hidden) Serial.print(F(" BEST")); 1826 } 1827 } 1828 if (alpha>=beta&&isbeta) { 1829 if (nstep>cur_step) add_cut(nstep); // 1830 if (TRACE) { Serial.print(F("BETA CUT:")); Serial.println(score); } 1831 return alpha; 1832 } 1833 if (nstep==cur_step) { 1834 if (!hidden) { Serial.print(F(" ")); Serial.println(tmp); } 1835 progress=100*(i-start+1)/(j-start); 1836 if (alpha==9999||alpha==-5000) break; 1837 if (!solving) { 1838 if (alpha>startweight&&cur_level>2) break; 1839 else { // - +50% 1840 if (cur_level>1&&100*(millis()-starttime)/(limittime-starttime)>240-limit*20) break; 1841 } 1842 } 1843 } 1844 if (nstep==cur_step+1&&!solving&&progress==0) break; 1845 gui(); 1846 } 1847 if (nstep==cur_step) { steps[nstep]=steps[best]; steps[0]=steps[best]; } 1848 return score; 1849} 1850//**************************** 1851void kingpositions() { 1852 for (signed char i=0;i<8;i++) // 1853 for (signed char j=0;j<8;j++) 1854 if (pole[j][i]==fk) { 1855 WKJ=j; WKI=i; 1856 } else if (pole[j][i]==-fk) { 1857 BKJ=j; BKI=i; 1858 } 1859} 1860//**************************** 1861int get_endspiel() { // 1862 int weight=0; 1863 for (signed char i=0;i<8;i++) 1864 for (signed char j=0;j<8;j++) 1865 if (pole[j][i]<0) 1866 weight+=fig_weight[-pole[j][i]]; 1867 else if (pole[j][i]>0) 1868 weight+=fig_weight[pole[j][i]]; // 8000 1869 if (weight<3500) endspiel=true; else endspiel=false; 1870 return weight; 1871} 1872//**************************** 1873boolean is_drawn() { // 1874 boolean drawn=false; 1875 int cn=0,cbw=0,cbb=0,co=0,cb=0,cw=0; 1876 for (signed char i=0;i<8;i++) 1877 for (signed char j=0;j<8;j++) { 1878 if (abs(pole[j][i])==1) co++; 1879 if (abs(pole[j][i])>3&&abs(pole[j][i])<6) co++; // , , 1880 if (abs(pole[j][i])==6) continue; // 1881 if (abs(pole[j][i])==2) cn++; // 1882 if (abs(pole[j][i])==3&&(i+j+2)%2==0) cbb++; // 1883 if (abs(pole[j][i])==3&&(i+j+2)%2==1) cbw++; // 1884 if (pole[j][i]==3) cw++; // 1885 if (pole[j][i]==-3) cb++; // 1886 } 1887 if (cn==1&&co+cbb+cbw==0) drawn=true; // 1888 if (cbb+cbw==1&&co+cn==0) drawn=true; // 1889 if (co+cn+cbb==0||co+cn+cbw==0) drawn=true; // 1890 if (co+cn==0&&cb==1&&cw==1) drawn=true; // 1891 if (drawn) return drawn; 1892 int rep=1; 1893 for (int s=cur_step-1; s>0; s--) { 1894 if (steps[s].fig1==0) continue; 1895 backstep(s); 1896 boolean eq=true; 1897 for (signed char i=0;i<8;i++) 1898 for (signed char j=0;j<8;j++) 1899 if (pole[j][i]!=pole0[j][i]) 1900 { eq=false; break; } 1901 if (eq) rep++; 1902 if (rep>2) break; 1903 } 1904 if (rep>1) { Serial.print(rep); Serial.println(" repetitions"); } 1905 for (signed char i=0;i<8;i++) 1906 for (signed char j=0;j<8;j++) pole[j][i]=pole0[j][i]; // 1907 if (rep>2) drawn=true; 1908 return drawn; 1909} 1910//**************************** 1911int solve_step() { 1912const int LMIN[6]={2,3,4,5,6,7}; 1913const int LMAX[6]={4,6,8,10,12,14}; 1914boolean check_on; 1915 if (!hidden) { 1916 M5.Lcd.fillRect(240,166,80,20,CBLACK); 1917 M5.Lcd.drawFastHLine(10,237,220,CDARK); 1918 } 1919 starttime=millis(); 1920 isstatus=1; 1921 limittime=starttime+limits[limit]*1000; // 1922 for (signed char i=0;i<8;i++) 1923 for (signed char j=0;j<8;j++) pole0[j][i]=pole[j][i]; // 1924 1925 isbeta=true; 1926 if (hidden) isbeta=false; 1927 else if (cur_step<5) { // FEN 1928 isbeta=false; 1929 for (int i=cur_step-1;i>0;i--) 1930 if (steps[i].fig1!=0) backstep(i); 1931 for (signed char i=0;i<8;i++) 1932 for (signed char j=0;j<8;j++) 1933 if (polestart[j][i]!=pole[j][i]) { isbeta=true; break; } 1934 for (signed char i=0;i<8;i++) 1935 for (signed char j=0;j<8;j++) pole[j][i]=pole0[j][i]; // 1936 } 1937 Serial.print("isbeta="); Serial.println(isbeta); 1938 1939 lastbest.fig1=0; 1940 kingpositions(); 1941 int wei=get_endspiel(); 1942 1943 count=0; 1944 startweight=evaluate(cur_step); 1945 if (!hidden) { 1946 Serial.println(""); 1947 Serial.println(F("---------------")); 1948 if (endspiel) { Serial.print(F("Endspiel: ")); Serial.println(wei); } 1949 if (cur_step%2==1) Serial.print(F("WHITE, ")); else Serial.print(F("BLACK, ")); 1950 Serial.print(F("start Score= ")); Serial.println(startweight); 1951 } 1952 start_var=cur_step+21; 1953 only_action=false; 1954 lastbest.fig1=0; 1955 steps[0].fig1=0; 1956 load_variants(cur_step); 1957 check_on=check_on_table; 1958 if (cur_var==0||is_drawn()) { 1959 beep(500); 1960 M5.Lcd.drawFastHLine(10,237,220,CBLACK); 1961 M5.Lcd.drawFastHLine(10,239,220,CBLACK); 1962 isstatus=0; 1963 solving=false; 1964 if (check_on_table) return -9999; else return 8999; 1965 } 1966 if (cur_var==1) { // 1 1967 M5.Lcd.drawFastHLine(10,237,220,CBLACK); 1968 M5.Lcd.drawFastHLine(10,239,220,CBLACK); 1969 isstatus=0; 1970 solving=false; 1971 steps[cur_step]=steps[cur_step+21]; 1972 return startweight; 1973 } 1974 int vars=cur_var; 1975 int ALPHA=-20000; 1976 int BETA=20000; 1977 int score; 1978 solving=true; 1979 int l=0; 1980 for (signed char i=0;i<MAXCUTS;i++) { cuts[i].weight=0; cuts[i].fig1=0; } // 1981 for (int i=cur_step+21;i<cur_step+21+vars;i++) { // 1982 movestep(i); 1983 steps[i].weight=evaluate(cur_step); 1984 if (steps[i].fig2!=0) steps[i].weight-=steps[i].fig1; 1985 backstep(i); 1986 } 1987 while (l<6) { 1988 cur_level=l+1; 1989 progress=0; 1990 M5.Lcd.drawFastHLine(10,239,220,CDARK); 1991 MINDEPTH=LMIN[l]; 1992 MAXDEPTH=LMAX[l]; 1993 if (!hidden) { 1994 if (l>0) Serial.println(""); Serial.print(F("******* LEVEL=")); Serial.print(l+1); 1995 Serial.print(" "); Serial.print(MINDEPTH); Serial.print("-"); Serial.print(MAXDEPTH); 1996 Serial.print(" "); Serial.print((millis()-starttime)/1000.,1); Serial.println("s"); 1997 } 1998 sort_variants(cur_step+21,cur_step+20+vars); // 1999 cur_var=vars; 2000 check_on_table=check_on; 2001 for (int i=cur_step+21;i<cur_step+21+vars;i++) steps[i].weight=-8000; //// 2002 score=alphaBeta(cur_step+21,cur_step,ALPHA,BETA,MINDEPTH); 2003 if (score>9996) break; 2004 if (score>9000&&limit<2) break; 2005 if (100*(millis()-starttime)/(limittime-starttime)>75-l*8) break; 2006 if (!solving||!isbeta||hidden) break; 2007 //if (hidden||cur_step<5) break; 2008 l++; 2009 } //while l 2010 if (score<-9000) { 2011 if (!hidden) Serial.println(F("GIVE UP!")); 2012 } else { 2013 int ran=random(5,10); //// 2014 while (ran>0&&cur_step<5&&!isbeta) { 2015 for (int i=cur_step+21;i<cur_step+21+vars;i++) 2016 if (steps[i].weight>=score-10) { 2017 ran--; 2018 if (ran==0) { 2019 if (millis()%2==1) 2020 if (steps[cur_step].x1!=steps[i].x1||steps[cur_step].x2!=steps[i].x2|| 2021 steps[cur_step].y1!=steps[i].y1||steps[cur_step].y2!=steps[i].y2) { 2022 steps[cur_step]=steps[i]; 2023 if (!hidden) Serial.println(F("Best step replaced!")); 2024 break; 2025 } 2026 } 2027 } 2028 } //// 2029 if (!hidden) { Serial.print(F("STEP=")); Serial.println(str_step(cur_step)); } 2030 if (score>9000) { 2031 if (!hidden) Serial.print(F("CHECKMATE ")); 2032 if (score<9999) { 2033 if (!hidden) {Serial.print(F("in ")); Serial.print((9999-score)/2+1); Serial.print(F(" steps")); } 2034 } else steps[cur_step].check=2; 2035 if (!hidden) Serial.println(""); 2036 } 2037 } 2038 M5.Lcd.drawFastHLine(10,237,220,CBLACK); 2039 M5.Lcd.drawFastHLine(10,239,220,CBLACK); 2040 progress=0; 2041 solving=0; 2042 isstatus=0; 2043 endtime=millis(); 2044 return score; 2045 2046 2047} 2048//**************************** 2049
Downloadable files
No schematic at all, just download a sketch in Code section.
No schematic at all, just download a sketch in Code section.

Comments
Only logged in users can leave comments