Skip to content

Instantly share code, notes, and snippets.

@devatnull
Forked from 9nut/megachess_odroidgo.ino
Created November 6, 2022 19:35
Show Gist options
  • Save devatnull/39f3b36513943d0eb39c6f382f189e01 to your computer and use it in GitHub Desktop.
Save devatnull/39f3b36513943d0eb39c6f382f189e01 to your computer and use it in GitHub Desktop.
FIXED Megachess M5stack adapted to ODROID GO
//ArduinoMega Chess 1.0 M5Stack
//engine 1.4
//Sergey Urusov, ususovsv@gmail.com
//
// 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("urusovsv@gmail.com");
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