-
-
Save devatnull/39f3b36513943d0eb39c6f382f189e01 to your computer and use it in GitHub Desktop.
FIXED Megachess M5stack adapted to ODROID GO
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//ArduinoMega Chess 1.0 M5Stack | |
//engine 1.4 | |
//Sergey Urusov, [email protected] | |
// | |
// Adapted to ODROID GO | |
#include <odroid_go.h> | |
#include <Preferences.h> | |
Preferences prefs; | |
uint16_t CBLACK,CBLUE,CRED,CGREEN,CCYAN,CMAGENTA,CYELLOW,CWHITE,CGRAY,CDARK,CGRAY2,CBLACKF,CWHITEF,CWHITEFIG,CBLACKFIG,CBLACKCONT; | |
int cycle=0; // | |
const signed char fp=1; | |
const signed char fn=2; | |
const signed char fb=3; | |
const signed char fr=4; | |
const signed char fq=5; | |
const signed char fk=6; | |
const int fig_weight[]={0,100,320,330,500,900,0}; | |
const char fig_symb[]=" NBRQK"; | |
unsigned long count; | |
boolean rotate=false; | |
const signed char polezero[8][8] PROGMEM={ | |
{ 0, 0, 0, 0, 0, 0, 0, 0}, | |
{ 0, 0, 0, 0, 0, 0, 0, 0}, | |
{ 0, 0, 0, 0, 0, 0, 0, 0}, | |
{ 0, 0, 0, 0, 0, 0, 0, 0}, | |
{ 0, 0, 0, 0, 0, 0, 0, 0}, | |
{ 0, 0, 0, 0, 0, 0, 0, 0}, | |
{ 0, 0, 0, 0, 0, 0, 0, 0}, | |
{ 0, 0, 0, 0, 0, 0, 0, 0}, | |
}; | |
const signed char polestart[8][8] PROGMEM={ | |
{-fr,-fn,-fb,-fq,-fk,-fb,-fn,-fr}, | |
{-fp,-fp,-fp,-fp,-fp,-fp,-fp,-fp}, | |
{ 0, 0, 0, 0, 0, 0, 0, 0}, | |
{ 0, 0, 0, 0, 0, 0, 0, 0}, | |
{ 0, 0, 0, 0, 0, 0, 0, 0}, | |
{ 0, 0, 0, 0, 0, 0, 0, 0}, | |
{ fp, fp, fp, fp, fp, fp, fp, fp}, | |
{ fr, fn, fb, fq, fk, fb, fn, fr}, | |
}; | |
signed char pole[8][8]={ // 3 | |
{-fr,-fn,-fb,-fq,-fk,-fb,-fn,-fr}, | |
{-fp,-fp,-fp,-fp,-fp,-fp,-fp,-fp}, | |
{ 0, 0, 0, 0, 0, 0, 0, 0}, | |
{ 0, 0, 0, 0, 0, 0, 0, 0}, | |
{ 0, 0, 0, 0, 0, 0, 0, 0}, | |
{ 0, 0, 0, 0, 0, 0, 0, 0}, | |
{ fp, fp, fp, fp, fp, fp, fp, fp}, | |
{ fr, fn, fb, fq, fk, fb, fn, fr}, | |
}; | |
signed char pole0[8][8]; // | |
signed char poledisp[8][8]; // | |
signed char polechoice[7]; // | |
boolean w00,w000,b00,b000; | |
signed char blinkstep; | |
typedef struct { | |
signed char fig1, fig2; // | |
signed char x1,y1,x2,y2; // | |
signed char check; // | |
signed char type; // 1- ,2- ,3- ,4-5-6-7- ,,, | |
int weight; // , | |
} step_type; | |
const int MAXSTEPS=1000; //. | |
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
int MINDEPTH; //. | |
int MAXDEPTH; //. | |
int LIMDEPTH; //. | |
const signed char MAXCUTS=10; //.. - - (10- , 20) | |
boolean TRACE=0; | |
boolean solving=false; | |
boolean choice=false; | |
boolean sound=1; | |
short cur_step=1; // , 1.... | |
short limit=0; // , 0-2; | |
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
const long limits[3]={4,15,60}; | |
// 0 1 2 | |
step_type steps[MAXSTEPS]; // | |
step_type cuts[MAXCUTS]; // - | |
step_type lastbest,lastanimatedgreen; | |
int lastscore; | |
int minbeta,maxalpha; | |
int startweight; | |
int cur_level; // () | |
int start_var; // , 1.... | |
int cur_var; // , 1.... | |
int current_var; // , 1.... | |
int cur_choice; // | |
boolean check_on_table; // | |
boolean isstatus; | |
signed char WKJ=0,WKI=0,BKJ=0,BKI=0; // | |
boolean endspiel=false; // | |
signed char progress; // 0-100 | |
boolean only_action=false; // - | |
unsigned long starttime,endtime,limittime,quitime=0; | |
int menu=0; // | |
unsigned long lastpressed,lastpressedleft,lastpressedright,lastpressedany; | |
boolean submenu=0; | |
boolean movesload=0; | |
boolean isbeta=1; | |
boolean hidden=false; | |
const uint8_t fig[6][72] PROGMEM={ | |
{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7E, 0x0, 0x0, 0xFF, 0x0, | |
0x0, 0xFF, 0x0, 0x0, 0xFF, 0x0, 0x0, 0x7E, 0x0, 0x0, 0x3C, 0x0, 0x1, 0xFF, 0x80, 0x1, 0xFF, 0x80, | |
0x0, 0x3C, 0x0, 0x0, 0x3C, 0x0, 0x0, 0x7E, 0x0, 0x0, 0x7E, 0x0, 0x0, 0xFF, 0x0, 0x1, 0xFF, 0x80, | |
0x3, 0xFF, 0xC0, 0x7, 0xFF, 0xE0, 0x7, 0xFF, 0xE0, 0x7, 0xFF, 0xE0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 | |
}, // | |
{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0x0, 0x0, 0xFF, 0x0, 0x1, 0xFF, 0x80, 0x3, 0xFF, 0xC0, | |
0x7, 0xFF, 0xE0, 0xF, 0xFF, 0xF0, 0x1F, 0xFF, 0xF8, 0x1F, 0x3F, 0xF8, 0x1E, 0x3F, 0xF8, 0xC, 0x7F, 0xF8, | |
0x0, 0xFF, 0xF0, 0x1, 0xFF, 0xE0, 0x1, 0xFF, 0xC0, 0x1, 0xFF, 0x80, 0x1, 0xFF, 0x0, 0x0, 0xFE, 0x0, | |
0x0, 0x7E, 0x0, 0x7, 0xFF, 0xE0, 0xF, 0xFF, 0xF0, 0xF, 0xFF, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 | |
}, // | |
{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3C, 0x0, 0x0, 0x7E, 0x0, 0x0, 0x7E, 0x0, 0x0, 0x3C, 0x0, | |
0x1, 0xFF, 0x80, 0x3, 0xFF, 0xC0, 0x7, 0xFF, 0xE0, 0x7, 0xFF, 0xE0, 0x7, 0xFF, 0xE0, 0x7, 0xFF, 0xE0, | |
0x7, 0xFF, 0xE0, 0x7, 0xFF, 0xE0, 0x7, 0xFF, 0xE0, 0x3, 0xFF, 0xC0, 0x1, 0xFF, 0x80, 0x0, 0xFF, 0x0, | |
0x8, 0x7E, 0x10, 0x1C, 0x7E, 0x38, 0x3F, 0xFF, 0xFC, 0x3F, 0xFF, 0xFC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 | |
}, // | |
{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xF, 0x3C, 0xF0, 0xF, 0x3C, 0xF0, 0xF, 0xFF, 0xF0, 0xF, 0xFF, 0xF0, | |
0x7, 0xFF, 0xE0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, | |
0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, 0x3, 0xFF, 0xC0, | |
0x3, 0xFF, 0xC0, 0x7, 0xFF, 0xE0, 0xF, 0xFF, 0xF0, 0xF, 0xFF, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 | |
}, // | |
{0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x3, 0x3C, 0xC0, 0x7, 0x99, 0xE0, 0x33, 0x18, 0xCC, 0x7B, 0x18, 0xDE, | |
0x33, 0x18, 0xCC, 0x33, 0x18, 0xCC, 0x33, 0x18, 0xCC, 0x33, 0x18, 0xCC, 0x33, 0x18, 0xCC, 0x33, 0xBD, 0xCC, | |
0x1B, 0xBD, 0xD8, 0x1F, 0xFF, 0xF8, 0x1F, 0xFF, 0xF8, 0xF, 0xFF, 0xF0, 0xF, 0xFF, 0xF0, 0x7, 0xFF, 0xE0, | |
0x3, 0xFF, 0xC0, 0x7, 0xFF, 0xE0, 0xF, 0xFF, 0xF0, 0xF, 0xFF, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 | |
}, // | |
{0x0, 0x0, 0x0, 0x0, 0x3C, 0x0, 0x0, 0x3C, 0x0, 0x0, 0x3C, 0x0, 0xF, 0x3C, 0xF0, 0x1F, 0xFF, 0xF8, | |
0x3F, 0xFF, 0xFC, 0x7F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFE, | |
0x7F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFE, 0x3F, 0xFF, 0xFC, 0x1F, 0xFF, 0xF8, 0xF, 0xFF, 0xF0, 0x7, 0xFF, 0xE0, | |
0x3, 0xFF, 0xC0, 0x7, 0xFF, 0xE0, 0xF, 0xFF, 0xF0, 0xF, 0xFF, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 | |
} // | |
}; | |
const uint8_t fig_cont[6][72] PROGMEM={ | |
{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7E, 0x0, 0x0, 0x81, 0x0, 0x1, 0x0, 0x80, | |
0x1, 0x0, 0x80, 0x1, 0x0, 0x80, 0x0, 0x81, 0x0, 0x3, 0xC3, 0xC0, 0x2, 0x0, 0x40, 0x2, 0x0, 0x40, | |
0x3, 0xC3, 0xC0, 0x0, 0x42, 0x0, 0x0, 0x81, 0x0, 0x0, 0x81, 0x0, 0x1, 0x0, 0x80, 0x2, 0x0, 0x40, | |
0x4, 0x0, 0x20, 0x8, 0x0, 0x10, 0x8, 0x0, 0x10, 0x8, 0x0, 0x10, 0xF, 0xFF, 0xF0, 0x0, 0x0, 0x0 | |
}, // | |
{0x0, 0x0, 0x0, 0x0, 0x66, 0x0, 0x0, 0x99, 0x0, 0x1, 0x0, 0x80, 0x2, 0xC0, 0x40, 0x4, 0xC0, 0x20, | |
0x8, 0x0, 0x10, 0x10, 0x0, 0x8, 0x20, 0x0, 0x4, 0x20, 0xC0, 0x4, 0x21, 0x40, 0x4, 0x12, 0x80, 0x4, | |
0xD, 0x0, 0x8, 0x2, 0x0, 0x10, 0x2, 0x0, 0x20, 0x2, 0x0, 0x40, 0x2, 0x0, 0x80, 0x1, 0x1, 0x0, | |
0x7, 0x81, 0xE0, 0x8, 0x0, 0x10, 0x10, 0x0, 0x8, 0x10, 0x0, 0x8, 0x1F, 0xFF, 0xF8, 0x0, 0x0, 0x0 | |
}, // | |
{0x0, 0x0, 0x0, 0x0, 0x3C, 0x0, 0x0, 0x42, 0x0, 0x0, 0x81, 0x0, 0x0, 0x81, 0x0, 0x1, 0xC3, 0x80, | |
0x2, 0x18, 0x40, 0x4, 0x18, 0x20, 0x8, 0x18, 0x10, 0x8, 0x18, 0x10, 0x9, 0xFF, 0x90, 0x9, 0xFF, 0x90, | |
0x8, 0x18, 0x10, 0x8, 0x18, 0x10, 0x8, 0x18, 0x10, 0x4, 0x18, 0x20, 0x2, 0x18, 0x40, 0x9, 0x0, 0x90, | |
0x14, 0x81, 0x28, 0x23, 0x81, 0xC4, 0x40, 0x0, 0x2, 0x40, 0x0, 0x2, 0x7F, 0xFF, 0xFE, 0x0, 0x0, 0x0 | |
}, // | |
{0x0, 0x0, 0x0, 0x1F, 0x3C, 0xF8, 0x10, 0xC3, 0x8, 0x10, 0xC3, 0x8, 0x10, 0x0, 0x8, 0x10, 0x0, 0x8, | |
0xB, 0xFF, 0xD0, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, | |
0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, 0x4, 0x0, 0x20, | |
0x4, 0x0, 0x20, 0xB, 0xFF, 0xD0, 0x10, 0x0, 0x8, 0x10, 0x0, 0x8, 0x1F, 0xFF, 0xF8, 0x0, 0x0, 0x0 | |
}, // | |
{0x0, 0x18, 0x0, 0x3, 0x24, 0xC0, 0x4, 0xC3, 0x20, 0x38, 0x66, 0x1C, 0x4C, 0xA5, 0x32, 0x84, 0xA5, 0x21, | |
0x4C, 0xA5, 0x32, 0x4C, 0xA5, 0x32, 0x4C, 0xA5, 0x32, 0x4C, 0xA5, 0x32, 0x4C, 0xA5, 0x32, 0x4C, 0x42, 0x32, | |
0x24, 0x42, 0x24, 0x20, 0x0, 0x4, 0x20, 0x0, 0x4, 0x10, 0x0, 0x8, 0x10, 0x0, 0x8, 0x8, 0x0, 0x10, | |
0x4, 0x0, 0x20, 0xF, 0xFF, 0xF0, 0x10, 0x0, 0x8, 0x10, 0x0, 0x8, 0x1F, 0xFF, 0xF8, 0x0, 0x0, 0x0 | |
}, // | |
{0x0, 0x7E, 0x0, 0x0, 0x42, 0x0, 0x0, 0x42, 0x0, 0xF, 0xC3, 0xF0, 0x10, 0xC3, 0x8, 0x20, 0x7E, 0x4, | |
0x40, 0x3C, 0x2, 0x80, 0x18, 0x1, 0x80, 0x18, 0x1, 0x80, 0x18, 0x1, 0x80, 0x18, 0x1, 0x80, 0x18, 0x1, | |
0x80, 0x18, 0x1, 0x80, 0x18, 0x1, 0x40, 0x18, 0x2, 0x20, 0x18, 0x4, 0x10, 0x18, 0x8, 0x8, 0x18, 0x10, | |
0x4, 0x18, 0x20, 0xB, 0xFF, 0xD0, 0x10, 0x0, 0x8, 0x10, 0x0, 0x8, 0x1F, 0xFF, 0xF8, 0x0, 0x0, 0x0 | |
} // | |
}; | |
const int pos[7][8][8] PROGMEM={ | |
{{ 0, 0, 0, 0, 0, 0, 0, 0}, // | |
{100,100,100,100,100,100,100,100}, //{ 50, 50, 50, 50, 50, 50, 50, 50}, | |
{ 20, 30, 40, 50, 50, 40, 30, 20}, //{ 10, 10, 20, 30, 30, 20, 10, 10}, | |
{ 5, 5, 10, 25, 25, 10, 5, 5}, | |
{ 0, 0, 0, 20, 20, 0, 0, 0}, | |
{ 5, -5,-10, 0, 0,-10, -5, 5}, | |
{ 5, 10, 10,-20,-20, 10, 10, 5}, //{ 5, 10, 10,-20,-20, 10, 10, 5}, | |
{ 0, 0, 0, 0, 0, 0, 0, 0}}, | |
{{-50,-40,-30,-30,-30,-30,-40,-50}, // | |
{-40,-20, 0, 0, 0, 0,-20,-40}, | |
{-30, 0, 10, 15, 15, 10, 0,-30}, | |
{-30, 5, 15, 20, 20, 15, 5,-30}, | |
{-30, 0, 15, 20, 20, 15, 0,-30}, | |
{-30, 5, 10, 15, 15, 10, 5,-30}, | |
{-40,-20, 0, 5, 5, 0,-20,-40}, | |
{-50,-40,-30,-30,-30,-30,-40,-50}}, | |
{{-20,-10,-10,-10,-10,-10,-10,-20}, // | |
{-10, 0, 0, 0, 0, 0, 0,-10}, | |
{-10, 0, 5, 10, 10, 5, 0,-10}, | |
{-10, 5, 5, 10, 10, 5, 5,-10}, | |
{-10, 0, 10, 10, 10, 10, 0,-10}, | |
{-10, 10, 10, 10, 10, 10, 10,-10}, | |
{-10, 5, 0, 0, 0, 0, 5,-10}, | |
{-20,-10,-10,-10,-10,-10,-10,-20}}, | |
{{ 0, 0, 0, 0, 0, 0, 0, 0}, // | |
{ 5, 10, 10, 10, 10, 10, 10, 5}, | |
{ -5, 0, 0, 0, 0, 0, 0, -5}, | |
{ -5, 0, 0, 0, 0, 0, 0, -5}, | |
{ -5, 0, 0, 0, 0, 0, 0, -5}, | |
{ -5, 0, 0, 0, 0, 0, 0, -5}, | |
{ -5, 0, 0, 0, 0, 0, 0, -5}, | |
{ 0, 0, 0, 5, 5, 0, 0, 0}}, | |
{{-20,-10,-10, -5, -5,-10,-10,-20}, // | |
{-10, 0, 0, 0, 0, 0, 0,-10}, | |
{-10, 0, 5, 5, 5, 5, 0,-10}, | |
{ -5, 0, 5, 5, 5, 5, 0, -5}, | |
{ 0, 0, 5, 5, 5, 5, 0, -5}, | |
{-10, 5, 5, 5, 5, 5, 0,-10}, | |
{-10, 0, 5, 0, 0, 0, 0,-10}, | |
{-20,-10,-10, -5, -5,-10,-10,-20}}, | |
{{-30,-40,-40,-50,-50,-40,-40,-30}, // | |
{-30,-40,-40,-50,-50,-40,-40,-30}, | |
{-30,-40,-40,-50,-50,-40,-40,-30}, | |
{-30,-40,-40,-50,-50,-40,-40,-30}, | |
{-20,-30,-30,-40,-40,-30,-30,-20}, | |
{-10,-20,-20,-20,-20,-20,-20,-10}, | |
{ 10, 10,-10,-10,-10,-10, 10, 10}, //{ 20, 20, 0, 0, 0, 0, 20, 20}, | |
{ 10, 40, 30, 0, 0, 0, 50, 10}}, //{ 20, 30, 10, 0, 0, 10, 30, 20}}, | |
{{-50,-40,-30,-20,-20,-30,-40,-50}, // | |
{-30,-20,-10, 0, 0,-10,-20,-30}, | |
{-30,-10, 20, 30, 30, 20,-10,-30}, | |
{-30,-10, 30, 40, 40, 30,-10,-30}, | |
{-30,-10, 30, 40, 40, 30,-10,-30}, | |
{-30,-10, 20, 30, 30, 20,-10,-30}, | |
{-30,-30, 0, 0, 0, 0,-30,-30}, | |
{-50,-30,-30,-30,-30,-30,-30,-50}} | |
}; | |
//********************************** | |
void drawBitmap(int16_t x, int16_t y, | |
const uint8_t *bitmap, int16_t w, int16_t h, | |
uint16_t color) { | |
int16_t i, j, byteWidth = (w + 7) / 8; | |
for(j=0; j<h; j++) { | |
for(i=0; i<w; i++ ) { | |
if(pgm_read_byte(bitmap + j * byteWidth + i / 8) & (128 >> (i & 7))) { | |
GO.lcd.drawPixel(x+i, y+j, color); | |
} | |
} | |
} | |
} | |
//**************************** | |
uint8_t music[1000]; | |
void tone_volume(uint16_t frequency, uint32_t duration) { | |
float interval=0.001257*float(frequency); | |
float phase=0; | |
for (int i=0;i<1000;i++) { | |
music[i]=127+126*sin(phase); | |
phase+=interval; | |
} | |
music[999]=0; | |
int remains=duration; | |
for (int i=0;i<duration;i+=200) { | |
if (remains<200) { | |
music[remains*999/200]=0; | |
} | |
GO.Speaker.playMusic(music,5000); | |
remains-=200; | |
} | |
} | |
//**************************** | |
void beep(int leng) { | |
if (sound) GO.Speaker.setVolume(1); else GO.Speaker.setVolume(0); | |
tone_volume(1000,leng); | |
} | |
//**************************** | |
void definecolors() { | |
CBLACK =0x0000; | |
CBLUE =0x07FF; //0x001F; | |
CRED =0xF800; | |
CGREEN =0x07E0; | |
CCYAN =0x07FF; | |
CMAGENTA=0xF81F; | |
CYELLOW =0xFFE0; | |
CWHITE =0xFFFF; | |
CWHITEFIG =getColor(200,200,140); | |
CGRAY =0x7BEF; | |
CDARK =getColor(32,32,32); | |
CGRAY2 =getColor(16,16,16); | |
CBLACKF =getColor(114,75,0); | |
CWHITEF =getColor(180,114,0); | |
CBLACKFIG =getColor(15,24,8); | |
CBLACKCONT =getColor(160,160,120); | |
} | |
//**************************** | |
uint16_t getColor(uint8_t red, uint8_t green, uint8_t blue) | |
{ | |
red >>= 3; | |
green >>= 2; | |
blue >>= 3; | |
return (red << 11) | (green << 5) | blue; | |
} | |
//**************************** | |
void clearstatus() { | |
GO.lcd.fillRect(240,166,80,20,BLACK); | |
GO.lcd.drawFastHLine(10,237,220,BLACK); | |
GO.lcd.drawFastHLine(10,239,220,BLACK); | |
} | |
//**************************** | |
void setup() { | |
Serial.begin(115200); | |
Serial.flush(); | |
Serial.println(F("Start")); | |
GO.begin(); | |
prefs.begin("AM_Chess", false); | |
GO.lcd.setBrightness(200); // BRIGHTNESS = MAX 255 | |
GO.lcd.fillScreen(BLACK); // CLEAR SCREEN | |
// GO.lcd.setRotation(0); // SCREEN ROTATION = 0 | |
definecolors(); | |
beep(100); | |
for (int i=0;i<MAXSTEPS;i++) { | |
steps[i].x1=0; steps[i].y1=0; | |
steps[i].x2=0; steps[i].y2=0; | |
steps[i].fig1=0; steps[i].fig2=0; | |
steps[i].check=0; | |
steps[i].type=0; | |
steps[i].weight=0; | |
} | |
GO.lcd.setTextColor(getColor(230,230,200)); | |
GO.lcd.setTextSize(2); | |
GO.lcd.setCursor(50,30); GO.lcd.print("Arduino Mega Chess"); | |
GO.lcd.setCursor(88,50); GO.lcd.print("for ODROID GO"); | |
GO.lcd.setTextColor(CGRAY); | |
GO.lcd.setCursor(62,70); GO.lcd.print("by Sergey Urusov"); | |
GO.lcd.setTextSize(1); | |
GO.lcd.setCursor(100,95); GO.lcd.print("[email protected]"); | |
GO.lcd.setCursor(85,110); GO.lcd.print("version 1.0, engine 1.4"); | |
GO.lcd.setCursor(80,220); GO.lcd.print("press Menu to READ this"); | |
GO.lcd.setTextColor(CWHITEFIG); | |
GO.lcd.drawRect(60,150,20,20,CGRAY); // < | |
GO.lcd.drawRect(80,150,20,20,CGRAY); | |
GO.lcd.drawRect(80,130,20,20,CGRAY); | |
GO.lcd.drawRect(80,170,20,20,CGRAY); | |
GO.lcd.drawRect(100,150,20,20,CGRAY); // > | |
GO.lcd.drawCircle(175,160,10,CGRAY); // B | |
GO.lcd.drawCircle(200,150,10,CGRAY); // A | |
GO.lcd.setTextSize(1); | |
GO.lcd.setCursor(66,157); GO.lcd.print("<"); | |
GO.lcd.setCursor(106,157); GO.lcd.print(">"); | |
GO.lcd.setCursor(173,158); GO.lcd.print("B"); | |
GO.lcd.setCursor(197,148); GO.lcd.print("A"); | |
GO.lcd.setCursor(110,190); GO.lcd.print("Menu:menu A:Do"); | |
GO.lcd.setCursor(110,200); GO.lcd.print("B:Undo"); | |
/* | |
GO.lcd.setCursor(80,220); GO.lcd.print("press any key to READ this"); | |
GO.lcd.setTextColor(CWHITEFIG); | |
GO.lcd.drawRect(38,150,60,30,CGRAY); | |
GO.lcd.drawRect(130,150,60,30,CGRAY); | |
GO.lcd.drawRect(225,150,60,30,CGRAY); | |
GO.lcd.setTextSize(1); | |
GO.lcd.setCursor(57,162); GO.lcd.print("Left"); | |
GO.lcd.setCursor(143,162); GO.lcd.print("Choice"); | |
GO.lcd.setCursor(240,162); GO.lcd.print("Right"); | |
GO.lcd.setCursor(110,190); GO.lcd.print("long press - menu"); | |
GO.lcd.setCursor(110,200); GO.lcd.print("or exit from menu"); | |
*/ | |
uint32_t tim=millis(); | |
while (millis()-tim<15000) { | |
GO.update(); | |
if (GO.BtnStart.pressedFor(50)) { | |
beep(100); | |
GO.lcd.fillRect(75,220,180,12,CBLACK); | |
GO.lcd.setTextColor(CGRAY); | |
GO.lcd.setCursor(77,220); GO.lcd.print("press any key to ENTER game"); | |
while (millis()-tim<15000) { | |
GO.update(); | |
if (GO.BtnA.isPressed()||GO.BtnB.isPressed()) break; | |
} | |
break; | |
} | |
} | |
beep(100); | |
GO.lcd.fillScreen(BLACK); // CLEAR SCREEN | |
initboard(); | |
} | |
//**************************** | |
void initboard() { | |
for (int i=0;i<8;i++) | |
for (int j=0;j<8;j++) poledisp[j][i]=-100; // | |
GO.lcd.fillScreen(CBLACK); | |
GO.lcd.setTextColor(CGRAY); | |
GO.lcd.setTextSize(1); | |
for (int j=1;j<9;j++) { | |
GO.lcd.setCursor(0,j*28-17); | |
if (rotate) GO.lcd.print(j); else GO.lcd.print(9-j); | |
} | |
for (byte i=1;i<9;i++) { | |
GO.lcd.setCursor(i*28-9,227); | |
if (rotate) GO.lcd.print(char(96+9-i)); else GO.lcd.print(char(96+i)); | |
} | |
initscreen(); | |
} | |
//**************************** | |
void initscreen() { | |
show_board(); | |
show_steps(); | |
} | |
//**************************** | |
void loop() { | |
gui(); | |
if (solving) { | |
for (int i=1;i<3;i++) { tone_volume(400+400*i,100); delay(70); } | |
hidden=false; | |
lastscore=solve_step(); | |
float tim=float(millis()-starttime)/1000; | |
for (int i=2;i>=1;i--) { tone_volume(400+400*i,100); delay(70); } | |
if (lastscore>-9000&&lastscore!=8999) { | |
movestep(cur_step); | |
cur_step++; steps[cur_step].fig1=0; | |
} | |
initscreen(); | |
animate_step(cur_step-1,false); | |
clearstatus(); | |
if (lastscore>9000) { | |
GO.lcd.setTextSize(1); | |
GO.lcd.setTextColor(CGREEN,CBLACK); | |
GO.lcd.setCursor(260,176); | |
if (lastscore<9999) { | |
GO.lcd.print("# in "); | |
GO.lcd.print((9999-lastscore)/2+1); GO.lcd.print(F(" st")); | |
} else GO.lcd.print("Checkmate"); | |
} else if (lastscore<-9000) { | |
GO.lcd.setTextSize(1); | |
GO.lcd.setTextColor(CRED,CBLACK); | |
GO.lcd.setCursor(260,176); | |
steps[cur_step].fig1=0; | |
GO.lcd.print("GIVE UP!"); | |
show_steps(); | |
} else if (lastscore==8999) { //Draw | |
GO.lcd.setTextSize(1); | |
GO.lcd.setTextColor(CYELLOW); | |
GO.lcd.setCursor(260,176); | |
GO.lcd.print("Draw"); | |
} | |
GO.lcd.setTextSize(1); | |
GO.lcd.setTextColor(CGRAY); | |
GO.lcd.setCursor(240,176); | |
GO.lcd.print(tim,0); | |
GO.lcd.print("s "); | |
if (abs(lastscore)<5000) { | |
GO.lcd.print(lastscore); | |
} | |
GO.lcd.setCursor(240,166); | |
GO.lcd.print(count); | |
GO.lcd.print("pos"); | |
Serial.print(F("Positions estimated=")); Serial.println(count); | |
Serial.print(F("Time=")); Serial.print(tim,1); Serial.println("s"); | |
Serial.print(F("Speed=")); Serial.print(count/tim,1); Serial.println("nps"); | |
lastpressedany=millis(); | |
} | |
delay(10); | |
} | |
//**************************** | |
void load_moves() { | |
start_var=cur_step+21; | |
only_action=false; | |
lastbest.fig1=0; | |
steps[0].fig1=0; | |
load_variants(cur_step); | |
current_var=start_var; | |
int cv=cur_var; | |
hidden=true; | |
uint32_t tim=millis(); | |
solve_step(); | |
if (millis()-tim<1000) delay(millis()-tim); | |
cur_var=cv; | |
sort_variants(cur_step+21,cur_step+20+cur_var); | |
} | |
//********************************** | |
void gui() { | |
if (isstatus) { | |
if (millis()-quitime>1000) { | |
if (isstatus) show_status(); | |
quitime=millis(); | |
} | |
} | |
GO.update(); | |
if (GO.BtnA.isPressed()) | |
if (lastpressed==0) lastpressed=millis(); // | |
if (GO.JOY_X.isAxisPressed() == 2) | |
if (lastpressedleft==0) lastpressedleft=millis(); // | |
if (GO.JOY_X.isAxisPressed() == 1) | |
if (lastpressedright==0) lastpressedright=millis(); // | |
lastpressedany=max(max(max(lastpressed,lastpressedleft),lastpressedright),lastpressedany); | |
if (!menu&&!isstatus&&rotate==cur_step%2) { // AI | |
if (millis()>lastpressedany+3000) { | |
delay(100); | |
solving=true; | |
Serial.println(F("\nAutostart solving!")); | |
return; | |
} | |
float angle=3.1416-6.2832*(millis()-lastpressedany)/3000; | |
GO.lcd.drawLine(308,175,308+9*sin(angle),175+9*cos(angle),CGRAY); | |
delay(200); | |
} | |
if (!menu&&!isstatus&&rotate!=cur_step%2) { // | |
if (!movesload) { | |
load_moves(); | |
movesload=1; | |
animate_step(cur_step-1,true); | |
} | |
animategreen_step(current_var,false); | |
delay(100); | |
} | |
// if (GO.BtnA.isReleased()&&lastpressed) | |
// if (millis()-lastpressed>500) { // | |
if (GO.BtnMenu.pressedFor(50)) { | |
if (!isstatus) { | |
if (movesload) animategreen_step(current_var,true); | |
movesload=0; | |
lastpressed=0; | |
beep(50); | |
if (menu==0) menu=1; else menu=0; | |
submenu=0; | |
show_menu(); | |
} | |
return; | |
} else if (GO.BtnVolume.pressedFor(50)) { | |
beep(100); | |
sound = !sound; | |
beep(100); | |
show_menu(); | |
return; | |
} else if (GO.BtnSelect.pressedFor(50)) { | |
rotate = !rotate; | |
initboard(); | |
return; | |
} else if (GO.BtnA.pressedFor(50)) { | |
if (movesload&&cur_var>0) animategreen_step(current_var,true); | |
beep(5); | |
lastpressed=0; | |
switch (menu) { | |
case 0: // | |
if (solving) { // | |
beep(100); | |
solving=false; | |
} else { // AI | |
if (movesload) { | |
movesload=0; | |
float tim=float(millis()-starttime)/1000; | |
tone_volume(600,100); | |
steps[cur_step]=steps[current_var]; | |
movestep(cur_step); | |
cur_step++; steps[cur_step].fig1=0; | |
initscreen(); | |
animate_step(cur_step-1,false); | |
clearstatus(); | |
} else { | |
delay(100); | |
solving=1; | |
animate_step(cur_step,false); | |
} | |
} | |
return; | |
case 1: | |
if (submenu) { //new game | |
beep(200); | |
cur_step=1; | |
steps[1].fig1=0; | |
for (int i=0;i<8;i++) | |
for (int j=0;j<8;j++) pole[j][i]=(signed char)pgm_read_byte(&polestart[j][i]); | |
lastanimatedgreen.x1==99; | |
kingpositions(); | |
initboard(); | |
clearstatus(); | |
menu=0; | |
initscreen(); | |
show_menu(); | |
} else if (cur_step>1) { // | |
beep(100); | |
cur_step--; | |
animate_step(cur_step,true); | |
lastscore=0; | |
backstep(cur_step); | |
steps[cur_step].fig1=0; | |
lastscore=0; | |
show_board(); | |
menu=0; | |
show_steps(); | |
clearstatus(); | |
return; | |
} break; | |
case 2: | |
if (submenu) { //load game | |
short cur_step_=prefs.getShort("cur_step"); | |
short limit_=prefs.getShort("limit"); | |
if (cur_step>0&&cur_step<1000&&limit>=0&&limit<3) { | |
initboard(); | |
cur_step=cur_step_; limit=limit_; | |
sound=prefs.getBool("sound"); | |
rotate=prefs.getBool("rotate"); | |
prefs.getBytes("pole",pole,sizeof(pole)); | |
prefs.getBytes("steps",steps,sizeof(step_type)*cur_step); | |
beep(100); | |
} else { | |
beep(1000); sound=1; rotate=0; limit=0; cur_step=1; | |
} | |
//File file = SD.open("/AM_Chess.sav"); | |
//if (file) { | |
// Serial.println("file open"); | |
// file.read((uint8_t*)pole,64); | |
// uint8_t c[sizeof(step_type)]; | |
// file.read(c,sizeof(cur_step)); memcpy(&cur_step,c,sizeof(cur_step)); | |
// file.read(c,sizeof(limit)); memcpy(&limit,c,sizeof(limit)); | |
// file.read(c,sizeof(sound)); memcpy(&sound,c,sizeof(sound)); | |
// step_type t; | |
// for (int i=1;i<cur_step;i++) { | |
// t=steps[i]; | |
// file.read(c,sizeof(step_type)); | |
// memcpy(&t,c,sizeof(step_type)); | |
// } | |
// file.close(); | |
// beep(100); | |
//} else { beep(1000); Serial.println("SD card error!"); } | |
steps[0].fig1=0; | |
steps[cur_step].fig1=0; | |
lastanimatedgreen.x1==99; | |
initboard(); | |
kingpositions(); | |
clearstatus(); | |
menu=0; | |
show_menu(); | |
initscreen(); | |
return; | |
} else { // | |
beep(100); | |
rotate=!rotate; | |
initboard(); | |
return; | |
} break; | |
case 3: | |
if (submenu) { //save game | |
prefs.putShort("cur_step",cur_step); | |
prefs.putShort("limit",limit); | |
prefs.putBool("sound",sound); | |
prefs.putBool("rotate",rotate); | |
prefs.putBytes("pole",pole,sizeof(pole)); | |
prefs.putBytes("steps",steps,sizeof(step_type)*cur_step); | |
beep(50); delay(50); beep(50); delay(50); beep(50); | |
//File file = SD.open("/AM_Chess.sav", FILE_WRITE); | |
//if (file) { | |
// Serial.println("file open for write"); | |
// file.write((const uint8_t*)pole,64); | |
// uint8_t c[sizeof(step_type)]; | |
// memcpy(c,&cur_step,sizeof(cur_step)); file.write(c,sizeof(cur_step)); | |
// memcpy(c,&limit,sizeof(limit)); file.write(c,sizeof(limit)); | |
// memcpy(c,&sound,sizeof(sound)); file.write(c,sizeof(sound)); | |
// step_type t; | |
// for (int i=1;i<cur_step;i++) { | |
// t=steps[i]; | |
// memcpy(c,&t,sizeof(step_type)); | |
// file.write(c,sizeof(step_type)); | |
// } | |
// file.close(); | |
// beep(100); | |
//} else { beep(1000); Serial.println("SD card error!"); } | |
menu=0; | |
show_menu(); | |
return; | |
} else { // Game | |
submenu=1; menu=1; | |
show_menu(); | |
} break; | |
case 4: | |
if (submenu) { // USB | |
if (!load_usb()) return; | |
limit=2; | |
beep(200); | |
menu=0; | |
initboard(); | |
kingpositions(); | |
clearstatus(); | |
initscreen(); | |
return; | |
} else { // | |
beep(100); | |
limit++; if (limit>2) limit=0; | |
show_menu(); | |
return; | |
} | |
case 5: // | |
if (sound==1) { beep(100); sound=0; } else { sound=1; beep(200); } | |
show_menu(); | |
return; | |
} //switch | |
} | |
if (GO.JOY_X.isAxisPressed() == 2) { | |
lastpressedleft=0; | |
if (menu==0) { | |
if (movesload&&cur_var>0) { | |
animategreen_step(current_var,true); | |
current_var--; | |
if (current_var<cur_step+21) current_var=cur_step+21+cur_var-1; | |
} | |
} else { | |
beep(100); | |
menu--; | |
if (menu<1) | |
if (submenu) menu=4; else menu=5; | |
show_menu(); | |
delay(200); | |
} | |
} | |
if (GO.JOY_X.isAxisPressed() == 1) { | |
lastpressedright=0; | |
if (menu==0) { | |
if (movesload&&cur_var>0) { | |
animategreen_step(current_var,true); | |
current_var++; | |
if (current_var>=cur_step+21+cur_var) current_var=cur_step+21; | |
} | |
} else { | |
beep(100); | |
menu++; if (menu>5) menu=1; | |
if (submenu&&menu>4) menu=1; | |
show_menu(); | |
delay(200); | |
} | |
} | |
} | |
//********************************** | |
void animategreen_step(int nstep, boolean hide) { | |
if (cur_var==0) return; | |
int j=steps[nstep].x1; | |
int j2=steps[nstep].x2; | |
int dj=j2-j; | |
int i=steps[nstep].y1; | |
int i2=steps[nstep].y2; | |
int di=i2-i; | |
if (di!=0) di=di/abs(di); | |
if (dj!=0) dj=dj/abs(dj); | |
if (lastanimatedgreen.x1==steps[nstep].x1&&lastanimatedgreen.y1==steps[nstep].y1&& | |
lastanimatedgreen.x2==steps[nstep].x2&&lastanimatedgreen.y2==steps[nstep].y2&& | |
lastanimatedgreen.fig1==steps[nstep].fig1&&!hide) { | |
int show=(millis()/500)%2; | |
movestep(nstep); | |
if (show) show_cont(i2,j2); | |
backstep(nstep); | |
if (!show) show_fig(i2,j2); | |
if (!rotate) GO.lcd.drawRect(i2*28+8,j2*28+1,27,27,CGREEN); | |
else GO.lcd.drawRect((7-i2)*28+8,(7-j2)*28+1,27,27,CGREEN); | |
return; | |
} | |
lastanimatedgreen=steps[nstep]; | |
if (hide) show_fig(i,j); | |
while (j!=steps[nstep].x2||i!=steps[nstep].y2) { | |
show_fig(i,j); | |
if (!hide) | |
if (!rotate) GO.lcd.drawRect(i*28+8,j*28+1,27,27,CGREEN); | |
else GO.lcd.drawRect((7-i)*28+8,(7-j)*28+1,27,27,CGREEN); | |
int mj=0; | |
if (j!=steps[nstep].x2) { j+=dj; mj=1; } | |
if (abs(steps[nstep].fig1)==fn&&mj==1) continue; | |
if (i!=steps[nstep].y2) i+=di; | |
} | |
if (hide) { show_fig(i,j); lastanimatedgreen.x1=99; } | |
} | |
//**************************** | |
void show_cont(int i,int j) { | |
uint16_t color,color_cont; | |
color=CBLACKF; | |
if ((i+j+2)%2==0) color=CWHITEF; | |
int jj=j, ii=i; | |
if (rotate) { jj=7-j; ii=7-i; } | |
GO.lcd.fillRect(ii*28+7,jj*28,29,29,color); | |
//GO.lcd.drawRect(ii*28+7,jj*28,29,29,CGREEN); | |
color=CBLACK; | |
if (pole[j][i]>0) color=CWHITE; | |
if (pole[j][i]!=0) { | |
drawBitmap(ii*28+10, jj*28+3,&fig_cont[(int)abs(pole[j][i])-1][0], 24, 24,color); | |
} | |
} | |
//********************************** | |
void animate_step(int nstep, boolean hide) { | |
uint16_t color=getColor(220,220,200); | |
if (!hide&&nstep-1>0&&steps[nstep-1].fig1!=0) animate_step(nstep-1,true); | |
if (nstep<1||steps[nstep].fig1==0) return; | |
int j=steps[nstep].x1; | |
int dj=steps[nstep].x2-steps[nstep].x1; | |
int i=steps[nstep].y1; | |
int di=steps[nstep].y2-steps[nstep].y1; | |
if (di!=0) di=di/abs(di); | |
if (dj!=0) dj=dj/abs(dj); | |
if (hide) show_fig(i,j); | |
while (j!=steps[nstep].x2||i!=steps[nstep].y2) { | |
show_fig(i,j); | |
if (!hide) | |
if (!rotate) GO.lcd.drawRect(i*28+8,j*28+1,27,27,color); | |
else GO.lcd.drawRect((7-i)*28+8,(7-j)*28+1,27,27,color); | |
int mj=0; | |
if (j!=steps[nstep].x2) { j+=dj; mj=1; } | |
if (abs(steps[nstep].fig1)==fn&&mj==1) continue; | |
if (i!=steps[nstep].y2) i+=di; | |
} | |
show_fig(i,j); | |
if (!hide) | |
if (!rotate) GO.lcd.drawRect(i*28+8,j*28+1,27,27,color); | |
else GO.lcd.drawRect((7-i)*28+8,(7-j)*28+1,27,27,color); | |
} | |
//********************************** | |
void show_status() { | |
if (rotate!=cur_step%2) return; | |
int tim=(millis()-starttime)/1000; | |
int cur=220000*tim/(limittime-starttime); | |
if (cur>220) { cur=220; solving=false; } | |
GO.lcd.drawFastHLine(10,237,cur,CGRAY); | |
GO.lcd.drawFastHLine(10,239,progress*2,CGRAY); | |
int m=tim/60; | |
int s=tim%60; | |
GO.lcd.setTextWrap(1); | |
GO.lcd.setTextColor(CGRAY); | |
GO.lcd.setTextSize(1); | |
GO.lcd.fillRect(240,166,80,10,CBLACK); | |
GO.lcd.setCursor(242,166); | |
if (m>0) { GO.lcd.print(m); GO.lcd.print(":"); } | |
if (s>0) { | |
if (s<10&&m>0) GO.lcd.print("0"); | |
GO.lcd.print(s); | |
} else if (m>0) GO.lcd.print("00"); else GO.lcd.print("0"); | |
GO.lcd.setCursor(280,166); | |
GO.lcd.print(cur_level); | |
GO.lcd.setCursor(242,176); | |
if (cur_step%2==1) GO.lcd.setTextColor(CWHITE); else GO.lcd.setTextColor(CGRAY); | |
if (lastbest.fig1!=steps[0].fig1||lastbest.x1!=steps[0].x1||lastbest.y1!=steps[0].y1|| | |
lastbest.x2!=steps[0].x2||lastbest.y2!=steps[0].y2) { | |
lastbest=steps[0]; | |
GO.lcd.fillRect(240,176,80,10,CBLACK); | |
GO.lcd.setCursor(242,176); | |
GO.lcd.setTextColor(CGRAY); | |
GO.lcd.print(str_step(0)); | |
blinkstep=0; | |
} | |
if (steps[0].fig1!=0&&blinkstep==0&&tim>5) { | |
signed char poleb[8][8]; | |
for (int i=0;i<8;i++) | |
for (int j=0;j<8;j++) { poleb[j][i]=pole[j][i]; pole[j][i]=pole0[j][i]; } | |
movestep(0); | |
show_board(); | |
delay(100); | |
backstep(0); | |
show_board(); | |
for (int i=0;i<8;i++) | |
for (int j=0;j<8;j++) pole[j][i]=poleb[j][i]; | |
kingpositions(); | |
} | |
blinkstep++; | |
if (blinkstep>2) blinkstep=0; | |
} | |
//**************************** | |
void show_fig(int i,int j) { | |
uint16_t color,color_cont; | |
color=CBLACKF; | |
if ((i+j+2)%2==0) color=CWHITEF; | |
int jj=j, ii=i; | |
if (rotate) { jj=7-j; ii=7-i; } | |
GO.lcd.fillRect(ii*28+7,jj*28,29,29,color); | |
GO.lcd.drawRect(ii*28+7,jj*28,29,29,CGRAY); | |
color=CBLACKFIG; color_cont=CBLACKCONT; //CGRAY; | |
if (pole[j][i]>0) { color=CWHITEFIG; color_cont=CBLACK; } | |
if (pole[j][i]!=0) { | |
drawBitmap(ii*28+10, jj*28+3,&fig[(int)abs(pole[j][i])-1][0], 24, 24,color); | |
drawBitmap(ii*28+10, jj*28+3,&fig_cont[(int)abs(pole[j][i])-1][0], 24, 24,color_cont); | |
} | |
} | |
//**************************** | |
void show_board() { | |
for (int i=0;i<8;i++) | |
for (int j=0;j<8;j++) { | |
if (poledisp[j][i]!=pole[j][i]) show_fig(i,j); | |
poledisp[j][i]=pole[j][i]; | |
} | |
} | |
//********************************** | |
boolean load_usb() { | |
char s='x',i=0,j=0; boolean load=false; | |
Serial.println(F("Wait for FEN position")); | |
for (int i=0;i<8;i++) | |
for (int j=0;j<8;j++) { | |
pole0[j][i]=pole[j][i]; | |
pole[j][i]=(char)pgm_read_byte(&polezero[j][i]); | |
} | |
while (s!=' ') { | |
s=Serial.read(); | |
if (i>7) { i=0; j++; } | |
if (!getpole(j,i)) break; | |
switch (s) { | |
case '/': i=0; break; | |
case 'p': pole[j][i]=-fp; i++; break; | |
case 'P': pole[j][i]=fp; i++; break; | |
case 'n': pole[j][i]=-fn; i++; break; | |
case 'N': pole[j][i]=fn; i++; break; | |
case 'b': pole[j][i]=-fb; i++; break; | |
case 'B': pole[j][i]=fb; i++; break; | |
case 'r': pole[j][i]=-fr; i++; break; | |
case 'R': pole[j][i]=fr; i++; break; | |
case 'q': pole[j][i]=-fq; i++; break; | |
case 'Q': pole[j][i]=fq; i++; break; | |
case 'k': pole[j][i]=-fk; i++; break; | |
case 'K': pole[j][i]=fk; i++; break; | |
case '1': i++; break; | |
case '2': i+=2; break; | |
case '3': i+=3; break; | |
case '4': i+=4; break; | |
case '5': i+=5; break; | |
case '6': i+=6; break; | |
case '7': i+=7; break; | |
case '8': i=0; j++; break; | |
case ' ': break; | |
} | |
delay(20); | |
if (i+j>0&&Serial.available()==0) break; | |
} | |
s=0; | |
if (Serial.available()>0) s=Serial.read(); | |
while (Serial.available()>0) Serial.read(); | |
if (s=='w'||s==0) { cur_step=1; load=true; rotate=1; } | |
else if (s=='b') { cur_step=2; load=true; rotate=0; } | |
else load=false; | |
if (load) { | |
steps[1].fig1=0; steps[2].fig1=0; | |
Serial.println(F("Position loaded")); | |
} else { | |
for (int i=0;i<8;i++) | |
for (int j=0;j<8;j++) | |
pole[j][i]=pole0[j][i]; | |
} | |
return load; | |
} | |
//********************************** | |
String str_step(int i) { | |
String s=""; | |
if (steps[i].fig1==0) return s; | |
if (steps[i].type==2) s="0-0"; | |
else if (steps[i].type==3) s="0-0-0"; | |
else { | |
if (abs(steps[i].fig1)>1) s=fig_symb[(int)abs(steps[i].fig1)]; | |
if (abs(steps[i].fig1<5)) { | |
s=s+char(97+steps[i].y1); | |
s=s+String(8-steps[i].x1); | |
if (steps[i].fig2==0) s=s+"-"; | |
} | |
if (steps[i].fig2!=0) { | |
s=s+"x"; | |
if (abs(steps[i].fig2)>1) s=s+fig_symb[(int)abs(steps[i].fig2)]; | |
} | |
s=s+char(97+steps[i].y2); | |
s=s+String(8-steps[i].x2); | |
} | |
if (steps[i].type>3) s=s+fig_symb[steps[i].type-2]; | |
if (steps[i].check==1) s=s+"+"; else | |
if (steps[i].check==2) s=s+"#"; | |
return s; | |
} | |
//**************************** | |
void show_steps() { | |
uint16_t color=getColor(200,200,180); | |
GO.lcd.fillRect(234,0,90,160,getColor(8,8,8)); | |
GO.lcd.fillRect(234,0,90,24,CDARK); | |
GO.lcd.setTextSize(1); | |
GO.lcd.setTextColor(getColor(160,160,140),CDARK); | |
GO.lcd.setCursor(241,2); | |
GO.lcd.print(" ArduinoMega"); | |
GO.lcd.setCursor(240,14); | |
GO.lcd.print("Chess ODROID"); | |
int i=1; int y=27; | |
int cur=(cur_step+1)/2; // | |
int lim_step=cur_step; | |
if (cur>6) i=cur-5; | |
while (i<=cur&&y<140) { // | |
GO.lcd.setCursor(240,y); | |
GO.lcd.setTextColor(CGRAY); | |
GO.lcd.print(i); | |
GO.lcd.print(". "); | |
if (i*2-1==cur_step-1) GO.lcd.setTextColor(color); | |
if (steps[i*2-1].fig1!=0) GO.lcd.print(str_step(i*2-1)); | |
if (steps[i*2].fig1==0||i*2>lim_step) break; | |
GO.lcd.setTextColor(CBLACK); | |
GO.lcd.setCursor(240,y+10); | |
GO.lcd.print(i); | |
GO.lcd.print(" "); | |
GO.lcd.setTextColor(CGRAY); | |
if (i*2==cur_step-1) GO.lcd.setTextColor(color); | |
GO.lcd.print(str_step(i*2)); | |
i++; y+=22; | |
} | |
show_menu(); | |
} | |
//**************************** | |
void show_menu() { | |
uint16_t color=getColor(220,220,200); | |
if (menu==0) submenu=0; else animategreen_step(current_var,true); | |
GO.lcd.fillRect(233,190,86,50,CBLACK); | |
GO.lcd.setTextSize(1); | |
if (menu==1) GO.lcd.setTextColor(CBLACK,CBLUE); else GO.lcd.setTextColor(color,CGRAY2); | |
if (submenu) { | |
GO.lcd.setCursor(242,190); GO.lcd.print(" New Game "); | |
} else { | |
GO.lcd.setCursor(233,190); GO.lcd.print(" Back "); | |
} | |
if (menu==2) GO.lcd.setTextColor(CBLACK,CBLUE); else GO.lcd.setTextColor(color,CGRAY2); | |
if (submenu) { | |
GO.lcd.setCursor(242,203); GO.lcd.print(" Load Game "); | |
} else { | |
GO.lcd.setCursor(271,190); GO.lcd.print(" Rotate "); | |
} | |
if (menu==3) GO.lcd.setTextColor(CBLACK,CBLUE); else GO.lcd.setTextColor(color,CGRAY2); | |
if (submenu) { | |
GO.lcd.setCursor(242,216); GO.lcd.print(" Save Game "); | |
} else { | |
GO.lcd.setCursor(242,203); GO.lcd.print(" Game menu "); | |
} | |
if (menu==4) GO.lcd.setTextColor(CBLACK,CBLUE); else GO.lcd.setTextColor(color,CGRAY2); | |
if (submenu) { | |
GO.lcd.setCursor(242,229); GO.lcd.print(" USB FEN "); | |
} else { | |
GO.lcd.setCursor(242,216); GO.lcd.print(" Level "); | |
switch (limit) { | |
case 0: GO.lcd.print("LOW "); break; | |
case 1: GO.lcd.print("MED "); break; | |
case 2: GO.lcd.print("HIGH"); break; | |
} | |
} | |
if (menu==5) GO.lcd.setTextColor(CBLACK,CBLUE); else GO.lcd.setTextColor(color,CGRAY2); | |
if (submenu) { | |
} else { | |
GO.lcd.setCursor(242,227); GO.lcd.print(" Sound "); | |
if (sound) GO.lcd.print("ON "); else GO.lcd.print("OFF "); | |
} | |
} | |
//**************************** | |
boolean getdiagrowcheckw(signed char dj,signed char di) { // | |
signed char d,j1,i1; | |
j1=WKJ; i1=WKI; | |
for (d=1;d<8;d++) { | |
j1+=dj; i1+=di; | |
if (getpole(j1,i1)) { | |
if (pole[j1][i1]==-fq||pole[j1][i1]==-fb) return true; | |
if (pole[j1][i1]!=0) break; | |
} else break; | |
} | |
return false; | |
} | |
//**************************** | |
boolean getdiagrowcheckb(signed char dj,signed char di) { // | |
signed char d,j1,i1; | |
j1=BKJ; i1=BKI; | |
for (d=1;d<8;d++) { | |
j1+=dj; i1+=di; | |
if (getpole(j1,i1)) { | |
if (pole[j1][i1]==fq||pole[j1][i1]==fb) return true; | |
if (pole[j1][i1]!=0) break; | |
} else break; | |
} | |
return false; | |
} | |
//**************************** | |
boolean getstreightrowcheckw(signed char dj,signed char di) { // - | |
signed char d,j1,i1; | |
j1=WKJ; i1=WKI; | |
for (d=1;d<8;d++) { | |
j1+=dj; i1+=di; | |
if (getpole(j1,i1)) { | |
if (pole[j1][i1]==-fq||pole[j1][i1]==-fr) return true; | |
if (pole[j1][i1]!=0) break; | |
} else break; | |
} | |
return false; | |
} | |
//**************************** | |
boolean getstreightrowcheckb(signed char dj,signed char di) { // - | |
signed char d,j1,i1; | |
j1=BKJ; i1=BKI; | |
for (d=1;d<8;d++) { | |
j1+=dj; i1+=di; | |
if (getpole(j1,i1)) { | |
if (pole[j1][i1]==fq||pole[j1][i1]==fr) return true; | |
if (pole[j1][i1]!=0) break; | |
} else break; | |
} | |
return false; | |
} | |
//**************************** | |
boolean get_check(signed char king) { // | |
if (king==fk) { // | |
if (getdiagrowcheckw(-1, 1)) return true; | |
if (getdiagrowcheckw(-1,-1)) return true; | |
if (getdiagrowcheckw( 1,-1)) return true; | |
if (getdiagrowcheckw( 1, 1)) return true; | |
if (getstreightrowcheckw(-1, 0)) return true; | |
if (getstreightrowcheckw( 0, 1)) return true; | |
if (getstreightrowcheckw( 0,-1)) return true; | |
if (getstreightrowcheckw( 1, 0)) return true; | |
if (getpole(WKJ-2,WKI-1)&&pole[WKJ-2][WKI-1]==-fn) return true; | |
if (getpole(WKJ-2,WKI+1)&&pole[WKJ-2][WKI+1]==-fn) return true; | |
if (getpole(WKJ-1,WKI-2)&&pole[WKJ-1][WKI-2]==-fn) return true; | |
if (getpole(WKJ-1,WKI+2)&&pole[WKJ-1][WKI+2]==-fn) return true; | |
if (getpole(WKJ+1,WKI-2)&&pole[WKJ+1][WKI-2]==-fn) return true; | |
if (getpole(WKJ+1,WKI+2)&&pole[WKJ+1][WKI+2]==-fn) return true; | |
if (getpole(WKJ+2,WKI-1)&&pole[WKJ+2][WKI-1]==-fn) return true; | |
if (getpole(WKJ+2,WKI+1)&&pole[WKJ+2][WKI+1]==-fn) return true; | |
if (getpole(WKJ-1,WKI-1)&&pole[WKJ-1][WKI-1]==-fp) return true; | |
if (getpole(WKJ-1,WKI+1)&&pole[WKJ-1][WKI+1]==-fp) return true; | |
} else { // | |
if (getdiagrowcheckb( 1,-1)) return true; | |
if (getdiagrowcheckb( 1, 1)) return true; | |
if (getdiagrowcheckb(-1, 1)) return true; | |
if (getdiagrowcheckb(-1,-1)) return true; | |
if (getstreightrowcheckb( 1, 0)) return true; | |
if (getstreightrowcheckb( 0, 1)) return true; | |
if (getstreightrowcheckb( 0,-1)) return true; | |
if (getstreightrowcheckb(-1, 0)) return true; | |
if (getpole(BKJ+2,BKI-1)&&pole[BKJ+2][BKI-1]==fn) return true; | |
if (getpole(BKJ+2,BKI+1)&&pole[BKJ+2][BKI+1]==fn) return true; | |
if (getpole(BKJ+1,BKI-2)&&pole[BKJ+1][BKI-2]==fn) return true; | |
if (getpole(BKJ+1,BKI+2)&&pole[BKJ+1][BKI+2]==fn) return true; | |
if (getpole(BKJ-1,BKI-2)&&pole[BKJ-1][BKI-2]==fn) return true; | |
if (getpole(BKJ-1,BKI+2)&&pole[BKJ-1][BKI+2]==fn) return true; | |
if (getpole(BKJ-2,BKI-1)&&pole[BKJ-2][BKI-1]==fn) return true; | |
if (getpole(BKJ-2,BKI+1)&&pole[BKJ-2][BKI+1]==fn) return true; | |
if (getpole(BKJ+1,BKI-1)&&pole[BKJ+1][BKI-1]==fp) return true; | |
if (getpole(BKJ+1,BKI+1)&&pole[BKJ+1][BKI+1]==fp) return true; | |
} | |
if (abs(BKJ-WKJ)<=1&&abs(BKI-WKI)<=1) return true; // | |
return false; | |
} | |
//**************************** | |
boolean getpole(signed char j,signed char i) { // | |
if (j>=0&&j<8&&i>=0&&i<8) return true; | |
return false; | |
} | |
//**************************** | |
void addstep(signed char j1,signed char i1,signed char j2,signed char i2,signed char type) { | |
int st=start_var+cur_var; | |
steps[st].x1=j1; | |
steps[st].x2=j2; | |
steps[st].y1=i1; | |
steps[st].y2=i2; | |
steps[st].fig1=pole[j1][i1]; | |
steps[st].fig2=pole[j2][i2]; | |
if (type==1) { // | |
steps[st].fig2=-steps[st].fig1; | |
} | |
steps[st].type=type; | |
signed char ko=-fk; // | |
if (steps[st].fig1>0) ko=fk; | |
movestep(st); | |
if (get_check(ko)) { backstep(st); return; } // - | |
boolean che=get_check(-ko); // | |
backstep(st); | |
steps[st].weight=abs(steps[st].fig2)-abs(steps[st].fig1); | |
if (type>3) steps[st].weight+=fig_weight[type-2]; | |
if (endspiel&&steps[st].fig1==ko) steps[st].weight+=10; // - | |
steps[st].check=che; | |
if (che) steps[st].weight+=10; | |
if (only_action) { | |
if (steps[st].fig1==fp&&steps[st].x2==1||steps[st].fig1==-fp&&steps[st].x2==6) // | |
{ cur_var++; return; } | |
if (steps[st].fig2==0&&steps[st].type<4&&!che&&!check_on_table) return; | |
} | |
cur_var++; | |
} | |
//**************************** | |
void getrowstepsw(signed char j,signed char i,signed char dj,signed char di) { // | |
signed char d,j1,i1; | |
j1=j; i1=i; | |
for (d=1;d<8;d++) { | |
j1+=dj; i1+=di; | |
if (getpole(j1,i1)) { | |
if (pole[j1][i1]<=0) addstep(j,i,j1,i1,0); | |
if (pole[j1][i1]!=0) break; | |
} else break; | |
} | |
} | |
//**************************** | |
void getrowstepsb(signed char j,signed char i,signed char dj,signed char di) { // | |
signed char d,j1,i1; | |
j1=j; i1=i; | |
for (d=1;d<8;d++) { | |
j1+=dj; i1+=di; | |
if (getpole(j1,i1)) { | |
if (pole[j1][i1]>=0) addstep(j,i,j1,i1,0); | |
if (pole[j1][i1]!=0) break; | |
} else break; | |
} | |
} | |
//**************************** | |
void getonestepw(signed char j,signed char i,signed char dj,signed char di) { // | |
signed char j1,i1; | |
j1=j+dj; i1=i+di; | |
if (getpole(j1,i1)) | |
if (pole[j1][i1]<=0) addstep(j,i,j1,i1,0); | |
} | |
//**************************** | |
void getonestepb(signed char j,signed char i,signed char dj,signed char di) { // | |
signed char j1,i1; | |
j1=j+dj; i1=i+di; | |
if (getpole(j1,i1)) | |
if (pole[j1][i1]>=0) addstep(j,i,j1,i1,0); | |
} | |
//**************************** | |
void sort_variants(int from, int to) { // | |
while (1) { | |
int mov=0; | |
for (int i=from;i<to;i++) // | |
if (steps[i].weight<steps[i+1].weight) { | |
mov++; | |
step_type buf=steps[i]; | |
steps[i]=steps[i+1]; | |
steps[i+1]=buf; | |
} | |
if (mov==0) break; | |
} | |
} | |
//**************************** | |
void load_variants(int nstep) { // nstep | |
cur_var=0; | |
if (pole[WKJ][WKI]!=fk||pole[BKJ][BKI]!=-fk) kingpositions(); | |
if (nstep%2==1) check_on_table=get_check(fk); | |
else check_on_table=get_check(-fk); // | |
for (signed char i=0;i<8;i++) | |
for (signed char j=0;j<8;j++) | |
if (pole[j][i]>0&&nstep%2==1||pole[j][i]<0&&nstep%2==0) { | |
switch (pole[j][i]) { | |
case fp: // | |
if (getpole(j-1,i)&&pole[j-1][i]==0) | |
if (j!=1) addstep(j,i,j-1,i,0); else | |
for (signed char t=4;t<8;t++) addstep(1,i,0,i,t); //-... | |
if (j==6&&pole[j-1][i]==0&&pole[j-2][i]==0) addstep(j,i,j-2,i,0); | |
if (getpole(j-1,i-1)&&pole[j-1][i-1]<0) | |
if (j!=1) addstep(j,i,j-1,i-1,0); else | |
for (signed char t=4;t<8;t++) addstep(j,i,j-1,i-1,t); //-... | |
if (getpole(j-1,i+1)&&pole[j-1][i+1]<0) | |
if (j!=1) addstep(j,i,j-1,i+1,0); else | |
for (signed char t=4;t<8;t++) addstep(j,i,j-1,i+1,t); //-... | |
if (j==3&&steps[nstep-1].fig1==-fp&&steps[nstep-1].x2==3&&steps[nstep-1].x1==1) { | |
if (steps[nstep-1].y2-i==1) { // | |
addstep(j,i,j-1,i+1,1); | |
} else if (steps[nstep-1].y2-i==-1) { // | |
addstep(j,i,j-1,i-1,1); | |
} | |
} | |
break; | |
case -fp: // | |
if (getpole(j+1,i)&&pole[j+1][i]==0) | |
if (j!=6) addstep(j,i,j+1,i,0); else | |
for (signed char t=4;t<8;t++) addstep(j,i,j+1,i,t); //-... | |
if (j==1&&pole[j+1][i]==0&&pole[j+2][i]==0) addstep(j,i,j+2,i,0); | |
if (getpole(j+1,i-1)&&pole[j+1][i-1]>0) | |
if (j!=6) addstep(j,i,j+1,i-1,0); else | |
for (signed char t=4;t<8;t++) addstep(j,i,j+1,i-1,t); //-... | |
if (getpole(j+1,i+1)&&pole[j+1][i+1]>0) | |
if (j!=6) addstep(j,i,j+1,i+1,0); else | |
for (signed char t=4;t<8;t++) addstep(j,i,j+1,i+1,t); //-... | |
if (j==4&&steps[nstep-1].fig1==fp&&steps[nstep-1].x2==4&&steps[nstep-1].x1==6) { | |
if (steps[nstep-1].y2-i==1) { // | |
addstep(j,i,j+1,i+1,1); | |
} else if (steps[nstep-1].y2-i==-1) { // | |
addstep(j,i,j+1,i-1,1); | |
} | |
} | |
break; | |
case fn: // | |
getonestepw(j,i,-2,-1); | |
getonestepw(j,i,-2,1); | |
getonestepw(j,i,-1,-2); | |
getonestepw(j,i,-1,2); | |
getonestepw(j,i,2,-1); | |
getonestepw(j,i,2,1); | |
getonestepw(j,i,1,-2); | |
getonestepw(j,i,1,2); | |
break; | |
case -fn: // | |
getonestepb(j,i,-2,-1); | |
getonestepb(j,i,-2,1); | |
getonestepb(j,i,-1,-2); | |
getonestepb(j,i,-1,2); | |
getonestepb(j,i,2,-1); | |
getonestepb(j,i,2,1); | |
getonestepb(j,i,1,-2); | |
getonestepb(j,i,1,2); | |
break; | |
case fb: // | |
getrowstepsw(j,i,1,1); | |
getrowstepsw(j,i,-1,-1); | |
getrowstepsw(j,i,1,-1); | |
getrowstepsw(j,i,-1,1); | |
break; | |
case -fb: // | |
getrowstepsb(j,i,1,1); | |
getrowstepsb(j,i,-1,-1); | |
getrowstepsb(j,i,1,-1); | |
getrowstepsb(j,i,-1,1); | |
break; | |
case fr: // | |
getrowstepsw(j,i,1,0); | |
getrowstepsw(j,i,-1,0); | |
getrowstepsw(j,i,0,1); | |
getrowstepsw(j,i,0,-1); | |
break; | |
case -fr: // | |
getrowstepsb(j,i,1,0); | |
getrowstepsb(j,i,-1,0); | |
getrowstepsb(j,i,0,1); | |
getrowstepsb(j,i,0,-1); | |
break; | |
case fq: // | |
getrowstepsw(j,i,1,1); | |
getrowstepsw(j,i,-1,-1); | |
getrowstepsw(j,i,1,-1); | |
getrowstepsw(j,i,-1,1); | |
getrowstepsw(j,i,1,0); | |
getrowstepsw(j,i,-1,0); | |
getrowstepsw(j,i,0,1); | |
getrowstepsw(j,i,0,-1); | |
break; | |
case -fq: // | |
getrowstepsb(j,i,1,1); | |
getrowstepsb(j,i,-1,-1); | |
getrowstepsb(j,i,1,-1); | |
getrowstepsb(j,i,-1,1); | |
getrowstepsb(j,i,1,0); | |
getrowstepsb(j,i,-1,0); | |
getrowstepsb(j,i,0,1); | |
getrowstepsb(j,i,0,-1); | |
break; | |
case fk: // | |
getonestepw(j,i, 1,-1); | |
getonestepw(j,i, 1, 0); | |
getonestepw(j,i, 1, 1); | |
getonestepw(j,i, 0,-1); | |
getonestepw(j,i, 0, 1); | |
getonestepw(j,i,-1,-1); | |
getonestepw(j,i,-1, 0); | |
getonestepw(j,i,-1, 1); | |
if (!check_on_table) add_rok(j,i,nstep); | |
break; | |
case -fk: // | |
getonestepb(j,i, 1,-1); | |
getonestepb(j,i, 1, 0); | |
getonestepb(j,i, 1, 1); | |
getonestepb(j,i, 0,-1); | |
getonestepb(j,i, 0, 1); | |
getonestepb(j,i,-1,-1); | |
getonestepb(j,i,-1, 0); | |
getonestepb(j,i,-1, 1); | |
if (!check_on_table) add_rok(j,i,nstep); | |
break; | |
} //switch | |
} //if | |
if (nstep>cur_step) { | |
for (int i=start_var;i<start_var+cur_var;i++) { // | |
for (signed char j=0;j<MAXCUTS;j++) | |
if (cuts[j].fig1==steps[i].fig1&& | |
cuts[j].x1==steps[i].x1&&cuts[j].y1==steps[i].y1&& | |
cuts[j].x2==steps[i].x2&&cuts[j].y2==steps[i].y2) { | |
steps[i].weight+=100+cuts[j].weight; | |
break; | |
} | |
if (nstep>1&&steps[nstep-1].fig2!=0) // - | |
if (steps[nstep-1].x2==steps[i].x2&&steps[nstep-1].y2==steps[i].y2) | |
steps[i].weight+=1000; | |
} | |
} | |
sort_variants(start_var,start_var+cur_var-1); | |
} | |
//**************************** | |
void movestep(int nstep) { | |
pole[steps[nstep].x1][steps[nstep].y1]=0; | |
pole[steps[nstep].x2][steps[nstep].y2]=steps[nstep].fig1; | |
if (steps[nstep].fig1==fk) { | |
WKJ=steps[nstep].x2; WKI=steps[nstep].y2; | |
} else if (steps[nstep].fig1==-fk) { | |
BKJ=steps[nstep].x2; BKI=steps[nstep].y2; | |
} | |
if (steps[nstep].type==0) return; | |
if (steps[nstep].type==1) // | |
if (steps[nstep].fig1>0) | |
pole[steps[nstep].x2+1][steps[nstep].y2]=0; | |
else | |
pole[steps[nstep].x2-1][steps[nstep].y2]=0; | |
else if (steps[nstep].type==2) // | |
if (steps[nstep].fig1>0) { // | |
pole[7][4]=0; pole[7][5]=fr; pole[7][6]=fk; pole[7][7]=0; //show_board(); delay(3000); | |
} else { // | |
pole[0][4]=0; pole[0][5]=-fr; pole[0][6]=-fk; pole[0][7]=0; //show_board(); delay(3000); | |
} | |
else if (steps[nstep].type==3) // | |
if (steps[nstep].fig1>0) { // | |
pole[7][0]=0; pole[7][1]=0; pole[7][2]=fk; pole[7][3]=fr; pole[7][4]=0; | |
} else { // | |
pole[0][0]=0; pole[0][1]=0; pole[0][2]=-fk; pole[0][3]=-fr; pole[0][4]=0; | |
} | |
else if (steps[nstep].type>3) //-.... | |
if (steps[nstep].fig1>0) pole[steps[nstep].x2][steps[nstep].y2]=steps[nstep].type-2; | |
else pole[steps[nstep].x2][steps[nstep].y2]=2-steps[nstep].type; | |
} | |
//**************************** | |
void backstep(int nstep) { | |
pole[steps[nstep].x1][steps[nstep].y1]=steps[nstep].fig1; | |
pole[steps[nstep].x2][steps[nstep].y2]=steps[nstep].fig2; | |
if (steps[nstep].fig1==fk) { | |
WKJ=steps[nstep].x1; WKI=steps[nstep].y1; | |
} else if (steps[nstep].fig1==-fk) { | |
BKJ=steps[nstep].x1; BKI=steps[nstep].y1; | |
} | |
if (steps[nstep].type==0) return; | |
if (steps[nstep].type==1) { // | |
pole[steps[nstep].x2][steps[nstep].y2]=0; | |
if (steps[nstep].fig1>0) | |
pole[steps[nstep].x2+1][steps[nstep].y2]=-fp; | |
else | |
pole[steps[nstep].x2-1][steps[nstep].y2]=fp; | |
} else if (steps[nstep].type==2) // | |
if (steps[nstep].fig1>0) { // | |
pole[7][4]=fk; pole[7][5]=0; pole[7][6]=0; pole[7][7]=fr; | |
} else { // | |
pole[0][4]=-fk; pole[0][5]=0; pole[0][6]=0; pole[0][7]=-fr; // show_board(); delay(3000); | |
} | |
else if (steps[nstep].type==3) // | |
if (steps[nstep].fig1>0) { // | |
pole[7][0]=fr; pole[7][1]=0; pole[7][2]=0; pole[7][3]=0; pole[7][4]=fk; | |
} else { // | |
pole[0][0]=-fr; pole[0][1]=0; pole[0][2]=0; pole[0][3]=0; pole[0][4]=-fk; | |
} | |
} | |
//**************************** | |
void get_wrocks(int nstep) { | |
w00=true; w000=true; | |
for (int i=1;i<nstep;i++) { | |
if (steps[i].fig1==fk) { w00=false; w000=false; return; } | |
if (steps[i].fig1==fr) | |
if (steps[i].x1==7&&steps[i].y1==7) w00=false; | |
else if (steps[i].x1==7&&steps[i].y1==0) w000=false; | |
} | |
} | |
//**************************** | |
void get_brocks(int nstep) { | |
b00=true; b000=true; | |
for (int i=1;i<nstep;i++) { | |
if (steps[i].fig1==-fk) { b00=false; b000=false; return; } | |
if (steps[i].fig1==-fr) | |
if (steps[i].x1==0&&steps[i].y1==7) b00=false; | |
else if (steps[i].x1==0&&steps[i].y1==0) b000=false; | |
} | |
} | |
//**************************** | |
void add_rok(signed char j,signed char i,int nstep) { // | |
boolean che1,che2; | |
if (nstep%2==1) { // | |
if (j!=7||i!=4) return; | |
if (pole[7][5]==0&&pole[7][6]==0&&pole[7][7]==fr) { // | |
pole[7][4]=0; | |
WKI=5; che1=get_check(fk); | |
WKI=6; che2=get_check(fk); | |
WKI=4; pole[7][4]=fk; | |
get_wrocks(nstep); | |
if (!che1&&!che2&&w00) addstep(7,4,7,6,2); | |
} | |
if (pole[7][0]==fr&&pole[7][1]==0&&pole[7][2]==0&&pole[7][3]==0) { // | |
pole[7][4]=0; | |
WKI=2; che1=get_check(fk); | |
WKI=3; che2=get_check(fk); | |
WKI=4; pole[7][4]=fk; | |
get_wrocks(nstep); | |
if (!che1&&!che2&&w000) addstep(7,4,7,2,3); | |
} | |
} else { // | |
if (j!=0||i!=4) return; | |
if (pole[0][5]==0&&pole[0][6]==0&&pole[0][7]==-fr) { // | |
pole[0][4]=0; | |
BKI=5; che1=get_check(-fk); | |
BKI=6; che2=get_check(-fk); | |
BKI=4; pole[0][4]=-fk; | |
get_brocks(nstep); | |
if (!che1&&!che2&&b00) addstep(0,4,0,6,2); | |
} | |
if (pole[0][0]==-fr&&pole[0][1]==0&&pole[0][2]==0&&pole[0][3]==0) { // | |
pole[0][4]=0; | |
BKI=2; che1=get_check(-fk); | |
BKI=3; che2=get_check(-fk); | |
BKI=4; pole[0][4]=-fk; | |
get_brocks(nstep); | |
if (!che1&&!che2&&b000) addstep(0,4,0,2,3); | |
} | |
} | |
} | |
//**************************** | |
int addrowstepsw(signed char j,signed char i,signed char dj,signed char di,signed char dc) { // | |
signed char d,j1,i1; int c=0; | |
j1=j; i1=i; | |
for (d=1;d<8;d++) { | |
j1+=dj; i1+=di; | |
if (getpole(j1,i1)) { | |
if (pole[j1][i1]==0) c+=dc; | |
else if (pole[j1][i1]>0) { // | |
c+=1; break; | |
} else { | |
if (cur_step>6) c+=-pole[j1][i1]; // | |
break; | |
} | |
} else break; | |
} | |
return c; | |
} | |
//**************************** | |
int addrowstepsb(signed char j,signed char i,signed char dj,signed char di,signed char dc) { // | |
signed char d,j1,i1; int c=0; | |
j1=j; i1=i; | |
for (d=1;d<8;d++) { | |
j1+=dj; i1+=di; | |
if (getpole(j1,i1)) { | |
if (pole[j1][i1]==0) c-=dc; | |
else if (pole[j1][i1]<0) { // | |
c-=1; break; | |
} else { | |
if (cur_step>6) c-=pole[j1][i1]; // | |
break; | |
} | |
} else break; | |
} | |
return c; | |
} | |
//**************************** | |
int addonestepw(signed char j,signed char i,signed char dj,signed char di) { // | |
signed char j1,i1; | |
j1=j+dj; i1=i+di; | |
if (getpole(j1,i1)) | |
if (pole[j1][i1]==0) return 2; | |
else if (pole[j1][i1]>0) return 1; | |
else return -pole[j1][i1]; | |
return 0; | |
} | |
//**************************** | |
int addonestepb(signed char j,signed char i,signed char dj,signed char di) { // | |
signed char j1,i1; | |
j1=j+dj; i1=i+di; | |
if (getpole(j1,i1)) | |
if (pole[j1][i1]==0) return -2; | |
else if (pole[j1][i1]<0) return -1; | |
else return -pole[j1][i1]; | |
return 0; | |
} | |
//**************************** | |
int activity() { // - + | |
int c=0; | |
signed char pwj[8],pwi[8],pbj[8],pbi[8],ipw=0,ipb=0,nbw=0,nbb=0; | |
for (signed char i=0;i<8;i++) | |
for (signed char j=0;j<8;j++) | |
if (pole[j][i]!=0) { | |
switch (pole[j][i]) { | |
case fp: // | |
if (getpole(j,i+1)&&pole[j][i+1]==fp) c+=2; // | |
if (getpole(j-1,i)&&pole[j-1][i]==fp) c-=20; // | |
pwj[ipw]=j; pwi[ipw]=i; ipw++; | |
break; | |
case -fp: // | |
if (getpole(j,i-1)&&pole[j][i-1]==-fp) c-=2; // | |
if (getpole(j+1,i)&&pole[j+1][i]==-fp) c+=20; // | |
pbj[ipb]=j; pbi[ipb]=i; ipb++; | |
break; | |
case fn: // | |
c+=addonestepw(j,i,-2,-1); | |
c+=addonestepw(j,i,-2,1); | |
c+=addonestepw(j,i,-1,-2); | |
c+=addonestepw(j,i,-1,2); | |
c+=addonestepw(j,i,2,-1); | |
c+=addonestepw(j,i,2,1); | |
c+=addonestepw(j,i,1,-2); | |
c+=addonestepw(j,i,1,2); | |
break; | |
case -fn: // | |
c+=addonestepb(j,i,-2,-1); | |
c+=addonestepb(j,i,-2,1); | |
c+=addonestepb(j,i,-1,-2); | |
c+=addonestepb(j,i,-1,2); | |
c+=addonestepb(j,i,2,-1); | |
c+=addonestepb(j,i,2,1); | |
c+=addonestepb(j,i,1,-2); | |
c+=addonestepb(j,i,1,2); | |
break; | |
case fb: // | |
c+=addrowstepsw(j,i,1,1,2); //!! 1.4 | |
c+=addrowstepsw(j,i,-1,-1,3);//!! | |
c+=addrowstepsw(j,i,1,-1,2); //!! | |
c+=addrowstepsw(j,i,-1,1,3); //!! | |
nbw++; | |
break; | |
case -fb: // | |
c+=addrowstepsb(j,i,1,1,3); //!! 1.4 | |
c+=addrowstepsb(j,i,-1,-1,2);//!! | |
c+=addrowstepsb(j,i,1,-1,3); //!! | |
c+=addrowstepsb(j,i,-1,1,2); //!! | |
nbb++; | |
break; | |
case fr: // | |
c+=addrowstepsw(j,i,1,0,2); // | |
c+=addrowstepsw(j,i,-1,0,2); | |
c+=addrowstepsw(j,i,0,1,1); | |
c+=addrowstepsw(j,i,0,-1,1); | |
break; | |
case -fr: // | |
c+=addrowstepsb(j,i,1,0,2); // | |
c+=addrowstepsb(j,i,-1,0,2); | |
c+=addrowstepsb(j,i,0,1,1); | |
c+=addrowstepsb(j,i,0,-1,1); | |
break; | |
case fq: // | |
if (cur_step>10) { | |
c+=addrowstepsw(j,i,1,1,1); | |
c+=addrowstepsw(j,i,-1,-1,2); | |
c+=addrowstepsw(j,i,1,-1,1); | |
c+=addrowstepsw(j,i,-1,1,2); | |
c+=addrowstepsw(j,i,1,0,1); | |
c+=addrowstepsw(j,i,-1,0,2); | |
c+=addrowstepsw(j,i,0,1,1); | |
c+=addrowstepsw(j,i,0,-1,1); | |
} | |
break; | |
case -fq: // | |
if (cur_step>10) { | |
c+=addrowstepsb(j,i,1,1,2); | |
c+=addrowstepsb(j,i,-1,-1,1); | |
c+=addrowstepsb(j,i,1,-1,2); | |
c+=addrowstepsb(j,i,-1,1,1); | |
c+=addrowstepsb(j,i,1,0,2); | |
c+=addrowstepsb(j,i,-1,0,1); | |
c+=addrowstepsb(j,i,0,1,1); | |
c+=addrowstepsb(j,i,0,-1,1); | |
} | |
break; | |
} //switch | |
if (cur_step>6) { | |
if (pole[j][i]>0) { // | |
if (abs(WKJ-j)<2&&abs(WKI-i)<2) c+=3; | |
if (abs(BKJ-j)<2&&abs(BKI-i)<2) c+=3; | |
if (abs(WKJ-j)<3&&abs(WKI-i)<3) c+=2; | |
if (abs(BKJ-j)<3&&abs(BKI-i)<3) c+=2; | |
} else { // | |
if (abs(WKJ-j)<2&&abs(WKI-i)<2) c-=3; | |
if (abs(BKJ-j)<2&&abs(BKI-i)<2) c-=3; | |
if (abs(WKJ-j)<3&&abs(WKI-i)<3) c-=2; | |
if (abs(BKJ-j)<3&&abs(BKI-i)<3) c-=2; | |
} | |
} | |
} | |
if (nbw>1) c+=30; // | |
if (nbb>1) c-=30; | |
for (signed char w=0;w<ipw;w++) { // | |
boolean pass=1; | |
for (signed char b=0;b<ipb;b++) { | |
if (pwi[w]>0&&pbi[b]==pwi[w]-1&&pbj[b]<pwj[w]) pass=0; // | |
if (pbi[b]==pwi[w]&&pbj[b]<pwj[w]) pass=0; // | |
if ( pwi[w]<7&&pbi[b]==pwi[w]+1&&pbj[b]<pwj[w]) pass=0; // | |
if (!pass) break; | |
} | |
if (pass) { | |
c+=50; | |
if (!endspiel) break; // | |
} | |
} | |
for (signed char b=0;b<ipb;b++) { // | |
boolean pass=1; | |
for (signed char w=0;w<ipw;w++) { | |
if (pbi[b]>0&&pwi[w]==pbi[b]-1&&pwj[w]>pbj[b]) pass=0; // | |
if (pwi[w]==pbi[b]&&pwj[w]>pbj[b]) pass=0; // | |
if (pbi[b]<7&&pwi[w]==pbi[b]+1&&pwj[w]>pbj[b]) pass=0; // | |
if (!pass) break; | |
} | |
if (pass) { | |
c-=50; | |
if (!endspiel) break; // | |
} | |
} | |
return c; | |
} | |
//**************************** | |
int evaluate(int nstep) { // | |
long ww=0, wb=0; | |
for (signed char i=0;i<8;i++) | |
for (signed char j=0;j<8;j++) | |
if (pole[j][i]<0) { | |
wb+=fig_weight[-pole[j][i]]+(short)pgm_read_word(&pos[-pole[j][i]-1][7-j][i]); | |
} | |
else if (pole[j][i]>0) { | |
ww+=fig_weight[pole[j][i]]+(short)pgm_read_word(&pos[pole[j][i]-1][j][i]); | |
} | |
count++; // | |
long str=activity(); | |
if (endspiel) { // | |
wb+=(short)pgm_read_word(&pos[6][7-BKJ][BKI])-(short)pgm_read_word(&pos[5][7-BKJ][BKI]); | |
ww+=(short)pgm_read_word(&pos[6][WKJ][WKI])-(short)pgm_read_word(&pos[5][WKJ][WKI]); | |
if (wb<450&&ww>450) { // - - | |
str-=(abs(WKJ-BKJ)+abs(WKI-BKI))*30; | |
} else if (ww<450&&wb>450) { // | |
str+=(abs(WKJ-BKJ)+abs(WKI-BKI))*30; | |
} | |
} | |
if (nstep>8) { // | |
if (steps[nstep-1].fig1==steps[nstep-5].fig1&&steps[nstep-2].fig1==steps[nstep-6].fig1&& | |
steps[nstep-3].fig1==steps[nstep-7].fig1&&steps[nstep-4].fig1==steps[nstep-8].fig1) | |
if (steps[nstep-1].x1==steps[nstep-5].x1&&steps[nstep-2].x1==steps[nstep-6].x1&& | |
steps[nstep-3].x1==steps[nstep-7].x1&&steps[nstep-4].x1==steps[nstep-8].x1) | |
if (steps[nstep-1].x2==steps[nstep-5].x2&&steps[nstep-2].x2==steps[nstep-6].x2&& | |
steps[nstep-3].x2==steps[nstep-7].x2&&steps[nstep-4].x2==steps[nstep-8].x2) | |
if (steps[nstep-1].y1==steps[nstep-5].y1&&steps[nstep-2].y1==steps[nstep-6].y1&& | |
steps[nstep-3].y1==steps[nstep-7].y1&&steps[nstep-4].y1==steps[nstep-8].x1) | |
if (steps[nstep-1].y2==steps[nstep-5].y2&&steps[nstep-2].y2==steps[nstep-6].y2&& | |
steps[nstep-3].y2==steps[nstep-7].y2&&steps[nstep-4].y2==steps[nstep-8].y2) | |
{ | |
//Serial.println(F(" Draw - 3 repeat")); | |
return 0; | |
} | |
} | |
if (nstep%2==1) return 5000*(ww-wb)/(ww+wb+2000)+str; else return 5000*(wb-ww)/(ww+wb+2000)-str; | |
} | |
//**************************** | |
void add_cut(int ind) {// ind | |
int minbeta=30000, minindex=MAXCUTS-1; | |
for (signed char i=0;i<MAXCUTS;i++) { | |
if (cuts[i].weight==0) { minindex=i; break; }// | |
if (cuts[i].fig1==steps[ind].fig1&& | |
cuts[i].x1==steps[ind].x1&&cuts[i].y1==steps[ind].y1&& | |
cuts[i].x2==steps[ind].x2&&cuts[i].y2==steps[ind].y2) { | |
cuts[i].weight++; return; // - 1 | |
} | |
if (cuts[i].weight<minbeta) { // | |
minbeta=cuts[i].weight; | |
minindex=i; | |
} | |
} | |
cuts[minindex]=steps[ind]; | |
cuts[minindex].weight=1; //1 | |
} | |
//**************************** | |
int quiescence(int start, int nstep, int alpha, int beta ) { | |
if (nstep-cur_step>=LIMDEPTH||start>MAXSTEPS-100) return evaluate(nstep); | |
if (!solving&&progress==0) return -5000; | |
int score=-20000; | |
start_var=start; | |
only_action=true; | |
load_variants(nstep); | |
if (!check_on_table) { | |
int stand_pat = evaluate(nstep); | |
if (stand_pat >= score) score=stand_pat; | |
if (score>alpha) alpha=score; | |
if (alpha>=beta&&isbeta) return alpha; | |
} | |
if (cur_var==0) { | |
if (check_on_table) { | |
if (TRACE) Serial.println(F("checkmate?")); | |
return -10000+nstep-cur_step; | |
} else return evaluate(nstep); | |
} | |
int j=start+cur_var; | |
for (int i=start;i<j;i++) { // | |
if (TRACE) { //***** | |
for (int u=0;u<nstep-cur_step;u++) Serial.print(F(" . ")); | |
Serial.println(str_step(i)); | |
} | |
movestep(i); | |
steps[nstep]=steps[i]; | |
int tmp=-quiescence(j+1,nstep+1,-beta,-alpha); | |
backstep(i); | |
if (tmp>score) score=tmp; | |
if (score>alpha) alpha=score; | |
if (alpha>=beta&&isbeta) { | |
add_cut(nstep); | |
return alpha; | |
} | |
gui(); | |
} | |
return score; | |
} | |
//**************************** | |
int alphaBeta(int start, int nstep, int alpha, int beta, int depthleft) { | |
//start - | |
//nstep - | |
int score=-20000,best; | |
if( depthleft==0) return quiescence(start,nstep,alpha,beta) ; | |
if (start>MAXSTEPS-100) return evaluate(nstep); | |
start_var=start; | |
only_action=false; | |
if (nstep!=cur_step) load_variants(nstep); | |
if (cur_var==0) { | |
if (check_on_table) { | |
if (TRACE) Serial.println(F("checkmate!")); | |
return -10000+nstep-cur_step; | |
} | |
return 0; | |
} | |
int j=start+cur_var; | |
best=start; | |
for (int i=start;i<j;i++) { // | |
if (nstep==cur_step) { | |
if (!hidden) { | |
Serial.print(str_step(i)); Serial.print(" "); | |
Serial.print(i-start+1); Serial.print("/"); Serial.print(j-start); | |
} | |
if (steps[i].weight<-9000) { Serial.println(F(" checkmate")); continue; } | |
if (steps[i].fig2!=0||steps[i].check||(alpha<-100&&isbeta)) | |
// , , -100 | |
{ LIMDEPTH=MAXDEPTH+2; if (!hidden) Serial.print(F("+2")); } else LIMDEPTH=MAXDEPTH; | |
} else { | |
if (TRACE) { //***** | |
for (int u=0;u<nstep-cur_step;u++) Serial.print(F(" ")); | |
Serial.println(str_step(i)); | |
} | |
} | |
movestep(i); | |
steps[nstep]=steps[i]; | |
int tmp=-alphaBeta(j+1,nstep+1,-beta,-alpha,depthleft-1); | |
backstep(i); | |
steps[i].weight=tmp; | |
if (tmp>score) score=tmp; | |
if (score>alpha) { | |
alpha=score; | |
if (nstep>cur_step) add_cut(nstep); // | |
if (TRACE) { Serial.print(F("ALPHA+:")); Serial.println(score); } | |
best=i; | |
if (nstep==cur_step) { | |
steps[0]=steps[best]; | |
if (!hidden) Serial.print(F(" BEST")); | |
} | |
} | |
if (alpha>=beta&&isbeta) { | |
if (nstep>cur_step) add_cut(nstep); // | |
if (TRACE) { Serial.print(F("BETA CUT:")); Serial.println(score); } | |
return alpha; | |
} | |
if (nstep==cur_step) { | |
if (!hidden) { Serial.print(F(" ")); Serial.println(tmp); } | |
progress=100*(i-start+1)/(j-start); | |
if (alpha==9999||alpha==-5000) break; | |
if (!solving) { | |
if (alpha>startweight&&cur_level>2) break; | |
else { // - +50% | |
if (cur_level>1&&100*(millis()-starttime)/(limittime-starttime)>240-limit*20) break; | |
} | |
} | |
} | |
if (nstep==cur_step+1&&!solving&&progress==0) break; | |
gui(); | |
} | |
if (nstep==cur_step) { steps[nstep]=steps[best]; steps[0]=steps[best]; } | |
return score; | |
} | |
//**************************** | |
void kingpositions() { | |
for (signed char i=0;i<8;i++) // | |
for (signed char j=0;j<8;j++) | |
if (pole[j][i]==fk) { | |
WKJ=j; WKI=i; | |
} else if (pole[j][i]==-fk) { | |
BKJ=j; BKI=i; | |
} | |
} | |
//**************************** | |
int get_endspiel() { // | |
int weight=0; | |
for (signed char i=0;i<8;i++) | |
for (signed char j=0;j<8;j++) | |
if (pole[j][i]<0) | |
weight+=fig_weight[-pole[j][i]]; | |
else if (pole[j][i]>0) | |
weight+=fig_weight[pole[j][i]]; // 8000 | |
if (weight<3500) endspiel=true; else endspiel=false; | |
return weight; | |
} | |
//**************************** | |
boolean is_drawn() { // | |
boolean drawn=false; | |
int cn=0,cbw=0,cbb=0,co=0,cb=0,cw=0; | |
for (signed char i=0;i<8;i++) | |
for (signed char j=0;j<8;j++) { | |
if (abs(pole[j][i])==1) co++; | |
if (abs(pole[j][i])>3&&abs(pole[j][i])<6) co++; // , , | |
if (abs(pole[j][i])==6) continue; // | |
if (abs(pole[j][i])==2) cn++; // | |
if (abs(pole[j][i])==3&&(i+j+2)%2==0) cbb++; // | |
if (abs(pole[j][i])==3&&(i+j+2)%2==1) cbw++; // | |
if (pole[j][i]==3) cw++; // | |
if (pole[j][i]==-3) cb++; // | |
} | |
if (cn==1&&co+cbb+cbw==0) drawn=true; // | |
if (cbb+cbw==1&&co+cn==0) drawn=true; // | |
if (co+cn+cbb==0||co+cn+cbw==0) drawn=true; // | |
if (co+cn==0&&cb==1&&cw==1) drawn=true; // | |
if (drawn) return drawn; | |
int rep=1; | |
for (int s=cur_step-1; s>0; s--) { | |
if (steps[s].fig1==0) continue; | |
backstep(s); | |
boolean eq=true; | |
for (signed char i=0;i<8;i++) | |
for (signed char j=0;j<8;j++) | |
if (pole[j][i]!=pole0[j][i]) | |
{ eq=false; break; } | |
if (eq) rep++; | |
if (rep>2) break; | |
} | |
if (rep>1) { Serial.print(rep); Serial.println(" repetitions"); } | |
for (signed char i=0;i<8;i++) | |
for (signed char j=0;j<8;j++) pole[j][i]=pole0[j][i]; // | |
if (rep>2) drawn=true; | |
return drawn; | |
} | |
//**************************** | |
int solve_step() { | |
const int LMIN[6]={2,3,4,5,6,7}; | |
const int LMAX[6]={4,6,8,10,12,14}; | |
boolean check_on; | |
if (!hidden) { | |
GO.lcd.fillRect(240,166,80,20,CBLACK); | |
GO.lcd.drawFastHLine(10,237,220,CDARK); | |
} | |
starttime=millis(); | |
isstatus=1; | |
limittime=starttime+limits[limit]*1000; // | |
for (signed char i=0;i<8;i++) | |
for (signed char j=0;j<8;j++) pole0[j][i]=pole[j][i]; // | |
isbeta=true; | |
if (hidden) isbeta=false; | |
else if (cur_step<5) { // FEN | |
isbeta=false; | |
for (int i=cur_step-1;i>0;i--) | |
if (steps[i].fig1!=0) backstep(i); | |
for (signed char i=0;i<8;i++) | |
for (signed char j=0;j<8;j++) | |
if (polestart[j][i]!=pole[j][i]) { isbeta=true; break; } | |
for (signed char i=0;i<8;i++) | |
for (signed char j=0;j<8;j++) pole[j][i]=pole0[j][i]; // | |
} | |
Serial.print("isbeta="); Serial.println(isbeta); | |
lastbest.fig1=0; | |
kingpositions(); | |
int wei=get_endspiel(); | |
count=0; | |
startweight=evaluate(cur_step); | |
if (!hidden) { | |
Serial.println(""); | |
Serial.println(F("---------------")); | |
if (endspiel) { Serial.print(F("Endspiel: ")); Serial.println(wei); } | |
if (cur_step%2==1) Serial.print(F("WHITE, ")); else Serial.print(F("BLACK, ")); | |
Serial.print(F("start Score= ")); Serial.println(startweight); | |
} | |
start_var=cur_step+21; | |
only_action=false; | |
lastbest.fig1=0; | |
steps[0].fig1=0; | |
load_variants(cur_step); | |
check_on=check_on_table; | |
if (cur_var==0||is_drawn()) { | |
beep(500); | |
GO.lcd.drawFastHLine(10,237,220,CBLACK); | |
GO.lcd.drawFastHLine(10,239,220,CBLACK); | |
isstatus=0; | |
solving=false; | |
if (check_on_table) return -9999; else return 8999; | |
} | |
if (cur_var==1) { // 1 | |
GO.lcd.drawFastHLine(10,237,220,CBLACK); | |
GO.lcd.drawFastHLine(10,239,220,CBLACK); | |
isstatus=0; | |
solving=false; | |
steps[cur_step]=steps[cur_step+21]; | |
return startweight; | |
} | |
int vars=cur_var; | |
int ALPHA=-20000; | |
int BETA=20000; | |
int score; | |
solving=true; | |
int l=0; | |
for (signed char i=0;i<MAXCUTS;i++) { cuts[i].weight=0; cuts[i].fig1=0; } // | |
for (int i=cur_step+21;i<cur_step+21+vars;i++) { // | |
movestep(i); | |
steps[i].weight=evaluate(cur_step); | |
if (steps[i].fig2!=0) steps[i].weight-=steps[i].fig1; | |
backstep(i); | |
} | |
while (l<6) { | |
cur_level=l+1; | |
progress=0; | |
GO.lcd.drawFastHLine(10,239,220,CDARK); | |
MINDEPTH=LMIN[l]; | |
MAXDEPTH=LMAX[l]; | |
if (!hidden) { | |
if (l>0) Serial.println(""); Serial.print(F("******* LEVEL=")); Serial.print(l+1); | |
Serial.print(" "); Serial.print(MINDEPTH); Serial.print("-"); Serial.print(MAXDEPTH); | |
Serial.print(" "); Serial.print((millis()-starttime)/1000.,1); Serial.println("s"); | |
} | |
sort_variants(cur_step+21,cur_step+20+vars); // | |
cur_var=vars; | |
check_on_table=check_on; | |
for (int i=cur_step+21;i<cur_step+21+vars;i++) steps[i].weight=-8000; //// | |
score=alphaBeta(cur_step+21,cur_step,ALPHA,BETA,MINDEPTH); | |
if (score>9996) break; | |
if (score>9000&&limit<2) break; | |
if (100*(millis()-starttime)/(limittime-starttime)>75-l*8) break; | |
if (!solving||!isbeta||hidden) break; | |
//if (hidden||cur_step<5) break; | |
l++; | |
} //while l | |
if (score<-9000) { | |
if (!hidden) Serial.println(F("GIVE UP!")); | |
} else { | |
int ran=random(5,10); //// | |
while (ran>0&&cur_step<5&&!isbeta) { | |
for (int i=cur_step+21;i<cur_step+21+vars;i++) | |
if (steps[i].weight>=score-10) { | |
ran--; | |
if (ran==0) { | |
if (millis()%2==1) | |
if (steps[cur_step].x1!=steps[i].x1||steps[cur_step].x2!=steps[i].x2|| | |
steps[cur_step].y1!=steps[i].y1||steps[cur_step].y2!=steps[i].y2) { | |
steps[cur_step]=steps[i]; | |
if (!hidden) Serial.println(F("Best step replaced!")); | |
break; | |
} | |
} | |
} | |
} //// | |
if (!hidden) { Serial.print(F("STEP=")); Serial.println(str_step(cur_step)); } | |
if (score>9000) { | |
if (!hidden) Serial.print(F("CHECKMATE ")); | |
if (score<9999) { | |
if (!hidden) {Serial.print(F("in ")); Serial.print((9999-score)/2+1); Serial.print(F(" steps")); } | |
} else steps[cur_step].check=2; | |
if (!hidden) Serial.println(""); | |
} | |
} | |
GO.lcd.drawFastHLine(10,237,220,CBLACK); | |
GO.lcd.drawFastHLine(10,239,220,CBLACK); | |
progress=0; | |
solving=0; | |
isstatus=0; | |
endtime=millis(); | |
return score; | |
} | |
//**************************** |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment