Sergey_Urusov
Published © GPL3+

Arduino Mega Chess

Chess processor with GUI dedicated for Arduino Mega.

IntermediateShowcase (no instructions)84,272
Arduino Mega Chess

Things used in this project

Hardware components

Arduino Mega 2560
Arduino Mega 2560
×1
2.8" TFT LCD Touch Screen Expansion Shield w/ Touch Pen for Arduino
×1
Buzzer
Buzzer
×1
Resistor 100 ohm
Resistor 100 ohm
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Schematics

Buzzer connection scheme

About schematic - display with touchscreen just plugged into arduino slot. Buzzer connected to the digital pin d44 with its plus clemme, and opposite to the ground through 100 Om resistor.

Code

ArduinoMega Chess 1.0

Arduino
//ArduinoMega Chess 1.0
//Sergey Urusov, ususovsv@gmail.com

#include <Adafruit_TFTLCD.h> 
#include <stdint.h>
#include "TouchScreen.h"
#include <avr/pgmspace.h>
#include <EEPROM.h> 


uint16_t BLACK,BLUE,RED,GREEN,CYAN,MAGENTA,YELLOW,WHITE,GRAY,DARK,GRAY2,BLACKF,WHITEF;
Adafruit_TFTLCD tft;
#define YP A1  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 7   // can be a digital pin
#define XP 6   // can be a digital pin
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 350);
int touchx,touchy,touchx0,touchy0,ntouch;         
unsigned long lasttouch;
#define MINPRESSURE 10
#define MAXPRESSURE 1000
const int PinBuzz = 44;
int cycle=0; // 
const char fp=1;
const char fn=2;
const char fb=3;
const char fr=4;
const char fq=5;
const 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 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 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},
             };  
             
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},
             };  
             
char pole0[8][8];  //   
char poledisp[8][8]; // 
char polechoice[7]; // 
boolean w00,w000,b00,b000;             
char blinkstep;
typedef struct {
  char fig1, fig2; //    
  char x1,y1,x2,y2; //     
  char check; //  
  char type; //  1-  ,2- ,3- ,4-5-6-7-  ,,,
  int weight; // , 
} step_type;
const int MAXSTEPS=500; //.      
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
int MINDEPTH; //.   
int MAXDEPTH; //.   
int LIMDEPTH; //.       
const char MAXCUTS=10; //.. -  - (10-  ,  20)
boolean TRACE=0;
boolean checkmatesearch=0; //   
boolean solving=false;
boolean choice=false;
boolean sound=0;
int cur_step=1; //  , 1....
int limit=0; //  , 0-6;
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
const long limits[7]={10,30,60,180,600,1800,100000};
//                     0  1  2   3   4    5      6 
step_type steps[MAXSTEPS]; //  
step_type cuts[MAXCUTS]; //  -
step_type lastbest;
int lastscore;
int minbeta,maxalpha;
int startweight;
int cur_level; //   ()
int start_var; //   , 1....
int cur_var; //  , 1....
int cur_choice; //   
boolean check_on_table; //  
boolean isstatus;
char WKJ=0,WKI=0,BKJ=0,BKI=0; // 
boolean endspiel=false; // 
char progress; //   0-100
boolean only_action=false; // -  
unsigned long starttime,limittime,quitime=0;             
boolean drag;
const uint8_t fig[6][32] PROGMEM={
{0x0, 0x0,  0x0,  0x0,  0x0,  0x0,  0x3,  0xC0, 0x7,  0xE0, 0x7,  0xE0, 0x3,  0xC0, 0x3,  0xC0,
0x7,  0xE0, 0x3,  0xC0, 0x3,  0xC0, 0x7,  0xE0, 0xF,  0xF0, 0xF,  0xF0, 0xF,  0xF0, 0x0,  0x0}, //
{0x0, 0x0,  0x3,  0x40, 0x7,  0xE0, 0xF,  0xF0, 0x1F, 0xF8, 0x3F, 0xFC, 0x39, 0xFC, 0x33, 0xFC,
0x7,  0xFC, 0xF,  0xF8, 0xF,  0xF0, 0x7,  0xE0, 0x3,  0xC0, 0x7,  0xE0, 0x1F, 0xF8, 0x0,  0x0},  //
{0x1, 0x80, 0x3,  0xC0, 0x1,  0x80, 0xF,  0xF0, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8,
0x1F, 0xF8, 0x1F, 0xF8, 0xF,  0xF0, 0x7,  0xE0, 0x3,  0xC0, 0x31, 0x8C, 0x7F, 0xFE, 0x0,  0x0}, // 
{0x0, 0x0,  0x19, 0x98, 0x1F, 0xF8, 0xF,  0xF0, 0xF,  0xF0, 0xF,  0xF0, 0xF,  0xF0, 0xF,  0xF0,
0xF,  0xF0, 0xF,  0xF0, 0xF,  0xF0, 0xF,  0xF0, 0xF,  0xF0, 0x1F, 0xF8, 0x1F, 0xF8, 0x0,  0x0}, //
{0x19, 0x98, 0xD9, 0x9B, 0xD9, 0x9B, 0xD9, 0x9B, 0x6D, 0xB6, 0x6D, 0xB6, 0x6D, 0xB6, 0x35, 0xAC,
0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x1F, 0xF8, 0xF,  0xF0, 0xF,  0xF0, 0x1F, 0xF8, 0x0,  0x0}, //
{0x1, 0x80, 0x1,  0x80, 0x79, 0x9E, 0x7D, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x7F, 0xFE, 0x3F, 0xFC, 0x3F, 0xFC, 0x1F, 0xF8, 0xF,  0xF0, 0xF,  0xF0, 0x1F, 0xF8, 0x0,  0x0}  //
};
const uint8_t fig_cont[6][32] PROGMEM={
{0x0, 0x0,  0x0,  0x0,  0x3,  0xC0, 0x4,  0x20, 0x8,  0x10, 0x8,  0x10, 0x4,  0x20, 0x4,  0x20,
0x8,  0x10, 0x4,  0x20, 0x4,  0x20, 0x8,  0x10, 0x10, 0x8,  0x10, 0x8,  0x10, 0x8,  0x1F, 0xF8}, //
{0x3, 0x40, 0x4,  0xA0, 0x8,  0x10, 0x12, 0x8,  0x20, 0x4,  0x40, 0x2,  0x46, 0x2,  0x4C, 0x2,
0x38, 0x2,  0x10, 0x4,  0x10, 0x8,  0x8,  0x10, 0x4,  0x20, 0x18, 0x18, 0x20, 0x4,  0x3F, 0xFC},  //
{0x2, 0x40, 0x4,  0x20, 0x6,  0x60, 0x10, 0x8,  0x21, 0x84, 0x21, 0x84, 0x21, 0x84, 0x27, 0xE4,
0x21, 0x84, 0x21, 0x84, 0x11, 0x88, 0x8,  0x10, 0x34, 0x2C, 0x4E, 0x72, 0x80, 0x1,  0xFF, 0xFF}, // 
{0x39, 0x9C, 0x26, 0x64, 0x20, 0x4,  0x1F, 0xF8, 0x10, 0x8,  0x10, 0x8,  0x10, 0x8,  0x10, 0x8,
0x10, 0x8,  0x10, 0x8,  0x10, 0x8,  0x10, 0x8,  0x1F, 0xF8, 0x20, 0x4,  0x20, 0x4,  0x3F, 0xFC}, //
{0x22, 0x24, 0x22, 0x24, 0x22, 0x24, 0x26, 0x64, 0x92, 0x49, 0x92, 0x49, 0x92, 0x49, 0x4A, 0x52,
0x40, 0x2,  0x40, 0x2,  0x5F, 0xFA, 0x20, 0x4,  0x1F, 0xF8, 0x10, 0x8,  0x20, 0x4,  0x3F, 0xFC}, //
{0x2, 0x40, 0x7A, 0x5E, 0x86, 0x61, 0x82, 0x41, 0x2,  0x40, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80,
0x80, 0x81, 0x41, 0x82, 0x5F, 0xFA, 0x20, 0x4,  0x1F, 0xF8, 0x10, 0x8,  0x20, 0x4,  0x3F, 0xFC}  //
};

const uint8_t issound[2][32] PROGMEM={
{0x0, 0x0,  0x0,  0x0,  0x0,  0x32, 0x0,  0x54, 0x0,  0x98, 0x1F, 0x10, 0x10, 0x30, 0x10, 0x50,
0x10, 0x90, 0x11, 0x10, 0x1F, 0x10, 0x4,  0x90, 0x8,  0x50, 0x10, 0x30, 0x0,  0x0,  0x0,  0x0},
{0x0, 0x0,  0x0,  0x0,  0x0,  0x30, 0x0,  0x50, 0x0,  0x90, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x1F, 0x10, 0x0,  0x90, 0x0,  0x50, 0x0,  0x30, 0x0,  0x0,  0x0,  0x0}
};
const uint8_t iswb[2][32] PROGMEM={
{0x0,  0x0,  0x0,  0x0,  0x3,  0xC0, 0x4,  0x20, 0x8,  0x10, 0x8,  0x10, 0x4,  0x20, 0x4,  0x20,
0x8,  0x10, 0x4,  0x20, 0x4,  0x20, 0x8,  0x10, 0x10, 0x8,  0x10, 0x8,  0x1F, 0xF8, 0x0,  0x0},
{0x0,  0x0,  0x0,  0x0,  0x3,  0xC0, 0x7,  0xE0, 0xF,  0xF0, 0xF,  0xF0, 0x7,  0xE0, 0x7,  0xE0,
0xF,  0xF0, 0x7,  0xE0, 0x7,  0xE0, 0xF,  0xF0, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x0,  0x0}
};
const uint8_t iscm[2][32] PROGMEM={
{0x0, 0x0,  0x7,  0xE0, 0xC,  0x30, 0xC,  0x30, 0xC,  0x30, 0xC,  0x30, 0x0,  0x30, 0x0,  0x60,
0x0,  0xC0, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x0,  0x0,  0x1,  0x80, 0x1,  0x80, 0x0,  0x0},
{0x0,  0x0,  0x3F, 0x0,  0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x1,  0x80, 0x3,  0x0,
0x6,  0x24, 0xC,  0x24, 0xC,  0xFF, 0xC,  0x24, 0x0,  0xFF, 0xC,  0x24, 0xC,  0x24, 0x0,  0x0}
};
const uint8_t islimit[7][32] PROGMEM={
{0x0, 0x0,  0x4,  0x70, 0xC,  0x88, 0x4,  0x88, 0x4,  0x88, 0x4,  0x88, 0x4,  0x88, 0x4,  0x88,
0xE,  0x70, 0x0,  0x0,  0x1D, 0xDC, 0x11, 0x10, 0x1D, 0xD0, 0x5,  0x10, 0x1D, 0xDC, 0x0,  0x0},
{0x0, 0x0,  0xC,  0x70, 0x12, 0x88, 0x2,  0x88, 0xC,  0x88, 0x2,  0x88, 0x2,  0x88, 0x12, 0x88,
0xC,  0x70, 0x0,  0x0,  0x1D, 0xDC, 0x11, 0x10, 0x1D, 0xD0, 0x5,  0x10, 0x1D, 0xDC, 0x0,  0x0},
{0x0, 0x0,  0x1,  0x80, 0x3,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80,
0x3,  0xC0, 0x0,  0x0,  0x22, 0xA4, 0x36, 0xA4, 0x2A, 0xB4, 0x22, 0xAC, 0x22, 0xA4, 0x0,  0x0},
{0x0, 0x0,  0x3,  0xC0, 0x6,  0x60, 0x0,  0x60, 0x1,  0xC0, 0x0,  0x60, 0x6,  0x60, 0x6,  0x60,
0x3,  0xC0, 0x0,  0x0,  0x22, 0xA4, 0x36, 0xA4, 0x2A, 0xB4, 0x22, 0xAC, 0x22, 0xA4, 0x0,  0x0},
{0x0, 0x0,  0xC,  0x78, 0x1C, 0xCC, 0xC,  0xCC, 0xC,  0xCC, 0xC,  0xCC, 0xC,  0xCC, 0xC,  0xCC,
0x1E, 0x78, 0x0,  0x0,  0x22, 0xA4, 0x36, 0xA4, 0x2A, 0xB4, 0x22, 0xAC, 0x22, 0xA4, 0x0,  0x0},
{0x0, 0x0,  0x1C, 0x78, 0x36, 0xCC, 0x6,  0xCC, 0x1C, 0xCC, 0x6,  0xCC, 0x36, 0xCC, 0x36, 0xCC,
0x1C, 0x78, 0x0,  0x0,  0x22, 0xA4, 0x36, 0xA4, 0x2A, 0xB4, 0x22, 0xAC, 0x22, 0xA4, 0x0,  0x0},
{0x0, 0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x3C, 0x3C, 0x7E, 0x7E, 0x63, 0xC6, 0x61, 0x86,
0x63, 0xC6, 0x66, 0x66, 0x3C, 0x3C, 0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0}
};
const uint8_t isdesc[2][32] PROGMEM={
{0x0,  0x0,  0xE3, 0x8E, 0xE3, 0x8E, 0xE3, 0x8E, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0xE3, 0x8E,
0xE3, 0x8E, 0xE3, 0x8E, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0xE3, 0x8E, 0xE3, 0x8E, 0xE3, 0x8E},
{0x0,  0x0,  0x0,  0x4,  0x0,  0xE,  0x0,  0xE,  0x0,  0x1C, 0x0,  0x1C, 0x0,  0x38, 0x0,  0x30,
0x30, 0x70, 0x78, 0xE0, 0x3C, 0xC0, 0x1F, 0xC0, 0xF,  0x80, 0x7,  0x0,  0x2,  0x0,  0x0,  0x0}

};
const uint8_t isback[32] PROGMEM={
0x0,  0x0,  0x0,  0x0,  0x20, 0xF0, 0x31, 0xF8, 0x3B, 0xFC, 0x3F, 0x8E, 0x3F, 0xE,  0x3F, 0xE,
0x3F, 0x8E, 0x3F, 0xCE, 0x0,  0xE,  0x0,  0xE,  0x0,  0x1C, 0x0,  0x38, 0x0,  0x70, 0x0,  0x0
};
const uint8_t issave[32] PROGMEM={
0x1,  0x80, 0x3,  0xC0, 0x7,  0xE0, 0x7,  0xE0, 0x3,  0xC0, 0x3F, 0xFC, 0x23, 0xC4, 0x23, 0xC4,
0x23, 0xC4, 0x23, 0xC4, 0x23, 0xC4, 0x23, 0xC4, 0x20, 0x4,  0x20, 0x4,  0x3F, 0xFC, 0x0,  0x0
};
const uint8_t isload[32] PROGMEM={
0x0,  0x0,  0x3,  0xC0, 0x3,  0xC0, 0x3,  0xC0, 0x3,  0xC0, 0x3F, 0xFC, 0x23, 0xC4, 0x23, 0xC4,
0x23, 0xC4, 0x27, 0xE4, 0x27, 0xE4, 0x23, 0xC4, 0x21, 0x84, 0x20, 0x4,  0x3F, 0xFC, 0x0,  0x0
};
const uint8_t isempty[32] PROGMEM={
0xFF,  0xFF, 0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,
0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0xFF, 0xFF
};
const uint8_t isinit[32] PROGMEM={
0xFF,  0xFF, 0x80, 0x1,  0x80, 0x1,  0xFF, 0xFF, 0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,
0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
const uint8_t isplay[32] PROGMEM={
0x0,  0x0,  0x3,  0xC0, 0x3,  0xC0, 0x3,  0xC0, 0x1,  0x80, 0x23, 0xF8, 0x17, 0xC8, 0xB,  0xC8,
0x3,  0xC0, 0x3,  0xC0, 0x2,  0x40, 0x4,  0x40, 0x4,  0x38, 0x4,  0x8,  0xC,  0x0,  0x0,  0x0
};
const uint8_t isrotate[2][32] PROGMEM={
{0x0,  0x0,  0x0,  0x0,  0x3F, 0xFC, 0x20, 0x4,  0x20, 0x4,  0x20, 0x4,  0x20, 0x4,  0x20, 0x4,
0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x0,  0x0,  0x0,  0x0},
{0x0, 0x0,  0x0,  0x0,  0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC,
0x20, 0x4,  0x20, 0x4,  0x20, 0x4,  0x20, 0x4,  0x20, 0x4,  0x3F, 0xFC, 0x0,  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}}  
};

//******
class Button {
public:
int bx,by,bw,bh,bshift;
String bs;
const uint8_t* bp;
 Button(int x,int y,int w,int h,String s,const uint8_t* p, int shift);
 void Show(int shift); 
 void Show(String s); 
 void Hide();
 boolean IsPressed(int xc, int yc);
private:
boolean active;
 void ishow(uint16_t textcolor,uint16_t backcolor);
};
Button::Button(int x,int y,int w,int h,String s,const uint8_t* p=NULL, int shift=0) {
  bx=x; by=y; bw=w; bh=h; bs=s; bp=p; bshift=shift;
};
void Button::Show(int shift=0) {
 bshift=shift; 
 active=true;
 ishow(WHITE,DARK);  
};
void Button::Show(String s) {
 bs=s; 
 active=true;
 ishow(WHITE,DARK);  
};
void Button::Hide() { 
 active=false; 
 ishow(GRAY,DARK);  
};
boolean Button::IsPressed(int xc, int yc) {
  if (active&&abs(bx+bw/2-xc)<bw/2&&abs(by+bh/2-yc)<bh/2) {
    ishow(WHITE,GRAY); 
    touchx=0; touchy=0;        
    return true;
  } 
  return false;
};  
void Button::ishow(uint16_t textcolor,uint16_t backcolor) {  
  tft.fillRoundRect(bx+2,by+2,bw,bh,3,GRAY2);               
  tft.fillRoundRect(bx,by,bw,bh,3,backcolor);               
  tft.setTextColor(textcolor);
  tft.setTextSize(1);    
  tft.setCursor(bx+(bw-bs.length()*6)/2,by+(bh-8)/2);       
  if (bp!=NULL) { 
   tft.drawBitmap(1+bx+(bw-16)/2, by+(bh-16)/2, bp+bshift*32, 16, 16,textcolor);          
  } 
  else  tft.print(bs);    
}
Button BAction(65, 216, 55, 20, "START");
Button BBW(125, 216, 22, 20, "",&iswb[0][0]);
Button BBack(152, 216, 23, 20, "",&isback[0]);
Button BInit(152, 216, 23, 20, "",&isinit[0]);
Button BLimit(180, 216, 23, 20, "",&islimit[0][0]);
Button BEmpty(180, 216, 23, 20, "",&isempty[0]);
Button BRotate(208, 216, 23, 20, "",&isrotate[0][0]);
Button BPlay(208, 216, 23, 20, "",&isplay[0]);
Button BCM(236, 216, 23, 20, "",&iscm[0][0]);
Button BSave(236, 216, 23, 20, "",&issave[0]);
Button BDesc(264, 216, 23, 20, "",&isdesc[0][0]);
Button BSound(292, 216, 23, 20, "",&issound[0][0]);
Button BLoad(292, 216, 23, 20, "",&isload[0]);
//******
//********************************** 
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))) {
        tft.drawPixel(x+i, y+j, color);
      }      
    }
  }
}
//****************************
void deletebuttons() {
  tft.fillRect(0,215,320,30,BLACK);               
}

//****************************
void clearstatus() {
  tft.fillRect(0,210,60,30,BLACK);             
  tft.drawFastHLine(5,210,200,BLACK);   
  tft.drawFastHLine(5,212,200,BLACK);  
}  
//****************************
void setup() {      
  Serial.begin(57600);  
  Serial.println(F("Start"));     
  pinMode(13, OUTPUT);
  tft.reset();  
  tft.begin(tft.readID()); 
  tft.setRotation(1);  
  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;
  }     
  initboard();
}
//****************************
void initboard() {        
  for (int i=0;i<8;i++)
   for (int j=0;j<8;j++) poledisp[j][i]=-100; //          
  tft.fillScreen(BLACK);      
  tft.setTextColor(GRAY);
  tft.setTextSize(1);  
  for (int j=1;j<9;j++) {
   tft.setCursor(2,j*24-15);  
   if (rotate) tft.print(j); else tft.print(9-j);
  }
  for (byte i=1;i<9;i++) { 
   tft.setCursor(i*24-1,198);    
   if (rotate) tft.print(char(96+9-i)); else tft.print(char(96+i));  
  }         
  initscreen();          
}
//****************************
void initscreen() {        
 show_board();   
 show_steps();      
 BAction.Show("START");
 BBW.Show(cur_step%2);   
 if (cur_step>1) BBack.Show(); else BBack.Hide();
 BSave.Hide();
 BLoad.Hide();
 BInit.Hide();
 BBack.Show();  
 BLimit.Show();         
 BPlay.Hide();           
 BRotate.Show(rotate);           
 BEmpty.Hide();
 BLimit.Show(limit);  
 BCM.Show(checkmatesearch); 
 BDesc.Show(choice); 
 BSound.Show(sound);    
}
//****************************
void loop() {        
  gui();  
  if (solving) {        
    int len=70;
    if (!sound) len=2;  
    for (int i=1;i<4;i++) { tone(44,400+300*i,len); delay(70); }
    lastscore=solve_step();               
    float tim=float(millis()-starttime)/1000;
    for (int i=3;i>=1;i--) { tone(44,400+300*i,len); delay(70); }
    if (!checkmatesearch&&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) {       
      tft.setTextSize(1);    
      tft.setTextColor(GREEN); 
      tft.setCursor(0,210);    
      if (lastscore<9999) {
       tft.print("# in "); 
       tft.print((9999-lastscore)/2+1); tft.print(F(" st"));        
      } else tft.print("Checkmate"); 
    } else if (lastscore<-9000) {
      tft.setTextSize(1);    
      tft.setTextColor(RED); 
      tft.setCursor(0,210);    
      tft.print("GIVE UP!");       
      show_steps();
    } else if (lastscore==8999) { //Draw
      tft.setTextSize(1);    
      tft.setTextColor(YELLOW); 
      tft.setCursor(0,210);    
      tft.print("Draw");       
    }         
    tft.setTextSize(1);    
    tft.setTextColor(GRAY); 
    tft.setCursor(0,220);    
    tft.print(tim,0); 
    tft.print("s ");    
    if (abs(lastscore)<5000) {   
     tft.print(lastscore);     
    }
    tft.setCursor(0,230);        
    tft.print(count); 
    tft.print("pos");   
    Serial.print(F("Positions estimated=")); Serial.println(count);
    Serial.print(F("Time=")); Serial.print(tim,1); Serial.println("s");    
  }
  delay(10);  
  
  
}

//********************************** 
void load_choice() {
  for (int i=0;i<7;i++) 
   if (cur_step%2==1) polechoice[i]=i; else polechoice[i]=-i;
}
//********************************** 
void show_choice() {
uint16_t color,color_cont;    
  for (int i=0;i<7;i++) {
    color=BLACKF;
    if (i%2==0) color=WHITEF;              
    tft.fillRect(260,i*25+35,25,25,color);    
    color=DARK;
    if (i==cur_choice) color=WHITE;   
    tft.drawRect(260,i*25+35,25,25,color);
    color=BLACK; color_cont=GRAY;
    if (polechoice[i]>0) { color=WHITE; color_cont=BLACK; }
    if (polechoice[i]!=0) {
     drawBitmap(264, i*25+39,&fig[abs(polechoice[i])-1][0], 16, 16,color);          
     drawBitmap(264, i*25+39,&fig_cont[abs(polechoice[i])-1][0], 16, 16,color_cont);     
    }
  }  
}
//********************************** 
void animate_step(int nstep, boolean hide) {   
 if (!hide&&nstep-1>0&&steps[nstep-1].fig1!=0) animate_step(nstep-1,true); 
 if (nstep-1<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; 
 di=di/abs(di); 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) tft.drawRect(i*24+13,j*24+1,23,23,WHITE);    
    else tft.drawRect((7-i)*24+13,(7-j)*24+1,23,23,WHITE);    
  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) tft.drawRect(i*24+13,j*24+1,23,23,WHITE);    
   else tft.drawRect((7-i)*24+13,(7-j)*24+1,23,23,WHITE);     
}
//********************************** 
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; }
   else if (s=='b') { cur_step=2; load=true; }
     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;  
}
//********************************** 
void play() {
 BAction.Show("STOP"); 
 BSave.Hide();
 BBW.Hide();
 BLoad.Hide();
 BInit.Hide();   
 BPlay.Hide();   
 BEmpty.Hide();
 BDesc.Hide(); 
 clearstatus();       
 for (int i=cur_step-1;i>0;i--) {
  if (steps[i].fig1!=0) backstep(i);
 }
 show_board();
 show_steps();
 boolean st=false;
 unsigned long tim=millis();
 int i=1;
 while (i<cur_step) {
  if (steps[i].fig1!=0) movestep(i); 
  digitalWrite(13, HIGH);
  TSPoint p = ts.getPoint();
  digitalWrite(13, LOW);  
  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);    
  int x=388-p.y/2.4; 
  int y=p.x/3.2-50;       
  if (p.z>MINPRESSURE&&p.z<MAXPRESSURE)     
    if (BAction.IsPressed(x,y)) { st=true; BAction.Show(); } 
  if (millis()-tim>2000||st) {
    tim=millis();
    i++;
    show_board();
    beep(20);              
  }  
 }       
 choice=0; 
 beep(200);                
 kingpositions();        
 clearstatus();
 initscreen();                               
}
//********************************** 
void gui() {   
  digitalWrite(13, HIGH);
  TSPoint p = ts.getPoint();
  digitalWrite(13, LOW);  
  // if sharing pins, you'll need to fix the directions of the touchscreen pins  
  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);    
  int x=388-p.y/2.4; 
  int y=p.x/3.2-50;       
  if (((abs(x-touchx)>5||abs(y-touchy)>5)||drag)&&p.z>MINPRESSURE&&p.z<MAXPRESSURE) {    
    touchx=x;
    touchy=y;             
    if (solving) {
      if (BAction.IsPressed(x,y)) { //        
        beep(100); 
        solving=false;  
        BAction.Show("stopping");        
        BAction.Hide();        
        return;    
      }   
    } else { //not solve
      if (BAction.IsPressed(x,y)) { // 
       if (!choice) {
        delay(100);        
        solving=true;   
        BAction.Show();         
        animate_step(cur_step-1,true);
        return;
       } else { //   USB
        delay(100);
        BAction.Hide(); 
        BSave.Hide();
        BBW.Hide();
        BLoad.Hide();
        BInit.Hide();   
        BPlay.Hide();   
        BEmpty.Hide();
        BDesc.Hide();        
        show_steps();
        choice=0;         
        if (!load_usb()) return;
        beep(200);                
        kingpositions();        
        clearstatus();
        initscreen();                              
       }
      } else if (BBW.IsPressed(x,y)) {   //-    
       beep(100);         
       if (cur_step==1) cur_step=2;
        else if (cur_step==2) cur_step=1;
         else if (cur_step%2==0) cur_step--; else cur_step++;       
       BBW.Show(cur_step%2);        
       if (choice) { load_choice(); show_choice(); }
       return;
      } else if (cur_step>1&&BBack.IsPressed(x,y)) {  //      
       beep(100);                
       cur_step--;       
       animate_step(cur_step,true);
       lastscore=0;              
       backstep(cur_step);               
       steps[cur_step].fig1=0;
       show_board();       
       show_steps();       
       if (cur_step>1) BBack.Show(); else BBack.Hide();      
       BBW.Show(cur_step%2);        
       clearstatus();       
       return;        
      } else if (BLimit.IsPressed(x,y)) {    //   
       beep(100);  
       limit++; if (limit>6) limit=0;       
       BLimit.Show(limit);        
       return; 
      } else if (BCM.IsPressed(x,y)) {   //                   
       beep(100); 
       checkmatesearch=!checkmatesearch; 
       BCM.Show(checkmatesearch);        
       if (!checkmatesearch) steps[cur_step].fig1=0;
       lastscore=0;
       show_steps();
       return; 
      } else if (BRotate.IsPressed(x,y)) {   //                   
       beep(100); 
       rotate=!rotate; 
       BRotate.Show(rotate);              
       initboard();       
       return;  
      } else if (BSound.IsPressed(x,y)) {   //                  
       if (sound==1) { beep(100); sound=0; } else { sound=1; beep(200); }       
       BSound.Show(sound);        
       return;
      } else if (BDesc.IsPressed(x,y)) {  //
       beep(100); 
       if (!choice) {
        choice=1;
        cur_choice=1;
        load_choice();
        show_choice();        
        BAction.Show("USB(FEN)");         
        BBack.Hide();  
        BInit.Show();  
        BSave.Show();  
        BLimit.Hide(); 
        BEmpty.Show();  
        BRotate.Hide();    
        BPlay.Show();    
        BCM.Hide();          
        BSound.Hide(); 
        BSave.Show();  
        BLoad.Show();    
       } else {
        choice=0;  
        lastscore=0;
        clearstatus();
        kingpositions();        
        initscreen();        
       }       
       BDesc.Show(choice);                                    
       return;
      } else if (BInit.IsPressed(x,y)) {  //        
        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]=(char)pgm_read_byte(&polestart[j][i]);         
        choice=0;         
        kingpositions();        
        clearstatus();
        initscreen();                     
      } else if (BEmpty.IsPressed(x,y)) {  //        
        beep(200);        
        cur_step=1;        
        clearstatus();        
        steps[1].fig1=0; steps[2].fig1=0;
        for (int i=0;i<8;i++)
         for (int j=0;j<8;j++) pole[j][i]=(char)pgm_read_byte(&polezero[j][i]);                 
        BEmpty.Show();   
        show_board();          
      } else if (BSave.IsPressed(x,y)) { 
        beep(100); 
        for (int i=0;i<8;i++)
         for (int j=0;j<8;j++) EEPROM.write(i*8+j,pole[j][i]);         
        EEPROM.put(64,cur_step);
        EEPROM.put(66,limit);
        for (int i=1;i<cur_step;i++) {
          EEPROM.put(66+i*10,steps[i]);
        }
        BSave.Show(); 
      } else if (BLoad.IsPressed(x,y)) { 
        beep(200); 
        for (int i=0;i<8;i++)
         for (int j=0;j<8;j++) pole[j][i]=EEPROM.read(i*8+j);
        EEPROM.get(64,cur_step);                 
        if (cur_step<0||cur_step>400) cur_step=1;        
        EEPROM.get(66,limit);                 
        if (limit<0||limit>6) limit=2;        
        for (int i=1;i<cur_step;i++) {
          EEPROM.get(66+i*10,steps[i]);
        }        
        steps[0].fig1=0;         
        steps[cur_step].fig1=0;         
        choice=0;                 
        kingpositions();
        clearstatus();
        initscreen();                                   
      } else if (BPlay.IsPressed(x,y)) {    //   
       beep(100);  
       BPlay.Show();        
       play();       
       return; 
      }
      if (!choice&&ntouch==0) {
       touchx0=touchx;
       touchy0=touchy;
       char x1=touchy0/24; 
       char y1=(touchx0-10)/24;       
       if (rotate) { x1=7-x1; y1=7-y1; }
       if (getpole(y1,x1)&&(cur_step%2==1&&pole[x1][y1]>0||cur_step%2==0&&pole[x1][y1]<0)) {        
        char p=pole[x1][y1];        
        drag=true;        
        pole[x1][y1]=0;
        show_fig(y1,x1);
        pole[x1][y1]=p;                
       } else drag=false; 
      }       
      ntouch++;
      if (drag&&ntouch>1) {
          uint16_t buf[256];          
          int x1=touchy0/24; 
          int y1=(touchx0-10)/24;       
          if (rotate) { x1=7-x1; y1=7-y1; }       
          if (abs(pole[x1][y1])>0&&(cur_step%2==1&&pole[x1][y1]>0||cur_step%2==0&&pole[x1][y1]<0)) {
          for (int i=0;i<16;i++)
            for (int j=0;j<16;j++) buf[i*16+j]=tft.readPixel(touchx-8+i,touchy-8+j);
          buf[0]=tft.readPixel(touchx-8,touchy-8);  
          uint16_t color,color_cont;    
          color=BLACK; color_cont=GRAY;
          if (pole[x1][y1]>0) { color=WHITE; color_cont=BLACK; }             
          drawBitmap(touchx-8, touchy-8,&fig[abs(pole[x1][y1])-1][0], 16, 16,color);          
          drawBitmap(touchx-8, touchy-8,&fig_cont[abs(pole[x1][y1])-1][0], 16, 16,color_cont);       
          delay(30);
          for (int i=0;i<16;i++)
            for (int j=0;j<16;j++) tft.drawPixel(touchx-8+i,touchy-8+j,buf[i*16+j]);            
          }  
      } else if (choice) {
        int x1=touchy/24; 
        int y1=(touchx-10)/24;             
        if (rotate) { x1=7-x1; y1=7-y1; } 
        if (touchy+touchx!=0&&choice&&getpole(y1,x1)) {        
         pole[x1][y1]=polechoice[cur_choice];
         show_board(); 
        }       
        if (touchx>=260&&touchx<=285&&touchy>=35&&touchy<=210) {
         cur_choice=(touchy-35)/25;
         show_choice();                       
        }
      }
      lasttouch=millis();
    } //not solve      
    if (!drag) { beep(10); ntouch=0; animate_step(cur_step-1,true); }     
  } else { //touching
    if (!solving&&!choice&&drag!=0&&ntouch>0&&p.z<MINPRESSURE&&millis()-lasttouch>300) { //drag 
     char x1=touchy0/24; 
     char y1=(touchx0-10)/24;     
     char x2=touchy/24; 
     char y2=(touchx-10)/24; 
     if (rotate) { x1=7-x1; y1=7-y1; x2=7-x2; y2=7-y2; }    
     if (getpole(y1,x1)) show_fig(y1,x1);
     if (getpole(y1,x1)&&getpole(y2,x2)) {      
       start_var=cur_step+1;
       only_action=false;   
       load_variants(cur_step);     
       for (int i=cur_step+1;i<cur_step+cur_var+1;i++)  
        if (steps[i].x1==x1&&steps[i].y1==y1&&steps[i].x2==x2&&steps[i].y2==y2) {
         steps[cur_step]=steps[i];          
         movestep(cur_step); cur_step++; steps[cur_step].fig1=0;
         int len=100;
         if (!sound) len=2;  
         for (int i=2;i>=1;i--) { tone(44,400+300*i,len); delay(100); }
         initscreen();
         animate_step(cur_step-1,false);
         break;                                 
        }            
     } else { 
      beep(10);       
     }
     ntouch=0;       
     drag=false;
    } 
  }
  if (millis()-quitime>1000) {
    if (isstatus) show_status(); 
    quitime=millis();
  }
  
  
}
//********************************** 
void show_status() {      
   int tim=(millis()-starttime)/1000; 
   int cur=200000*tim/(limittime-starttime);
   if (cur>200) { cur=200; solving=false; }   
   tft.drawFastHLine(5,210,cur,GRAY);                  
   tft.drawFastHLine(5,212,progress*2,GRAY);  
   int m=tim/60;
   int s=tim%60;
   tft.setTextWrap(1);
   tft.setTextColor(GRAY);
   tft.setTextSize(1);
   tft.fillRect(0,220,60,10,BLACK);             
   tft.setCursor(2,220);     
   if (m>0) { tft.print(m); tft.print(":"); }
   if (s>0) {
    if (s<10&&m>0) tft.print("0"); 
    tft.print(s);
   } else if (m>0) tft.print("00"); else tft.print("0");
   tft.setCursor(36,220);   
   tft.print(cur_level);
   
   tft.setCursor(2,230);   
   if (cur_step%2==1) tft.setTextColor(WHITE); else tft.setTextColor(GRAY);   
   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) {
     beep(10); 
     lastbest=steps[0];    
     tft.fillRect(0,230,50,10,BLACK);             
     tft.setCursor(2,230);     
     tft.print(str_step(0));    
     blinkstep=0;
   }  
   if (steps[0].fig1!=0&&blinkstep==0&&tim>5) {
    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 beep(int leng) {
  analogWrite(PinBuzz, 20);
  delay(2); 
  if (!sound) analogWrite(PinBuzz, 0);  
  delay(leng); 
  analogWrite(PinBuzz, 0);   
}  
//****************************
void definecolors() {
 BLACK  =0x0000;
 BLUE   =0x07FF;  //0x001F;
 RED    =0xF800;
 GREEN  =0x07E0;
 CYAN   =0x07FF;
 MAGENTA=0xF81F;
 YELLOW =0xFFE0;
 WHITE  =0xFFFF;
 GRAY   =0x7BEF;
 DARK   =getColor(32,32,32); 
 GRAY2   =getColor(16,16,16); 
 BLACKF  =getColor(94,58,0); 
 WHITEF  =getColor(180,114,0); 
}
//****************************
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 show_fig(int i,int j) {
uint16_t color,color_cont;  
   color=BLACKF;   
   if ((i+j+2)%2==0) color=WHITEF;           
   int jj=j, ii=i;
   if (rotate) { jj=7-j; ii=7-i; }   
   tft.fillRect(ii*24+12,jj*24,25,25,color);    
   tft.drawRect(ii*24+12,jj*24,25,25,WHITE);  
   color=BLACK; color_cont=GRAY;
   if (pole[j][i]>0) { color=WHITE; color_cont=BLACK; }
   if (pole[j][i]!=0) {
    drawBitmap(ii*24+17, jj*24+5,&fig[abs(pole[j][i])-1][0], 16, 16,color);          
    drawBitmap(ii*24+17, jj*24+5,&fig_cont[abs(pole[j][i])-1][0], 16, 16,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];
  }  
}
//****************************
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[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+"-";    
...

This file has been truncated, please download it to see its full contents.

ArduinoMega Chess 1.0 MCUFRIEND 320x480

Arduino
Sketch updated to touchscreen MCUFRIEND 320x480 pixels.
//ArduinoMega Chess 1.0  (MCUFRIEND 320x480 version)
//Sergey Urusov, ususovsv@gmail.com

#include <UTFTGLUE.h>
#include <stdint.h>
#include "TouchScreen.h"
#include <avr/pgmspace.h>
#include <EEPROM.h> 

uint16_t BLACK,BLUE,RED,GREEN,CYAN,MAGENTA,YELLOW,WHITE,GRAY,DARK,GRAY2,BLACKF,WHITEF;
MCUFRIEND_kbv tft;

int XP = 6, YP = A1, XM = A2, YM = 7;  
TouchScreen ts(XP, YP, XM, YM, 300);   
TSPoint tp;                            

int touchx,touchy,touchx0,touchy0,ntouch;         
unsigned long lasttouch;
#define MINPRESSURE 10
#define MAXPRESSURE 1000
const int PinBuzz = 44;
int cycle=0; // 
const char fp=1;
const char fn=2;
const char fb=3;
const char fr=4;
const char fq=5;
const 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 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 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},
             };  
             
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},
             };  
             
char pole0[8][8];  //   
char poledisp[8][8]; // 
char polechoice[7]; // 
boolean w00,w000,b00,b000;             
char blinkstep;
typedef struct {
  char fig1, fig2; //    
  char x1,y1,x2,y2; //     
  char check; //  
  char type; //  1-  ,2- ,3- ,4-5-6-7-  ,,,
  int weight; // , 
} step_type;
const int MAXSTEPS=500; //.      
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
int MINDEPTH; //.   
int MAXDEPTH; //.   
int LIMDEPTH; //.       
const char MAXCUTS=10; //.. -  - (10-  ,  20)
boolean TRACE=0;
boolean checkmatesearch=0; //   
boolean solving=false;
boolean choice=false;
boolean sound=0;
int cur_step=1; //  , 1....
int limit=0; //  , 0-6;
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
const long limits[7]={10,30,60,180,600,1800,100000};
//                     0  1  2   3   4    5      6 
step_type steps[MAXSTEPS]; //  
step_type cuts[MAXCUTS]; //  -
step_type lastbest;
int lastscore;
int minbeta,maxalpha;
int startweight;
int cur_level; //   ()
int start_var; //   , 1....
int cur_var; //  , 1....
int cur_choice; //   
boolean check_on_table; //  
boolean isstatus;
char WKJ=0,WKI=0,BKJ=0,BKI=0; // 
boolean endspiel=false; // 
char progress; //   0-100
boolean only_action=false; // -  
unsigned long starttime,limittime,quitime=0;             
boolean drag;
const uint8_t fig[6][32] PROGMEM={
{0x0, 0x0,  0x0,  0x0,  0x0,  0x0,  0x3,  0xC0, 0x7,  0xE0, 0x7,  0xE0, 0x3,  0xC0, 0x3,  0xC0,
0x7,  0xE0, 0x3,  0xC0, 0x3,  0xC0, 0x7,  0xE0, 0xF,  0xF0, 0xF,  0xF0, 0xF,  0xF0, 0x0,  0x0}, //
{0x0, 0x0,  0x3,  0x40, 0x7,  0xE0, 0xF,  0xF0, 0x1F, 0xF8, 0x3F, 0xFC, 0x39, 0xFC, 0x33, 0xFC,
0x7,  0xFC, 0xF,  0xF8, 0xF,  0xF0, 0x7,  0xE0, 0x3,  0xC0, 0x7,  0xE0, 0x1F, 0xF8, 0x0,  0x0},  //
{0x1, 0x80, 0x3,  0xC0, 0x1,  0x80, 0xF,  0xF0, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8,
0x1F, 0xF8, 0x1F, 0xF8, 0xF,  0xF0, 0x7,  0xE0, 0x3,  0xC0, 0x31, 0x8C, 0x7F, 0xFE, 0x0,  0x0}, // 
{0x0, 0x0,  0x19, 0x98, 0x1F, 0xF8, 0xF,  0xF0, 0xF,  0xF0, 0xF,  0xF0, 0xF,  0xF0, 0xF,  0xF0,
0xF,  0xF0, 0xF,  0xF0, 0xF,  0xF0, 0xF,  0xF0, 0xF,  0xF0, 0x1F, 0xF8, 0x1F, 0xF8, 0x0,  0x0}, //
{0x19, 0x98, 0xD9, 0x9B, 0xD9, 0x9B, 0xD9, 0x9B, 0x6D, 0xB6, 0x6D, 0xB6, 0x6D, 0xB6, 0x35, 0xAC,
0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x1F, 0xF8, 0xF,  0xF0, 0xF,  0xF0, 0x1F, 0xF8, 0x0,  0x0}, //
{0x1, 0x80, 0x1,  0x80, 0x79, 0x9E, 0x7D, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x7F, 0xFE, 0x3F, 0xFC, 0x3F, 0xFC, 0x1F, 0xF8, 0xF,  0xF0, 0xF,  0xF0, 0x1F, 0xF8, 0x0,  0x0}  //
};
const uint8_t fig_cont[6][32] PROGMEM={
{0x0, 0x0,  0x0,  0x0,  0x3,  0xC0, 0x4,  0x20, 0x8,  0x10, 0x8,  0x10, 0x4,  0x20, 0x4,  0x20,
0x8,  0x10, 0x4,  0x20, 0x4,  0x20, 0x8,  0x10, 0x10, 0x8,  0x10, 0x8,  0x10, 0x8,  0x1F, 0xF8}, //
{0x3, 0x40, 0x4,  0xA0, 0x8,  0x10, 0x12, 0x8,  0x20, 0x4,  0x40, 0x2,  0x46, 0x2,  0x4C, 0x2,
0x38, 0x2,  0x10, 0x4,  0x10, 0x8,  0x8,  0x10, 0x4,  0x20, 0x18, 0x18, 0x20, 0x4,  0x3F, 0xFC},  //
{0x2, 0x40, 0x4,  0x20, 0x6,  0x60, 0x10, 0x8,  0x21, 0x84, 0x21, 0x84, 0x21, 0x84, 0x27, 0xE4,
0x21, 0x84, 0x21, 0x84, 0x11, 0x88, 0x8,  0x10, 0x34, 0x2C, 0x4E, 0x72, 0x80, 0x1,  0xFF, 0xFF}, // 
{0x39, 0x9C, 0x26, 0x64, 0x20, 0x4,  0x1F, 0xF8, 0x10, 0x8,  0x10, 0x8,  0x10, 0x8,  0x10, 0x8,
0x10, 0x8,  0x10, 0x8,  0x10, 0x8,  0x10, 0x8,  0x1F, 0xF8, 0x20, 0x4,  0x20, 0x4,  0x3F, 0xFC}, //
{0x22, 0x24, 0x22, 0x24, 0x22, 0x24, 0x26, 0x64, 0x92, 0x49, 0x92, 0x49, 0x92, 0x49, 0x4A, 0x52,
0x40, 0x2,  0x40, 0x2,  0x5F, 0xFA, 0x20, 0x4,  0x1F, 0xF8, 0x10, 0x8,  0x20, 0x4,  0x3F, 0xFC}, //
{0x2, 0x40, 0x7A, 0x5E, 0x86, 0x61, 0x82, 0x41, 0x2,  0x40, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80,
0x80, 0x81, 0x41, 0x82, 0x5F, 0xFA, 0x20, 0x4,  0x1F, 0xF8, 0x10, 0x8,  0x20, 0x4,  0x3F, 0xFC}  //
};

const uint8_t fig24[6][72] PROGMEM={
{0x0, 0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x1E, 0x0,  0x0,  0x3F, 0x0,  0x80, 0x7F, 0x0,  0x80, 0x7F, 0x0,
0x80, 0x7F, 0x0,  0x0,  0x3F, 0x0,  0x0,  0x1C, 0x0,  0x0,  0x1C, 0x0,  0x80, 0xFF, 0x0,  0x80, 0xFF, 0x0,  0x0,  0x1C, 0x0,  0x0,  0x1C, 0x0,
0x0,  0x3E, 0x0,  0x0,  0x7F, 0x0,  0x80, 0xFF, 0x0,  0xC0, 0xFF, 0x1,  0xE0, 0xFF, 0x3,  0xE0, 0xFF, 0x3,  0xE0, 0xFF, 0x3,  0x0,  0x0,  0x0
}, //pawn
{0x0, 0x0,  0x0,  0x0,  0x6E, 0x0,  0x0,  0xFF, 0x0,  0x80, 0xFF, 0x1,  0x80, 0xFF, 0x3,  0xC0, 0xFF, 0x7,  0xE0, 0xFF, 0xF,  0xE0, 0xF9, 0xF,
0xF0, 0xF8, 0xF,  0xF0, 0xF8, 0xF,  0x60, 0xFC, 0xF,  0x0,  0xFE, 0xF,  0x0,  0xFF, 0xF,  0x0,  0xFF, 0x7,  0x0,  0xFF, 0x3,  0x0,  0xFF, 0x1,
0x0,  0xFE, 0x0,  0x0,  0x7C, 0x0,  0x0,  0x38, 0x0,  0x0,  0x38, 0x0,  0x0,  0x7C, 0x0,  0xF0, 0xFF, 0xF,  0xF0, 0xFF, 0xF,  0x0,  0x0,  0x0
}, //knight
{0x0, 0x0,  0x0,  0x0,  0x3C, 0x0,  0x0,  0x7E, 0x0,  0x0,  0x7E, 0x0,  0x0,  0x3C, 0x0,  0x0,  0x18, 0x0,  0x80, 0xFF, 0x1,  0xC0, 0xFF, 0x3,
0xE0, 0xFF, 0x7,  0xE0, 0xFF, 0x7,  0xE0, 0xFF, 0x7,  0xE0, 0xFF, 0x7,  0xE0, 0xFF, 0x7,  0xE0, 0xFF, 0x7,  0xE0, 0xFF, 0x7,  0xE0, 0xFF, 0x7,
0xE0, 0xFF, 0x7,  0xC0, 0xFF, 0x3,  0x80, 0xFF, 0x1,  0x0,  0xFF, 0x0,  0x8,  0x7E, 0x10, 0x1C, 0x3C, 0x38, 0xFE, 0xFF, 0x7F, 0x0,  0x0,  0x0
}, //bishop
{0x0, 0x0,  0x0,  0xF0, 0x3C, 0xF,  0xF0, 0x3C, 0xF,  0xF0, 0xFF, 0xF,  0xE0, 0xFF, 0x7,  0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,
0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,
0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,  0xE0, 0xFF, 0x7,  0xF0, 0xFF, 0xF,  0xF0, 0xFF, 0xF,  0x0,  0x0,  0x0
}, //rook
{0x0, 0x0,  0x0,  0xEE, 0xBD, 0x77, 0xEE, 0xBD, 0x77, 0xC6, 0x18, 0x63, 0xC6, 0x18, 0x63, 0xC6, 0x18, 0x63, 0xCC, 0x18, 0x33, 0xCC, 0x18, 0x33,
0xCC, 0x18, 0x33, 0xCC, 0x18, 0x33, 0xCC, 0x18, 0x33, 0x98, 0x99, 0x19, 0x98, 0x99, 0x19, 0x98, 0x99, 0x19, 0x98, 0x99, 0x19, 0x98, 0x99, 0x19,
0x30, 0xFF, 0xC,  0xB0, 0xFF, 0xD,  0xF0, 0xFF, 0xF,  0xE0, 0xFF, 0x7,  0xE0, 0xFF, 0x7,  0xF0, 0xFF, 0xF,  0xF0, 0xFF, 0xF,  0x0,  0x0,  0x0
}, //queen
{0x0, 0x0,  0x0,  0x0,  0x18, 0x0,  0xF0, 0x18, 0xF,  0xF8, 0x99, 0x1F, 0xFC, 0xDB, 0x3F, 0xFE, 0xFF, 0x7F, 0xFE, 0xFF, 0x7F, 0xFE, 0xFF, 0x7F,
0xFE, 0xFF, 0x7F, 0xFE, 0xFF, 0x7F, 0xFE, 0xFF, 0x7F, 0xFE, 0xFF, 0x7F, 0xFE, 0xFF, 0x7F, 0xFE, 0xFF, 0x3F, 0xFC, 0xFF, 0x1F, 0xF8, 0xFF, 0x1F,
0xF0, 0xFF, 0xF,  0xE0, 0xFF, 0x7,  0xE0, 0xFF, 0x7,  0xC0, 0xFF, 0x3,  0xE0, 0xFF, 0x7,  0xF0, 0xFF, 0xF,  0xF0, 0xFF, 0xF,  0x0,  0x0,  0x0
} //king
};

const uint8_t fig24_cont[6][72] PROGMEM={
{0x0, 0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x1C, 0x0,  0x0,  0x22, 0x0,  0x0,  0x41, 0x0,  0x80, 0x80, 0x0,  0x80, 0x80, 0x0,
0x80, 0x80, 0x0,  0x0,  0x41, 0x0,  0x0,  0x22, 0x0,  0xC0, 0xE3, 0x1,  0x40, 0x0,  0x1,  0x40, 0x0,  0x1,  0xC0, 0xE3, 0x1,  0x0,  0x22, 0x0,
0x0,  0x41, 0x0,  0x80, 0x80, 0x0,  0x40, 0x0,  0x1,  0x20, 0x0,  0x2,  0x10, 0x0,  0x4,  0x10, 0x0,  0x4,  0x10, 0x0,  0x4,  0xF0, 0xFF, 0x7
}, //pawn
{0x0, 0x6E, 0x0,  0x0,  0x91, 0x0,  0x80, 0x0,  0x1,  0x40, 0x2,  0x2,  0x40, 0x0,  0x4,  0x20, 0x0,  0x8,  0x10, 0x0,  0x10, 0x10, 0x6,  0x10,
0x8,  0x5,  0x10, 0x8,  0x5,  0x10, 0x90, 0x2,  0x10, 0x60, 0x1,  0x10, 0x80, 0x0,  0x10, 0x80, 0x0,  0x8,  0x80, 0x0,  0x4,  0x80, 0x0,  0x2,
0x0,  0x1,  0x1,  0x0,  0x82, 0x0,  0x0,  0x44, 0x0,  0x0,  0x44, 0x0,  0xF8, 0x83, 0x1F, 0x8,  0x0,  0x10, 0x8,  0x0,  0x10, 0xF8, 0xFF, 0x1F
}, //knight
{0x0, 0x3C, 0x0,  0x0,  0x42, 0x0,  0x0,  0x81, 0x0,  0x0,  0x81, 0x0,  0x0,  0x42, 0x0,  0x80, 0xE7, 0x1,  0x40, 0x0,  0x2,  0x20, 0x18, 0x4,
0x10, 0x18, 0x8,  0x10, 0x18, 0x8,  0x10, 0x18, 0x8,  0x90, 0xFF, 0x9,  0x90, 0xFF, 0x9,  0x10, 0x18, 0x8,  0x10, 0x18, 0x8,  0x10, 0x18, 0x8,
0x10, 0x18, 0x8,  0x20, 0x18, 0x4,  0x40, 0x18, 0x2,  0x88, 0x0,  0x11, 0x14, 0x81, 0x28, 0xE2, 0xC3, 0x47, 0x1,  0x0,  0x80, 0xFF, 0xFF, 0xFF
}, //bishop
{0xF8, 0x7E, 0x1F, 0x8,  0xC3, 0x10, 0x8,  0xC3, 0x10, 0x8,  0x0,  0x10, 0x10, 0x0,  0x8,  0xE0, 0xFF, 0x7,  0x20, 0x0,  0x4,  0x20, 0x0,  0x4,
0x20, 0x0,  0x4,  0x20, 0x0,  0x4,  0x20, 0x0,  0x4,  0x20, 0x0,  0x4,  0x20, 0x0,  0x4,  0x20, 0x0,  0x4,  0x20, 0x0,  0x4,  0x20, 0x0,  0x4,
0x20, 0x0,  0x4,  0x20, 0x0,  0x4,  0x20, 0x0,  0x4,  0xE0, 0xFF, 0x7,  0x10, 0x0,  0x8,  0x8,  0x0,  0x10, 0x8,  0x0,  0x10, 0xF8, 0xFF, 0x1F
}, //rook
{0xEF, 0xBD, 0xF7, 0x11, 0x42, 0x88, 0x11, 0x42, 0x88, 0x29, 0xA5, 0x94, 0x29, 0xA5, 0x94, 0x29, 0xA5, 0x94, 0x32, 0xA5, 0x4C, 0x32, 0xA5, 0x4C,
0x32, 0xA5, 0x4C, 0x32, 0xA5, 0x4C, 0x32, 0xA5, 0x4C, 0x64, 0x66, 0x26, 0x64, 0x66, 0x26, 0x64, 0x66, 0x26, 0x64, 0x66, 0x26, 0x64, 0x66, 0x26,
0xC8, 0x0,  0x13, 0x48, 0x0,  0x12, 0x8,  0x0,  0x10, 0x10, 0x0,  0x8,  0xF0, 0xFF, 0xF,  0x8,  0x0,  0x10, 0x8,  0x0,  0x10, 0xF8, 0xFF, 0x1F
}, //queen
{0x0, 0x18, 0x0,  0xF0, 0x24, 0xF,  0x8,  0xA5, 0x10, 0x4,  0x66, 0x20, 0x2,  0x24, 0x40, 0x1,  0x24, 0x80, 0x1,  0x18, 0x80, 0x1,  0x18, 0x80,
0x1,  0x18, 0x80, 0x1,  0x18, 0x80, 0x1,  0x18, 0x80, 0x1,  0x18, 0x80, 0x1,  0x18, 0x80, 0x1,  0x18, 0x40, 0x2,  0x18, 0x20, 0x4,  0x18, 0x20,
0xE8, 0xFF, 0x17, 0x10, 0x0,  0x8,  0x10, 0x0,  0x8,  0x20, 0x0,  0x4,  0xF0, 0xFF, 0xF,  0x8,  0x0,  0x10, 0x8,  0x0,  0x10, 0xF8, 0xFF, 0x1F
} //king
};


const uint8_t issound[2][32] PROGMEM={
{0x0, 0x0,  0x0,  0x0,  0x0,  0x32, 0x0,  0x54, 0x0,  0x98, 0x1F, 0x10, 0x10, 0x30, 0x10, 0x50,
0x10, 0x90, 0x11, 0x10, 0x1F, 0x10, 0x4,  0x90, 0x8,  0x50, 0x10, 0x30, 0x0,  0x0,  0x0,  0x0},
{0x0, 0x0,  0x0,  0x0,  0x0,  0x30, 0x0,  0x50, 0x0,  0x90, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x1F, 0x10, 0x0,  0x90, 0x0,  0x50, 0x0,  0x30, 0x0,  0x0,  0x0,  0x0}
};
const uint8_t iswb[2][32] PROGMEM={
{0x0,  0x0,  0x0,  0x0,  0x3,  0xC0, 0x4,  0x20, 0x8,  0x10, 0x8,  0x10, 0x4,  0x20, 0x4,  0x20,
0x8,  0x10, 0x4,  0x20, 0x4,  0x20, 0x8,  0x10, 0x10, 0x8,  0x10, 0x8,  0x1F, 0xF8, 0x0,  0x0},
{0x0,  0x0,  0x0,  0x0,  0x3,  0xC0, 0x7,  0xE0, 0xF,  0xF0, 0xF,  0xF0, 0x7,  0xE0, 0x7,  0xE0,
0xF,  0xF0, 0x7,  0xE0, 0x7,  0xE0, 0xF,  0xF0, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x0,  0x0}
};
const uint8_t iscm[2][32] PROGMEM={
{0x0, 0x0,  0x7,  0xE0, 0xC,  0x30, 0xC,  0x30, 0xC,  0x30, 0xC,  0x30, 0x0,  0x30, 0x0,  0x60,
0x0,  0xC0, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x0,  0x0,  0x1,  0x80, 0x1,  0x80, 0x0,  0x0},
{0x0,  0x0,  0x3F, 0x0,  0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x1,  0x80, 0x3,  0x0,
0x6,  0x24, 0xC,  0x24, 0xC,  0xFF, 0xC,  0x24, 0x0,  0xFF, 0xC,  0x24, 0xC,  0x24, 0x0,  0x0}
};
const uint8_t islimit[7][32] PROGMEM={
{0x0, 0x0,  0x4,  0x70, 0xC,  0x88, 0x4,  0x88, 0x4,  0x88, 0x4,  0x88, 0x4,  0x88, 0x4,  0x88,
0xE,  0x70, 0x0,  0x0,  0x1D, 0xDC, 0x11, 0x10, 0x1D, 0xD0, 0x5,  0x10, 0x1D, 0xDC, 0x0,  0x0},
{0x0, 0x0,  0xC,  0x70, 0x12, 0x88, 0x2,  0x88, 0xC,  0x88, 0x2,  0x88, 0x2,  0x88, 0x12, 0x88,
0xC,  0x70, 0x0,  0x0,  0x1D, 0xDC, 0x11, 0x10, 0x1D, 0xD0, 0x5,  0x10, 0x1D, 0xDC, 0x0,  0x0},
{0x0, 0x0,  0x1,  0x80, 0x3,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80,
0x3,  0xC0, 0x0,  0x0,  0x22, 0xA4, 0x36, 0xA4, 0x2A, 0xB4, 0x22, 0xAC, 0x22, 0xA4, 0x0,  0x0},
{0x0, 0x0,  0x3,  0xC0, 0x6,  0x60, 0x0,  0x60, 0x1,  0xC0, 0x0,  0x60, 0x6,  0x60, 0x6,  0x60,
0x3,  0xC0, 0x0,  0x0,  0x22, 0xA4, 0x36, 0xA4, 0x2A, 0xB4, 0x22, 0xAC, 0x22, 0xA4, 0x0,  0x0},
{0x0, 0x0,  0xC,  0x78, 0x1C, 0xCC, 0xC,  0xCC, 0xC,  0xCC, 0xC,  0xCC, 0xC,  0xCC, 0xC,  0xCC,
0x1E, 0x78, 0x0,  0x0,  0x22, 0xA4, 0x36, 0xA4, 0x2A, 0xB4, 0x22, 0xAC, 0x22, 0xA4, 0x0,  0x0},
{0x0, 0x0,  0x1C, 0x78, 0x36, 0xCC, 0x6,  0xCC, 0x1C, 0xCC, 0x6,  0xCC, 0x36, 0xCC, 0x36, 0xCC,
0x1C, 0x78, 0x0,  0x0,  0x22, 0xA4, 0x36, 0xA4, 0x2A, 0xB4, 0x22, 0xAC, 0x22, 0xA4, 0x0,  0x0},
{0x0, 0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x3C, 0x3C, 0x7E, 0x7E, 0x63, 0xC6, 0x61, 0x86,
0x63, 0xC6, 0x66, 0x66, 0x3C, 0x3C, 0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0}
};
const uint8_t isdesc[2][32] PROGMEM={
{0x0,  0x0,  0xE3, 0x8E, 0xE3, 0x8E, 0xE3, 0x8E, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0xE3, 0x8E,
0xE3, 0x8E, 0xE3, 0x8E, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0xE3, 0x8E, 0xE3, 0x8E, 0xE3, 0x8E},
{0x0,  0x0,  0x0,  0x4,  0x0,  0xE,  0x0,  0xE,  0x0,  0x1C, 0x0,  0x1C, 0x0,  0x38, 0x0,  0x30,
0x30, 0x70, 0x78, 0xE0, 0x3C, 0xC0, 0x1F, 0xC0, 0xF,  0x80, 0x7,  0x0,  0x2,  0x0,  0x0,  0x0}

};
const uint8_t isback[32] PROGMEM={
0x0,  0x0,  0x0,  0x0,  0x20, 0xF0, 0x31, 0xF8, 0x3B, 0xFC, 0x3F, 0x8E, 0x3F, 0xE,  0x3F, 0xE,
0x3F, 0x8E, 0x3F, 0xCE, 0x0,  0xE,  0x0,  0xE,  0x0,  0x1C, 0x0,  0x38, 0x0,  0x70, 0x0,  0x0
};
const uint8_t issave[32] PROGMEM={
0x1,  0x80, 0x3,  0xC0, 0x7,  0xE0, 0x7,  0xE0, 0x3,  0xC0, 0x3F, 0xFC, 0x23, 0xC4, 0x23, 0xC4,
0x23, 0xC4, 0x23, 0xC4, 0x23, 0xC4, 0x23, 0xC4, 0x20, 0x4,  0x20, 0x4,  0x3F, 0xFC, 0x0,  0x0
};
const uint8_t isload[32] PROGMEM={
0x0,  0x0,  0x3,  0xC0, 0x3,  0xC0, 0x3,  0xC0, 0x3,  0xC0, 0x3F, 0xFC, 0x23, 0xC4, 0x23, 0xC4,
0x23, 0xC4, 0x27, 0xE4, 0x27, 0xE4, 0x23, 0xC4, 0x21, 0x84, 0x20, 0x4,  0x3F, 0xFC, 0x0,  0x0
};
const uint8_t isempty[32] PROGMEM={
0xFF,  0xFF, 0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,
0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0xFF, 0xFF
};
const uint8_t isinit[32] PROGMEM={
0xFF,  0xFF, 0x80, 0x1,  0x80, 0x1,  0xFF, 0xFF, 0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,
0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
const uint8_t isplay[32] PROGMEM={
0x0,  0x0,  0x3,  0xC0, 0x3,  0xC0, 0x3,  0xC0, 0x1,  0x80, 0x23, 0xF8, 0x17, 0xC8, 0xB,  0xC8,
0x3,  0xC0, 0x3,  0xC0, 0x2,  0x40, 0x4,  0x40, 0x4,  0x38, 0x4,  0x8,  0xC,  0x0,  0x0,  0x0
};
const uint8_t isrotate[2][32] PROGMEM={
{0x0,  0x0,  0x0,  0x0,  0x3F, 0xFC, 0x20, 0x4,  0x20, 0x4,  0x20, 0x4,  0x20, 0x4,  0x20, 0x4,
0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x0,  0x0,  0x0,  0x0},
{0x0, 0x0,  0x0,  0x0,  0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC,
0x20, 0x4,  0x20, 0x4,  0x20, 0x4,  0x20, 0x4,  0x20, 0x4,  0x3F, 0xFC, 0x0,  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}}  
};

//******
class Button {
public:
int bx,by,bw,bh,bshift;
String bs;
const uint8_t* bp;
 Button(int x,int y,int w,int h,String s,const uint8_t* p, int shift);
 void Show(int shift); 
 void Show(String s); 
 void Hide();
 boolean IsPressed(int xc, int yc);
private:
boolean active;
 void ishow(uint16_t textcolor,uint16_t backcolor);
};
Button::Button(int x,int y,int w,int h,String s,const uint8_t* p=NULL, int shift=0) {
  bx=x; by=y; bw=w; bh=h; bs=s; bp=p; bshift=shift;
};
void Button::Show(int shift=0) {
 bshift=shift; 
 active=true;
 ishow(WHITE,DARK);  
};
void Button::Show(String s) {
 bs=s; 
 active=true;
 ishow(WHITE,DARK);  
};
void Button::Hide() { 
 active=false; 
 ishow(GRAY,DARK);  
};
boolean Button::IsPressed(int xc, int yc) {
  if (active&&abs(bx+bw/2-xc)<bw/2&&abs(by+bh/2-yc)<bh/2) {
    ishow(WHITE,GRAY); 
    touchx=0; touchy=0;        
    return true;
  } 
  return false;
};  
void Button::ishow(uint16_t textcolor,uint16_t backcolor) {  
  tft.fillRoundRect(bx+2,by+2,bw,bh,3,GRAY2);               
  tft.fillRoundRect(bx,by,bw,bh,3,backcolor);               
  tft.setTextColor(textcolor);
  tft.setTextSize(1);    
  tft.setCursor(bx+(bw-bs.length()*6)/2,by+(bh-8)/2);       
  if (bp!=NULL) { 
   tft.drawBitmap(1+bx+(bw-16)/2, by+(bh-16)/2, bp+bshift*32, 16, 16,textcolor);          
  } 
  else  tft.print(bs);    
}
Button BAction(320, 285, 70, 30, "START");
Button BBW(402, 285, 30, 30, "",&iswb[0][0]);
Button BBack(444, 285, 30, 30, "",&isback[0]);
Button BInit(444, 285, 30, 30, "",&isinit[0]);
Button BLimit(320, 245, 26, 30, "",&islimit[0][0]);
Button BEmpty(320, 245, 26, 30, "",&isempty[0]);
Button BRotate(352, 245, 26, 30, "",&isrotate[0][0]);
Button BPlay(352, 245, 26, 30, "",&isplay[0]);
Button BCM(384, 245, 26, 30, "",&iscm[0][0]);
Button BSave(384, 245, 26, 30, "",&issave[0]);
Button BDesc(416, 245, 26, 30, "",&isdesc[0][0]);
Button BSound(448, 245, 26, 30, "",&issound[0][0]);
Button BLoad(448, 245, 26, 30, "",&isload[0]);
//********************************** 
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) & (1 << (i % 8))) {        
        tft.drawPixel(x+i, y+j, color);
      }      
    }
  }
}
//****************************
void deletebuttons() {  
  tft.fillRect(320,245,160,75,BLACK);             
}

//****************************
void clearstatus() {
  tft.fillRect(320,225,160,20,BLACK);             
  tft.drawFastHLine(10,312,300,BLACK);   
  tft.drawFastHLine(10,315,300,BLACK);  
}  
//****************************
void setup() {      
  Serial.begin(57600);  
  Serial.println(F("Start"));     
  pinMode(13, OUTPUT);
  tft.reset();  
  tft.begin(tft.readID()); 
  tft.setRotation(1);  
  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;
  }     
  initboard();
}
//****************************
void initboard() {        
  for (int i=0;i<8;i++)
   for (int j=0;j<8;j++) poledisp[j][i]=-100; //          
  tft.fillScreen(BLACK);      
  tft.setTextColor(GRAY);
  tft.setTextSize(1);  
  for (int j=1;j<9;j++) {
   tft.setCursor(2,j*37-20);  
   if (rotate) tft.print(j); else tft.print(9-j);
  }
  for (byte i=1;i<9;i++) { 
   tft.setCursor(i*37-8,300);    
   if (rotate) tft.print(char(96+9-i)); else tft.print(char(96+i));  
  }         
  initscreen();          
}
//****************************
void initscreen() {        
 show_board();   
 show_steps();      
 BAction.Show("START");
 BBW.Show(cur_step%2);   
 if (cur_step>1) BBack.Show(); else BBack.Hide();
 BSave.Hide();
 BLoad.Hide();
 BInit.Hide();
 BBack.Show();  
 BLimit.Show();         
 BPlay.Hide();           
 BRotate.Show(rotate);           
 BEmpty.Hide();
 BLimit.Show(limit);  
 BCM.Show(checkmatesearch); 
 BDesc.Show(choice); 
 BSound.Show(sound);    
}
//****************************
void loop() {        
  gui();  
  if (solving) {        
    int len=70;
    if (!sound) len=2;  
    for (int i=1;i<4;i++) { tone(44,400+300*i,len); delay(70); }
    lastscore=solve_step();               
    float tim=float(millis()-starttime)/1000;
    for (int i=3;i>=1;i--) { tone(44,400+300*i,len); delay(70); }
    if (!checkmatesearch&&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) {       
      tft.setTextSize(1);    
      tft.setTextColor(GREEN); 
      tft.setCursor(322,230);    
      if (lastscore<9999) {
       tft.print("# in "); 
       tft.print((9999-lastscore)/2+1); tft.print(F(" st"));        
      } else tft.print("Checkmate"); 
    } else if (lastscore<-9000) {
      tft.setTextSize(1);    
      tft.setTextColor(RED); 
      tft.setCursor(322,230);    
      tft.print("GIVE UP!");       
      show_steps();
    } else if (lastscore==8999) { //Draw
      tft.setTextSize(1);    
      tft.setTextColor(YELLOW); 
      tft.setCursor(322,230);    
      tft.print("Draw");       
    }         
    tft.setTextSize(1);    
    tft.setTextColor(GRAY); 
    tft.setCursor(322,230);    
    tft.print(tim,0); 
    tft.print("s ");    
    if (abs(lastscore)<5000) {   
     tft.print("=");
     tft.print(lastscore);     
    }
    tft.setCursor(390,230);        
    tft.print(count); 
    tft.print(" pos");   
    Serial.print(F("Positions estimated=")); Serial.println(count);
    Serial.print(F("Time=")); Serial.print(tim,1); Serial.println("s");    
  }
  delay(10);  
  
  
}

//********************************** 
void load_choice() {
  for (int i=0;i<7;i++) 
   if (cur_step%2==1) polechoice[i]=i; else polechoice[i]=-i;
}
//********************************** 
void show_choice() {
uint16_t color,color_cont;    
  for (int i=0;i<7;i++) {
    color=BLACKF;
    if (i%2==0) color=WHITEF;              
    tft.fillRect(416,i*25+35,25,25,color);    
    color=DARK;
    if (i==cur_choice) color=WHITE;   
    tft.drawRect(416,i*25+35,25,25,color);
    color=BLACK; color_cont=GRAY;
    if (polechoice[i]>0) { color=WHITE; color_cont=BLACK; }
    if (polechoice[i]!=0) {
     tft.drawBitmap(420, i*25+39,&fig[abs(polechoice[i])-1][0], 16, 16,color);          
     tft.drawBitmap(420, i*25+39,&fig_cont[abs(polechoice[i])-1][0], 16, 16,color_cont);     
    }
  }  
}
//********************************** 
void animate_step(int nstep, boolean hide) {   
 if (!hide&&nstep-1>0&&steps[nstep-1].fig1!=0) animate_step(nstep-1,true); 
 if (nstep-1<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; 
 di=di/abs(di); 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) tft.drawRect(i*37+13,j*37+1,36,36,WHITE);    
    else tft.drawRect((7-i)*37+13,(7-j)*37+1,36,36,WHITE);    
  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) tft.drawRect(i*37+13,j*37+1,36,36,WHITE);    
   else tft.drawRect((7-i)*37+13,(7-j)*37+1,36,36,WHITE);     
}
//********************************** 
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; }
   else if (s=='b') { cur_step=2; load=true; }
     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;  
}
//********************************** 
void play() {
 BAction.Show("STOP"); 
 BSave.Hide();
 BBW.Hide();
 BLoad.Hide();
 BInit.Hide();   
 BPlay.Hide();   
 BEmpty.Hide();
 BDesc.Hide(); 
 clearstatus();       
 for (int i=cur_step-1;i>0;i--) {
  if (steps[i].fig1!=0) backstep(i);
 }
 show_board();
 show_steps();
 boolean st=false;
 unsigned long tim=millis();
 int i=1;
 while (i<cur_step) {
  if (steps[i].fig1!=0) movestep(i); 
  digitalWrite(13, HIGH);
  TSPoint p = ts.getPoint();
  digitalWrite(13, LOW);  
  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);    
  int x=map(p.y,980,110,0,479);
  int y=map(p.x,145,902,0,319);  
  if (p.z>MINPRESSURE&&p.z<MAXPRESSURE)     
    if (BAction.IsPressed(x,y)) { st=true; BAction.Show(); } 
  if (millis()-tim>2000||st) {
    tim=millis();
    i++;
    show_board();
    beep(20);              
  }  
 }       
 choice=0; 
 beep(200);                
 kingpositions();        
 clearstatus();
 initscreen();                               
}
//********************************** 
void gui() {   
  digitalWrite(13, HIGH);
  TSPoint p = ts.getPoint();
  digitalWrite(13, LOW);  
  // if sharing pins, you'll need to fix the directions of the touchscreen pins  
  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);    
  int x=map(p.y,980,110,0,479);
  int y=map(p.x,145,902,0,319);
  
  if (((abs(x-touchx)>5||abs(y-touchy)>5)||drag)&&p.z>MINPRESSURE&&p.z<MAXPRESSURE) {    
  //  tft.drawPixel(x,y,CYAN);    
  //  Serial.println(x);
  //  Serial.println(y);  
    touchx=x;
    touchy=y;             
    if (solving) {
      if (BAction.IsPressed(x,y)) { //        
        beep(100); 
        solving=false;  
        BAction.Show("stopping");        
        BAction.Hide();        
        return;    
      }   
    } else { //not solve
      if (BAction.IsPressed(x,y)) { // 
       if (!choice) {
        delay(100);        
        solving=true;   
        BAction.Show();         
        animate_step(cur_step-1,true);
        return;
       } else { //   USB
        delay(100);
        BAction.Hide(); 
        BSave.Hide();
        BBW.Hide();
        BLoad.Hide();
        BInit.Hide();   
        BPlay.Hide();   
        BEmpty.Hide();
        BDesc.Hide();        
        show_steps();
        choice=0;         
        if (!load_usb()) return;
        beep(200);                
        kingpositions();        
        clearstatus();
        initscreen();                              
       }
      } else if (BBW.IsPressed(x,y)) {   //-    
       beep(100);         
       if (cur_step==1) cur_step=2;
        else if (cur_step==2) cur_step=1;
         else if (cur_step%2==0) cur_step--; else cur_step++;       
       BBW.Show(cur_step%2);        
       if (choice) { load_choice(); show_choice(); }
       return;
      } else if (cur_step>1&&BBack.IsPressed(x,y)) {  //      
       beep(100);                
       cur_step--;       
       animate_step(cur_step,true);
       lastscore=0;              
       backstep(cur_step);               
       steps[cur_step].fig1=0;
       show_board();       
       show_steps();       
       if (cur_step>1) BBack.Show(); else BBack.Hide();      
       BBW.Show(cur_step%2);        
       clearstatus();       
       return;        
      } else if (BLimit.IsPressed(x,y)) {    //   
       beep(100);  
       limit++; if (limit>6) limit=0;       
       BLimit.Show(limit);        
       return; 
      } else if (BCM.IsPressed(x,y)) {   //                   
       beep(100); 
       checkmatesearch=!checkmatesearch; 
       BCM.Show(checkmatesearch);        
       if (!checkmatesearch) steps[cur_step].fig1=0;
       lastscore=0;
       show_steps();
       return; 
      } else if (BRotate.IsPressed(x,y)) {   //                   
       beep(100); 
       rotate=!rotate; 
       BRotate.Show(rotate);              
       initboard();       
       return;  
      } else if (BSound.IsPressed(x,y)) {   //                  
       if (sound==1) { beep(100); sound=0; } else { sound=1; beep(200); }       
       BSound.Show(sound);        
       return;
      } else if (BDesc.IsPressed(x,y)) {  //
       beep(100); 
       if (!choice) {
        choice=1;
        cur_choice=1;
        load_choice();
        show_choice();        
        BAction.Show("USB(FEN)");         
        BBack.Hide();  
        BInit.Show();  
        BSave.Show();  
        BLimit.Hide(); 
        BEmpty.Show();  
        BRotate.Hide();    
        BPlay.Show();    
        BCM.Hide();          
        BSound.Hide(); 
        BSave.Show();  
        BLoad.Show();    
       } else {
        choice=0;  
        lastscore=0;
        clearstatus();
        kingpositions();        
        initscreen();        
       }       
       BDesc.Show(choice);                                    
       return;
      } else if (BInit.IsPressed(x,y)) {  //        
        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]=(char)pgm_read_byte(&polestart[j][i]);         
        choice=0;         
        kingpositions();        
        clearstatus();
        initscreen();                     
      } else if (BEmpty.IsPressed(x,y)) {  //        
        beep(200);        
        cur_step=1;        
        clearstatus();        
        steps[1].fig1=0; steps[2].fig1=0;
        for (int i=0;i<8;i++)
         for (int j=0;j<8;j++) pole[j][i]=(char)pgm_read_byte(&polezero[j][i]);                 
        BEmpty.Show();   
        show_board();          
      } else if (BSave.IsPressed(x,y)) { 
        beep(100); 
        for (int i=0;i<8;i++)
         for (int j=0;j<8;j++) EEPROM.write(i*8+j,pole[j][i]);         
        EEPROM.put(64,cur_step);
        EEPROM.put(66,limit);
        for (int i=1;i<cur_step;i++) {
          EEPROM.put(66+i*10,steps[i]);
        }
        BSave.Show(); 
      } else if (BLoad.IsPressed(x,y)) { 
        beep(200); 
        for (int i=0;i<8;i++)
         for (int j=0;j<8;j++) pole[j][i]=EEPROM.read(i*8+j);
        EEPROM.get(64,cur_step);                 
        if (cur_step<0||cur_step>400) cur_step=1;        
        EEPROM.get(66,limit);                 
        if (limit<0||limit>6) limit=2;        
        for (int i=1;i<cur_step;i++) {
          EEPROM.get(66+i*10,steps[i]);
        }        
        steps[0].fig1=0;         
        steps[cur_step].fig1=0;         
        choice=0;                 
        kingpositions();
        clearstatus();
        initscreen();                                   
      } else if (BPlay.IsPressed(x,y)) {    //   
       beep(100);  
       BPlay.Show();        
       play();       
       return; 
      }
      if (!choice&&ntouch==0) {
       touchx0=touchx;
       touchy0=touchy;
       char x1=touchy0/37; 
       char y1=(touchx0-10)/37;       
       if (rotate) { x1=7-x1; y1=7-y1; }
       if (getpole(y1,x1)&&(cur_step%2==1&&pole[x1][y1]>0||cur_step%2==0&&pole[x1][y1]<0)) {        
        char p=pole[x1][y1];        
        drag=true;        
        pole[x1][y1]=0;
        show_fig(y1,x1);
        pole[x1][y1]=p;                
       } else drag=false; 
      }       
      ntouch++;
      if (drag&&ntouch>1) {
          uint16_t buf[256];          
          int x1=touchy0/37; 
          int y1=(touchx0-10)/37;       
          if (rotate) { x1=7-x1; y1=7-y1; }       
          if (abs(pole[x1][y1])>0&&(cur_step%2==1&&pole[x1][y1]>0||cur_step%2==0&&pole[x1][y1]<0)) {
          for (int i=0;i<16;i++)
            for (int j=0;j<16;j++) buf[i*16+j]=tft.readPixel(touchx-8+i,touchy-8+j);
          buf[0]=tft.readPixel(touchx-8,touchy-8);  
          uint16_t color,color_cont;    
          color=BLACK; color_cont=GRAY;
          if (pole[x1][y1]>0) { color=WHITE; color_cont=BLACK; }             
          tft.drawBitmap(touchx-8, touchy-8,&fig[abs(pole[x1][y1])-1][0], 16, 16,color);          
          tft.drawBitmap(touchx-8, touchy-8,&fig_cont[abs(pole[x1][y1])-1][0], 16, 16,color_cont);       
          delay(30);
          for (int i=0;i<16;i++)
            for (int j=0;j<16;j++) tft.drawPixel(touchx-8+i,touchy-8+j,buf[i*16+j]);            
          }  
      } else if (choice) {
        int x1=touchy/37; 
        int y1=(touchx-10)/37;             
        if (rotate) { x1=7-x1; y1=7-y1; } 
        if (touchy+touchx!=0&&choice&&getpole(y1,x1)) {        
         pole[x1][y1]=polechoice[cur_choice];
         show_board(); 
        }       
        if (touchx>=416&&touchx<=441&&touchy>=35&&touchy<=210) {
         cur_choice=(touchy-35)/25;
         show_choice();                       
        }
      }
      lasttouch=millis();
    } //not solve      
    if (!drag) { beep(10); ntouch=0; animate_step(cur_step-1,true); }     
  } else { //touching
    if (!solving&&!choice&&drag!=0&&ntouch>0&&p.z<MINPRESSURE&&millis()-lasttouch>300) { //drag 
     char x1=touchy0/37; 
     char y1=(touchx0-10)/37;     
     char x2=touchy/37; 
     char y2=(touchx-10)/37; 
     if (rotate) { x1=7-x1; y1=7-y1; x2=7-x2; y2=7-y2; }    
     if (getpole(y1,x1)) show_fig(y1,x1);
     if (getpole(y1,x1)&&getpole(y2,x2)) {      
       start_var=cur_step+1;
       only_action=false;   
       load_variants(cur_step);     
       for (int i=cur_step+1;i<cur_step+cur_var+1;i++)  
        if (steps[i].x1==x1&&steps[i].y1==y1&&steps[i].x2==x2&&steps[i].y2==y2) {
         steps[cur_step]=steps[i];          
         movestep(cur_step); cur_step++; steps[cur_step].fig1=0;
         int len=100;
         if (!sound) len=2;  
         for (int i=2;i>=1;i--) { tone(44,400+300*i,len); delay(100); }
         initscreen();
         animate_step(cur_step-1,false);
         break;                                 
        }            
     } else { 
      beep(10);       
     }
     ntouch=0;       
     drag=false;
    } 
  }
  if (millis()-quitime>1000) {
    if (isstatus) show_status(); 
    quitime=millis();
  }
  
  
}
//********************************** 
void show_status() {      
   int tim=(millis()-starttime)/1000; 
   int cur=300000*tim/(limittime-starttime);
   if (cur>300) { cur=300; solving=false; }   
   tft.drawFastHLine(10,312,cur,GRAY);                  
   tft.drawFastHLine(10,315,progress*2,GRAY);  
   int m=tim/60;
   int s=tim%60;
   tft.setTextWrap(1);
   tft.setTextColor(GRAY);
   tft.setTextSize(1);
   tft.fillRect(320,225,50,20,BLACK);             
   tft.setCursor(322,230);     
   if (m>0) { tft.print(m); tft.print(":"); }
   if (s>0) {
    if (s<10&&m>0) tft.print("0"); 
    tft.print(s);
   } else if (m>0) tft.print("00"); else tft.print("0");
   tft.setCursor(350,230);   
   tft.print(cur_level);
   
   tft.setCursor(370,230);   
   if (cur_step%2==1) tft.setTextColor(WHITE); else tft.setTextColor(GRAY);   
   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) {
     beep(10); 
     lastbest=steps[0];    
     tft.fillRect(370,230,50,10,BLACK);             
     tft.setCursor(370,230);     
     tft.print(str_step(0)); 
     blinkstep=0;
   }  
   if (steps[0].fig1!=0&&blinkstep==0&&tim>5) {
    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 beep(int leng) {
  analogWrite(PinBuzz, 20);
  delay(2); 
  if (!sound) analogWrite(PinBuzz, 0);  
  delay(leng); 
  analogWrite(PinBuzz, 0);   
}  
//****************************
void definecolors() {
...

This file has been truncated, please download it to see its full contents.

ArduinoMegaChess_DUE

Arduino
Sketch updated to Arduino DUE with ILI9486/XPT2046 320x480 pixels touchscreen.
//ArduinoMega Chess 1.0  (DUE 320x480 version)
//Sergey Urusov, ususovsv@gmail.com

#include <TFT_HX8357_Due.h> // Hardware-specific library
#include <stdint.h>
#include <URTouch.h>
#include <avr/pgmspace.h>
#include <Streaming.h>
#include <DueFlashStorage.h>

uint16_t BLACK,BLUE,RED,GREEN,CYAN,MAGENTA,YELLOW,WHITE,GRAY,DARK,GRAY2,BLACKF,WHITEF;

TFT_HX8357_Due tft = TFT_HX8357_Due();

URTouch  myTouch( 6, 5, 4, 3, 2);

DueFlashStorage dueFlashStorage;

int touchx,touchy,touchx0,touchy0,ntouch;         
unsigned long lasttouch;
#define MINPRESSURE 10
#define MAXPRESSURE 1000
const int PinBuzz = 12;
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 checkmatesearch=0; //   
boolean solving=false;
boolean choice=false;
boolean sound=1;
short cur_step=1; //  , 1....
short limit=0; //  , 0-7;
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
const int limits[8]={3,10,30,60,180,600,1800,100000};
//                   0  1  2  3   4   5    6      7 
step_type steps[MAXSTEPS]; //  
step_type cuts[MAXCUTS]; //  -
step_type lastbest;
int lastscore;
int minbeta,maxalpha;
int startweight;
int cur_level; //   ()
int start_var; //   , 1....
int cur_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,limittime,quitime=0;             
boolean drag;
signed char movedfig=0;
const uint8_t fig[6][32] PROGMEM={
{0x0, 0x0,  0x0,  0x0,  0x0,  0x0,  0x3,  0xC0, 0x7,  0xE0, 0x7,  0xE0, 0x3,  0xC0, 0x3,  0xC0,
0x7,  0xE0, 0x3,  0xC0, 0x3,  0xC0, 0x7,  0xE0, 0xF,  0xF0, 0xF,  0xF0, 0xF,  0xF0, 0x0,  0x0}, //
{0x0, 0x0,  0x3,  0x40, 0x7,  0xE0, 0xF,  0xF0, 0x1F, 0xF8, 0x3F, 0xFC, 0x39, 0xFC, 0x33, 0xFC,
0x7,  0xFC, 0xF,  0xF8, 0xF,  0xF0, 0x7,  0xE0, 0x3,  0xC0, 0x7,  0xE0, 0x1F, 0xF8, 0x0,  0x0},  //
{0x1, 0x80, 0x3,  0xC0, 0x1,  0x80, 0xF,  0xF0, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8,
0x1F, 0xF8, 0x1F, 0xF8, 0xF,  0xF0, 0x7,  0xE0, 0x3,  0xC0, 0x31, 0x8C, 0x7F, 0xFE, 0x0,  0x0}, // 
{0x0, 0x0,  0x19, 0x98, 0x1F, 0xF8, 0xF,  0xF0, 0xF,  0xF0, 0xF,  0xF0, 0xF,  0xF0, 0xF,  0xF0,
0xF,  0xF0, 0xF,  0xF0, 0xF,  0xF0, 0xF,  0xF0, 0xF,  0xF0, 0x1F, 0xF8, 0x1F, 0xF8, 0x0,  0x0}, //
{0x19, 0x98, 0xD9, 0x9B, 0xD9, 0x9B, 0xD9, 0x9B, 0x6D, 0xB6, 0x6D, 0xB6, 0x6D, 0xB6, 0x35, 0xAC,
0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x1F, 0xF8, 0xF,  0xF0, 0xF,  0xF0, 0x1F, 0xF8, 0x0,  0x0}, //
{0x1, 0x80, 0x1,  0x80, 0x79, 0x9E, 0x7D, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x7F, 0xFE, 0x3F, 0xFC, 0x3F, 0xFC, 0x1F, 0xF8, 0xF,  0xF0, 0xF,  0xF0, 0x1F, 0xF8, 0x0,  0x0}  //
};
const uint8_t fig_cont[6][32] PROGMEM={
{0x0, 0x0,  0x0,  0x0,  0x3,  0xC0, 0x4,  0x20, 0x8,  0x10, 0x8,  0x10, 0x4,  0x20, 0x4,  0x20,
0x8,  0x10, 0x4,  0x20, 0x4,  0x20, 0x8,  0x10, 0x10, 0x8,  0x10, 0x8,  0x10, 0x8,  0x1F, 0xF8}, //
{0x3, 0x40, 0x4,  0xA0, 0x8,  0x10, 0x12, 0x8,  0x20, 0x4,  0x40, 0x2,  0x46, 0x2,  0x4C, 0x2,
0x38, 0x2,  0x10, 0x4,  0x10, 0x8,  0x8,  0x10, 0x4,  0x20, 0x18, 0x18, 0x20, 0x4,  0x3F, 0xFC},  //
{0x2, 0x40, 0x4,  0x20, 0x6,  0x60, 0x10, 0x8,  0x21, 0x84, 0x21, 0x84, 0x21, 0x84, 0x27, 0xE4,
0x21, 0x84, 0x21, 0x84, 0x11, 0x88, 0x8,  0x10, 0x34, 0x2C, 0x4E, 0x72, 0x80, 0x1,  0xFF, 0xFF}, // 
{0x39, 0x9C, 0x26, 0x64, 0x20, 0x4,  0x1F, 0xF8, 0x10, 0x8,  0x10, 0x8,  0x10, 0x8,  0x10, 0x8,
0x10, 0x8,  0x10, 0x8,  0x10, 0x8,  0x10, 0x8,  0x1F, 0xF8, 0x20, 0x4,  0x20, 0x4,  0x3F, 0xFC}, //
{0x22, 0x24, 0x22, 0x24, 0x22, 0x24, 0x26, 0x64, 0x92, 0x49, 0x92, 0x49, 0x92, 0x49, 0x4A, 0x52,
0x40, 0x2,  0x40, 0x2,  0x5F, 0xFA, 0x20, 0x4,  0x1F, 0xF8, 0x10, 0x8,  0x20, 0x4,  0x3F, 0xFC}, //
{0x2, 0x40, 0x7A, 0x5E, 0x86, 0x61, 0x82, 0x41, 0x2,  0x40, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80,
0x80, 0x81, 0x41, 0x82, 0x5F, 0xFA, 0x20, 0x4,  0x1F, 0xF8, 0x10, 0x8,  0x20, 0x4,  0x3F, 0xFC}  //
};

const uint8_t fig24[6][72] PROGMEM={
{0x0, 0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x1E, 0x0,  0x0,  0x3F, 0x0,  0x80, 0x7F, 0x0,  0x80, 0x7F, 0x0,
0x80, 0x7F, 0x0,  0x0,  0x3F, 0x0,  0x0,  0x1C, 0x0,  0x0,  0x1C, 0x0,  0x80, 0xFF, 0x0,  0x80, 0xFF, 0x0,  0x0,  0x1C, 0x0,  0x0,  0x1C, 0x0,
0x0,  0x3E, 0x0,  0x0,  0x7F, 0x0,  0x80, 0xFF, 0x0,  0xC0, 0xFF, 0x1,  0xE0, 0xFF, 0x3,  0xE0, 0xFF, 0x3,  0xE0, 0xFF, 0x3,  0x0,  0x0,  0x0
}, //pawn
{0x0, 0x0,  0x0,  0x0,  0x6E, 0x0,  0x0,  0xFF, 0x0,  0x80, 0xFF, 0x1,  0x80, 0xFF, 0x3,  0xC0, 0xFF, 0x7,  0xE0, 0xFF, 0xF,  0xE0, 0xF9, 0xF,
0xF0, 0xF8, 0xF,  0xF0, 0xF8, 0xF,  0x60, 0xFC, 0xF,  0x0,  0xFE, 0xF,  0x0,  0xFF, 0xF,  0x0,  0xFF, 0x7,  0x0,  0xFF, 0x3,  0x0,  0xFF, 0x1,
0x0,  0xFE, 0x0,  0x0,  0x7C, 0x0,  0x0,  0x38, 0x0,  0x0,  0x38, 0x0,  0x0,  0x7C, 0x0,  0xF0, 0xFF, 0xF,  0xF0, 0xFF, 0xF,  0x0,  0x0,  0x0
}, //knight
{0x0, 0x0,  0x0,  0x0,  0x3C, 0x0,  0x0,  0x7E, 0x0,  0x0,  0x7E, 0x0,  0x0,  0x3C, 0x0,  0x0,  0x18, 0x0,  0x80, 0xFF, 0x1,  0xC0, 0xFF, 0x3,
0xE0, 0xFF, 0x7,  0xE0, 0xFF, 0x7,  0xE0, 0xFF, 0x7,  0xE0, 0xFF, 0x7,  0xE0, 0xFF, 0x7,  0xE0, 0xFF, 0x7,  0xE0, 0xFF, 0x7,  0xE0, 0xFF, 0x7,
0xE0, 0xFF, 0x7,  0xC0, 0xFF, 0x3,  0x80, 0xFF, 0x1,  0x0,  0xFF, 0x0,  0x8,  0x7E, 0x10, 0x1C, 0x3C, 0x38, 0xFE, 0xFF, 0x7F, 0x0,  0x0,  0x0
}, //bishop
{0x0, 0x0,  0x0,  0xF0, 0x3C, 0xF,  0xF0, 0x3C, 0xF,  0xF0, 0xFF, 0xF,  0xE0, 0xFF, 0x7,  0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,
0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,
0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,  0xC0, 0xFF, 0x3,  0xE0, 0xFF, 0x7,  0xF0, 0xFF, 0xF,  0xF0, 0xFF, 0xF,  0x0,  0x0,  0x0
}, //rook
{0x0, 0x0,  0x0,  0xEE, 0xBD, 0x77, 0xEE, 0xBD, 0x77, 0xC6, 0x18, 0x63, 0xC6, 0x18, 0x63, 0xC6, 0x18, 0x63, 0xCC, 0x18, 0x33, 0xCC, 0x18, 0x33,
0xCC, 0x18, 0x33, 0xCC, 0x18, 0x33, 0xCC, 0x18, 0x33, 0x98, 0x99, 0x19, 0x98, 0x99, 0x19, 0x98, 0x99, 0x19, 0x98, 0x99, 0x19, 0x98, 0x99, 0x19,
0x30, 0xFF, 0xC,  0xB0, 0xFF, 0xD,  0xF0, 0xFF, 0xF,  0xE0, 0xFF, 0x7,  0xE0, 0xFF, 0x7,  0xF0, 0xFF, 0xF,  0xF0, 0xFF, 0xF,  0x0,  0x0,  0x0
}, //queen
{0x0, 0x0,  0x0,  0x0,  0x18, 0x0,  0xF0, 0x18, 0xF,  0xF8, 0x99, 0x1F, 0xFC, 0xDB, 0x3F, 0xFE, 0xFF, 0x7F, 0xFE, 0xFF, 0x7F, 0xFE, 0xFF, 0x7F,
0xFE, 0xFF, 0x7F, 0xFE, 0xFF, 0x7F, 0xFE, 0xFF, 0x7F, 0xFE, 0xFF, 0x7F, 0xFE, 0xFF, 0x7F, 0xFE, 0xFF, 0x3F, 0xFC, 0xFF, 0x1F, 0xF8, 0xFF, 0x1F,
0xF0, 0xFF, 0xF,  0xE0, 0xFF, 0x7,  0xE0, 0xFF, 0x7,  0xC0, 0xFF, 0x3,  0xE0, 0xFF, 0x7,  0xF0, 0xFF, 0xF,  0xF0, 0xFF, 0xF,  0x0,  0x0,  0x0
} //king
};

const uint8_t fig24_cont[6][72] PROGMEM={
{0x0, 0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x1C, 0x0,  0x0,  0x22, 0x0,  0x0,  0x41, 0x0,  0x80, 0x80, 0x0,  0x80, 0x80, 0x0,
0x80, 0x80, 0x0,  0x0,  0x41, 0x0,  0x0,  0x22, 0x0,  0xC0, 0xE3, 0x1,  0x40, 0x0,  0x1,  0x40, 0x0,  0x1,  0xC0, 0xE3, 0x1,  0x0,  0x22, 0x0,
0x0,  0x41, 0x0,  0x80, 0x80, 0x0,  0x40, 0x0,  0x1,  0x20, 0x0,  0x2,  0x10, 0x0,  0x4,  0x10, 0x0,  0x4,  0x10, 0x0,  0x4,  0xF0, 0xFF, 0x7
}, //pawn
{0x0, 0x6E, 0x0,  0x0,  0x91, 0x0,  0x80, 0x0,  0x1,  0x40, 0x2,  0x2,  0x40, 0x0,  0x4,  0x20, 0x0,  0x8,  0x10, 0x0,  0x10, 0x10, 0x6,  0x10,
0x8,  0x5,  0x10, 0x8,  0x5,  0x10, 0x90, 0x2,  0x10, 0x60, 0x1,  0x10, 0x80, 0x0,  0x10, 0x80, 0x0,  0x8,  0x80, 0x0,  0x4,  0x80, 0x0,  0x2,
0x0,  0x1,  0x1,  0x0,  0x82, 0x0,  0x0,  0x44, 0x0,  0x0,  0x44, 0x0,  0xF8, 0x83, 0x1F, 0x8,  0x0,  0x10, 0x8,  0x0,  0x10, 0xF8, 0xFF, 0x1F
}, //knight
{0x0, 0x3C, 0x0,  0x0,  0x42, 0x0,  0x0,  0x81, 0x0,  0x0,  0x81, 0x0,  0x0,  0x42, 0x0,  0x80, 0xE7, 0x1,  0x40, 0x0,  0x2,  0x20, 0x18, 0x4,
0x10, 0x18, 0x8,  0x10, 0x18, 0x8,  0x10, 0x18, 0x8,  0x90, 0xFF, 0x9,  0x90, 0xFF, 0x9,  0x10, 0x18, 0x8,  0x10, 0x18, 0x8,  0x10, 0x18, 0x8,
0x10, 0x18, 0x8,  0x20, 0x18, 0x4,  0x40, 0x18, 0x2,  0x88, 0x0,  0x11, 0x14, 0x81, 0x28, 0xE2, 0xC3, 0x47, 0x1,  0x0,  0x80, 0xFF, 0xFF, 0xFF
}, //bishop
{0xF8, 0x7E, 0x1F, 0x8,  0xC3, 0x10, 0x8,  0xC3, 0x10, 0x8,  0x0,  0x10, 0x10, 0x0,  0x8,  0xE0, 0xFF, 0x7,  0x20, 0x0,  0x4,  0x20, 0x0,  0x4,
0x20, 0x0,  0x4,  0x20, 0x0,  0x4,  0x20, 0x0,  0x4,  0x20, 0x0,  0x4,  0x20, 0x0,  0x4,  0x20, 0x0,  0x4,  0x20, 0x0,  0x4,  0x20, 0x0,  0x4,
0x20, 0x0,  0x4,  0x20, 0x0,  0x4,  0x20, 0x0,  0x4,  0xE0, 0xFF, 0x7,  0x10, 0x0,  0x8,  0x8,  0x0,  0x10, 0x8,  0x0,  0x10, 0xF8, 0xFF, 0x1F
}, //rook
{0xEF, 0xBD, 0xF7, 0x11, 0x42, 0x88, 0x11, 0x42, 0x88, 0x29, 0xA5, 0x94, 0x29, 0xA5, 0x94, 0x29, 0xA5, 0x94, 0x32, 0xA5, 0x4C, 0x32, 0xA5, 0x4C,
0x32, 0xA5, 0x4C, 0x32, 0xA5, 0x4C, 0x32, 0xA5, 0x4C, 0x64, 0x66, 0x26, 0x64, 0x66, 0x26, 0x64, 0x66, 0x26, 0x64, 0x66, 0x26, 0x64, 0x66, 0x26,
0xC8, 0x0,  0x13, 0x48, 0x0,  0x12, 0x8,  0x0,  0x10, 0x10, 0x0,  0x8,  0xF0, 0xFF, 0xF,  0x8,  0x0,  0x10, 0x8,  0x0,  0x10, 0xF8, 0xFF, 0x1F
}, //queen
{0x0, 0x18, 0x0,  0xF0, 0x24, 0xF,  0x8,  0xA5, 0x10, 0x4,  0x66, 0x20, 0x2,  0x24, 0x40, 0x1,  0x24, 0x80, 0x1,  0x18, 0x80, 0x1,  0x18, 0x80,
0x1,  0x18, 0x80, 0x1,  0x18, 0x80, 0x1,  0x18, 0x80, 0x1,  0x18, 0x80, 0x1,  0x18, 0x80, 0x1,  0x18, 0x40, 0x2,  0x18, 0x20, 0x4,  0x18, 0x20,
0xE8, 0xFF, 0x17, 0x10, 0x0,  0x8,  0x10, 0x0,  0x8,  0x20, 0x0,  0x4,  0xF0, 0xFF, 0xF,  0x8,  0x0,  0x10, 0x8,  0x0,  0x10, 0xF8, 0xFF, 0x1F
} //king
};


const uint8_t issound[2][32] PROGMEM={
{0x0, 0x0,  0x0,  0x0,  0x0,  0x32, 0x0,  0x54, 0x0,  0x98, 0x1F, 0x10, 0x10, 0x30, 0x10, 0x50,
0x10, 0x90, 0x11, 0x10, 0x1F, 0x10, 0x4,  0x90, 0x8,  0x50, 0x10, 0x30, 0x0,  0x0,  0x0,  0x0},
{0x0, 0x0,  0x0,  0x0,  0x0,  0x30, 0x0,  0x50, 0x0,  0x90, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x1F, 0x10, 0x0,  0x90, 0x0,  0x50, 0x0,  0x30, 0x0,  0x0,  0x0,  0x0}
};
const uint8_t iswb[2][32] PROGMEM={
{0x0,  0x0,  0x0,  0x0,  0x3,  0xC0, 0x4,  0x20, 0x8,  0x10, 0x8,  0x10, 0x4,  0x20, 0x4,  0x20,
0x8,  0x10, 0x4,  0x20, 0x4,  0x20, 0x8,  0x10, 0x10, 0x8,  0x10, 0x8,  0x1F, 0xF8, 0x0,  0x0},
{0x0,  0x0,  0x0,  0x0,  0x3,  0xC0, 0x7,  0xE0, 0xF,  0xF0, 0xF,  0xF0, 0x7,  0xE0, 0x7,  0xE0,
0xF,  0xF0, 0x7,  0xE0, 0x7,  0xE0, 0xF,  0xF0, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x0,  0x0}
};
const uint8_t iscm[2][32] PROGMEM={
{0x0, 0x0,  0x7,  0xE0, 0xC,  0x30, 0xC,  0x30, 0xC,  0x30, 0xC,  0x30, 0x0,  0x30, 0x0,  0x60,
0x0,  0xC0, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x0,  0x0,  0x1,  0x80, 0x1,  0x80, 0x0,  0x0},
{0x0,  0x0,  0x3F, 0x0,  0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x1,  0x80, 0x3,  0x0,
0x6,  0x24, 0xC,  0x24, 0xC,  0xFF, 0xC,  0x24, 0x0,  0xFF, 0xC,  0x24, 0xC,  0x24, 0x0,  0x0}
};
const uint8_t islimit[8][32] PROGMEM={
{0x0, 0x0,  0x3,  0xC0, 0x6,  0x60, 0x0,  0x60, 0x1,  0xC0, 0x0,  0x60, 0x6,  0x60, 0x6,  0x60,
0x3,  0xC0, 0x0,  0x0,  0x1D, 0xDC, 0x11, 0x10, 0x1D, 0xD0, 0x5,  0x10, 0x1D, 0xDC, 0x0,  0x0},
{0x0, 0x0,  0x4,  0x70, 0xC,  0x88, 0x4,  0x88, 0x4,  0x88, 0x4,  0x88, 0x4,  0x88, 0x4,  0x88,
0xE,  0x70, 0x0,  0x0,  0x1D, 0xDC, 0x11, 0x10, 0x1D, 0xD0, 0x5,  0x10, 0x1D, 0xDC, 0x0,  0x0},
{0x0, 0x0,  0xC,  0x70, 0x12, 0x88, 0x2,  0x88, 0xC,  0x88, 0x2,  0x88, 0x2,  0x88, 0x12, 0x88,
0xC,  0x70, 0x0,  0x0,  0x1D, 0xDC, 0x11, 0x10, 0x1D, 0xD0, 0x5,  0x10, 0x1D, 0xDC, 0x0,  0x0},
{0x0, 0x0,  0x1,  0x80, 0x3,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80,
0x3,  0xC0, 0x0,  0x0,  0x22, 0xA4, 0x36, 0xA4, 0x2A, 0xB4, 0x22, 0xAC, 0x22, 0xA4, 0x0,  0x0},
{0x0, 0x0,  0x3,  0xC0, 0x6,  0x60, 0x0,  0x60, 0x1,  0xC0, 0x0,  0x60, 0x6,  0x60, 0x6,  0x60,
0x3,  0xC0, 0x0,  0x0,  0x22, 0xA4, 0x36, 0xA4, 0x2A, 0xB4, 0x22, 0xAC, 0x22, 0xA4, 0x0,  0x0},
{0x0, 0x0,  0xC,  0x78, 0x1C, 0xCC, 0xC,  0xCC, 0xC,  0xCC, 0xC,  0xCC, 0xC,  0xCC, 0xC,  0xCC,
0x1E, 0x78, 0x0,  0x0,  0x22, 0xA4, 0x36, 0xA4, 0x2A, 0xB4, 0x22, 0xAC, 0x22, 0xA4, 0x0,  0x0},
{0x0, 0x0,  0x1C, 0x78, 0x36, 0xCC, 0x6,  0xCC, 0x1C, 0xCC, 0x6,  0xCC, 0x36, 0xCC, 0x36, 0xCC,
0x1C, 0x78, 0x0,  0x0,  0x22, 0xA4, 0x36, 0xA4, 0x2A, 0xB4, 0x22, 0xAC, 0x22, 0xA4, 0x0,  0x0},
{0x0, 0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x3C, 0x3C, 0x7E, 0x7E, 0x63, 0xC6, 0x61, 0x86,
0x63, 0xC6, 0x66, 0x66, 0x3C, 0x3C, 0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0}
};
const uint8_t isdesc[2][32] PROGMEM={
{0x0,  0x0,  0xE3, 0x8E, 0xE3, 0x8E, 0xE3, 0x8E, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0xE3, 0x8E,
0xE3, 0x8E, 0xE3, 0x8E, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0xE3, 0x8E, 0xE3, 0x8E, 0xE3, 0x8E},
{0x0,  0x0,  0x0,  0x4,  0x0,  0xE,  0x0,  0xE,  0x0,  0x1C, 0x0,  0x1C, 0x0,  0x38, 0x0,  0x30,
0x30, 0x70, 0x78, 0xE0, 0x3C, 0xC0, 0x1F, 0xC0, 0xF,  0x80, 0x7,  0x0,  0x2,  0x0,  0x0,  0x0}

};
const uint8_t isback[32] PROGMEM={
0x0,  0x0,  0x0,  0x0,  0x20, 0xF0, 0x31, 0xF8, 0x3B, 0xFC, 0x3F, 0x8E, 0x3F, 0xE,  0x3F, 0xE,
0x3F, 0x8E, 0x3F, 0xCE, 0x0,  0xE,  0x0,  0xE,  0x0,  0x1C, 0x0,  0x38, 0x0,  0x70, 0x0,  0x0
};
const uint8_t issave[32] PROGMEM={
0x1,  0x80, 0x3,  0xC0, 0x7,  0xE0, 0x7,  0xE0, 0x3,  0xC0, 0x3F, 0xFC, 0x23, 0xC4, 0x23, 0xC4,
0x23, 0xC4, 0x23, 0xC4, 0x23, 0xC4, 0x23, 0xC4, 0x20, 0x4,  0x20, 0x4,  0x3F, 0xFC, 0x0,  0x0
};
const uint8_t isload[32] PROGMEM={
0x0,  0x0,  0x3,  0xC0, 0x3,  0xC0, 0x3,  0xC0, 0x3,  0xC0, 0x3F, 0xFC, 0x23, 0xC4, 0x23, 0xC4,
0x23, 0xC4, 0x27, 0xE4, 0x27, 0xE4, 0x23, 0xC4, 0x21, 0x84, 0x20, 0x4,  0x3F, 0xFC, 0x0,  0x0
};
const uint8_t isempty[32] PROGMEM={
0xFF,  0xFF, 0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,
0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0xFF, 0xFF
};
const uint8_t isinit[32] PROGMEM={
0xFF,  0xFF, 0x80, 0x1,  0x80, 0x1,  0xFF, 0xFF, 0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,
0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0x80, 0x1,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
const uint8_t isplay[32] PROGMEM={
0x0,  0x0,  0x3,  0xC0, 0x3,  0xC0, 0x3,  0xC0, 0x1,  0x80, 0x23, 0xF8, 0x17, 0xC8, 0xB,  0xC8,
0x3,  0xC0, 0x3,  0xC0, 0x2,  0x40, 0x4,  0x40, 0x4,  0x38, 0x4,  0x8,  0xC,  0x0,  0x0,  0x0
};
const uint8_t isrotate[2][32] PROGMEM={
{0x0,  0x0,  0x0,  0x0,  0x3F, 0xFC, 0x20, 0x4,  0x20, 0x4,  0x20, 0x4,  0x20, 0x4,  0x20, 0x4,
0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x0,  0x0,  0x0,  0x0},
{0x0, 0x0,  0x0,  0x0,  0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xFC,
0x20, 0x4,  0x20, 0x4,  0x20, 0x4,  0x20, 0x4,  0x20, 0x4,  0x3F, 0xFC, 0x0,  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}}  
};

volatile static int32_t toggles;                    // number of ups/downs in a tone burst 

void tone(int toneFreq,int32_t duration){                        // duration in ms
  const uint32_t rcVal = VARIANT_MCK/256/toneFreq;  // target value for counter, before it resets (= 82 for 4kHz)
  toggles = 2*toneFreq*duration/1000;               // calculate no of waveform edges (rises/falls) for the tone burst
  setupTC(TC1,0,TC3_IRQn,toneFreq);                 // Start Timer/Counter 1, channel 0, interrupt, frequency
  }
  
void setupTC(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t freq){
  pmc_set_writeprotect(false);                       // disable write protection of timer registers
  pmc_enable_periph_clk((uint32_t) irq);             // enable clock / interrupt 
  TC_Configure(tc, channel,            
               TC_CMR_TCCLKS_TIMER_CLOCK4 |          // TIMER_CLOCK4: MCK/128=656,250Hz. 16 bits so 656,250/65,536=~10Hz/bit
               TC_CMR_WAVE |                         // Waveform mode
               TC_CMR_WAVSEL_UP_RC );                // Counter running up and reset when = Register C value (rcVal)
  const uint32_t rcVal = VARIANT_MCK/256/freq;       // target value for counter, before it resets
  TC_SetRC(tc, channel, rcVal);
  TC_Start(tc, channel);
  (*tc).TC_CHANNEL[channel].TC_IER =  TC_IER_CPCS;   // IER: CPCS bit enables RC compare interrupt when set 
  (*tc).TC_CHANNEL[channel].TC_IDR = ~TC_IER_CPCS;   // IDR: clear CPCS bit = don't disable RC compare interrupt
  NVIC_EnableIRQ(irq);                               // Enable TC3_IRQn in the Nested Vector Interrupt Controller)
  }

void TC3_Handler(void){                              // timer ISR  TC1 ch 0
  TC_GetStatus(TC1,0);
  if (toggles != 0){
    digitalWrite(PinBuzz,!digitalRead(PinBuzz));     // invert the pin state (i.e toggle)
    if (toggles > 0) toggles--;
    } 
  }
  
 void noTone(){
  TC_Stop(TC1,0);                               // stop timer
  digitalWrite(PinBuzz,LOW);                         // no signal on pin
 } 

//******
class Button {
public:
int bx,by,bw,bh,bshift;
String bs;
const uint8_t* bp;
 Button(int x,int y,int w,int h,String s,const uint8_t* p, int shift);
 void Show(int shift); 
 void Show(String s); 
 void Hide();
 boolean IsPressed(int xc, int yc);
private:
boolean active;
 void ishow(uint16_t textcolor,uint16_t backcolor);
};
Button::Button(int x,int y,int w,int h,String s,const uint8_t* p=NULL, int shift=0) {
  bx=x; by=y; bw=w; bh=h; bs=s; bp=p; bshift=shift;
};
void Button::Show(int shift=0) {
 bshift=shift; 
 active=true;
 ishow(WHITE,DARK);  
};
void Button::Show(String s) {
 bs=s; 
 active=true;
 ishow(WHITE,DARK);  
};
void Button::Hide() { 
 active=false; 
 ishow(GRAY,DARK);  
};
boolean Button::IsPressed(int xc, int yc) {
  if (active&&abs(bx+bw/2-xc)<bw/2&&abs(by+bh/2-yc)<bh/2) {
    ishow(WHITE,GRAY); 
    touchx=0; touchy=0;        
    return true;
  } 
  return false;
};  
void Button::ishow(uint16_t textcolor,uint16_t backcolor) {  
  tft.fillRoundRect(bx+2,by+2,bw,bh,3,GRAY2);               
  tft.fillRoundRect(bx,by,bw,bh,3,backcolor);               
  tft.setTextColor(textcolor);
  tft.setTextSize(1);    
  tft.setCursor(bx+(bw-bs.length()*6)/2,by+(bh-8)/2);       
  if (bp!=NULL) { 
   tft.drawBitmap(1+bx+(bw-16)/2, by+(bh-16)/2, bp+bshift*32, 16, 16,textcolor);          
  } 
  else  tft.print(bs);    
}
Button BAction(320, 285, 70, 30, "START");
Button BBW(402, 285, 30, 30, "",&iswb[0][0]);
Button BBack(444, 285, 30, 30, "",&isback[0]);
Button BInit(444, 285, 30, 30, "",&isinit[0]);
Button BLimit(320, 245, 26, 30, "",&islimit[0][0]);
Button BEmpty(320, 245, 26, 30, "",&isempty[0]);
Button BRotate(352, 245, 26, 30, "",&isrotate[0][0]);
Button BPlay(352, 245, 26, 30, "",&isplay[0]);
Button BCM(384, 245, 26, 30, "",&iscm[0][0]);
Button BSave(384, 245, 26, 30, "",&issave[0]);
Button BDesc(416, 245, 26, 30, "",&isdesc[0][0]);
Button BSound(448, 245, 26, 30, "",&issound[0][0]);
Button BLoad(448, 245, 26, 30, "",&isload[0]);

union byte2_t {
         uint8_t b[2];
         struct {   
          short s;
         }; 
        };

byte2_t byte2;           
//********************************** 
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;  
  //if (color!=pixelfg) tft.fgColor(color);
  for(j=0; j<h; j++) {
    for(i=0; i<w; i++ ) {      
        if(pgm_read_byte(bitmap + j * byteWidth + i / 8) & (1 << (i % 8))) {                
        tft.drawPixel(x+i, y+j, color);
      }      
    }
  }
}
//****************************
void deletebuttons() {  
  tft.fillRect(320,245,160,75,BLACK);             
}

//****************************
void clearstatus() {
  tft.fillRect(320,225,160,20,BLACK);             
  tft.drawFastHLine(10,312,300,BLACK);   
  tft.drawFastHLine(10,315,300,BLACK);  
}  
//****************************
void setup() {      
  Serial.begin(57600);  
  Serial.println(F("Start"));     
  pinMode(13, OUTPUT);  
  tft.init(); 
  tft.setRotation(1);  
  myTouch.InitTouch();
  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;
  }     
  initboard();
}
//****************************
void initboard() {        
  for (int i=0;i<8;i++)
   for (int j=0;j<8;j++) poledisp[j][i]=-100; //          
  tft.fillScreen(BLACK);      
  tft.setTextColor(GRAY);
  tft.setTextSize(1);  
  for (int j=1;j<9;j++) {
   tft.setCursor(2,j*37-20);  
   if (rotate) tft.print(j); else tft.print(9-j);
  }
  for (byte i=1;i<9;i++) { 
   tft.setCursor(i*37-8,300);    
   if (rotate) tft.print(char(96+9-i)); else tft.print(char(96+i));  
  }         
  initscreen();          
}
//****************************
void initscreen() {        
 show_board();   
 show_steps();      
 BAction.Show("START");
 BBW.Show(cur_step%2);   
 if (cur_step>1) BBack.Show(); else BBack.Hide();
 BSave.Hide();
 BLoad.Hide();
 BInit.Hide();
 BBack.Show();  
 BLimit.Show();         
 BPlay.Hide();           
 BRotate.Show(rotate);           
 BEmpty.Hide();
 BLimit.Show(limit);  
 BCM.Show(checkmatesearch); 
 BDesc.Show(choice); 
 BSound.Show(sound);    
}
//****************************
void loop() {        
  gui();  
  if (solving) {        
    int len=70;
    if (!sound) len=2;  
    for (int i=1;i<4;i++) { 
      tone(400+300*i,len); 
      delay(70); }
    lastscore=solve_step();               
    float tim=float(millis()-starttime)/1000;
    for (int i=3;i>=1;i--) { 
       tone(400+300*i,len); 
     delay(70); }
    if (!checkmatesearch&&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) {       
      tft.setTextSize(1);    
      tft.setTextColor(GREEN); 
      tft.setCursor(322,230);    
      if (lastscore<9999) {
       tft.print("# in "); 
       tft.print((9999-lastscore)/2+1); tft.print(F(" st"));        
      } else tft.print("Checkmate"); 
    } else if (lastscore<-9000) {
      tft.setTextSize(1);    
      tft.setTextColor(RED); 
      tft.setCursor(322,230);    
      tft.print("GIVE UP!");       
      show_steps();
    } else if (lastscore==8999) { //Draw
      tft.setTextSize(1);    
      tft.setTextColor(YELLOW); 
      tft.setCursor(322,230);    
      tft.print("Draw");       
    }         
    tft.setTextSize(1);    
    tft.setTextColor(GRAY); 
    tft.setCursor(322,230);    
    tft.print(tim,0); 
    tft.print("s ");    
    if (abs(lastscore)<5000) {   
     tft.print("=");
     tft.print(lastscore);     
    }
    tft.setCursor(390,230);        
    tft.print(count); 
    tft.print(" pos");   
    Serial.print(F("Positions estimated=")); Serial.println(count);
    Serial.print(F("Time=")); Serial.print(tim,1); Serial.println("s");    
  }
  delay(10);  
  
  
}

//********************************** 
void load_choice() {
  for (int i=0;i<7;i++) 
   if (cur_step%2==1) polechoice[i]=i; else polechoice[i]=-i;
}
//********************************** 
void show_choice() {
uint16_t color,color_cont;    
  for (int i=0;i<7;i++) {
    color=BLACKF;
    if (i%2==0) color=WHITEF;              
    tft.fillRect(416,i*25+35,25,25,color);    
    color=DARK;
    if (i==cur_choice) color=WHITE;   
    tft.drawRect(416,i*25+35,25,25,color);
    color=BLACK; color_cont=GRAY;
    if (polechoice[i]>0) { color=WHITE; color_cont=BLACK; }
    if (polechoice[i]!=0) {
     tft.drawBitmap(420, i*25+39,&fig[abs(polechoice[i])-1][0], 16, 16,color);          
     tft.drawBitmap(420, i*25+39,&fig_cont[abs(polechoice[i])-1][0], 16, 16,color_cont);     
    }
  }  
}
//********************************** 
void animate_step(int nstep, boolean hide) {   
 if (!hide&&nstep-1>0&&steps[nstep-1].fig1!=0) animate_step(nstep-1,true); 
 if (nstep-1<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; 
 di=di/abs(di); 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) tft.drawRect(i*37+13,j*37+1,36,36,WHITE);    
    else tft.drawRect((7-i)*37+13,(7-j)*37+1,36,36,WHITE);    
  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) tft.drawRect(i*37+13,j*37+1,36,36,WHITE);    
   else tft.drawRect((7-i)*37+13,(7-j)*37+1,36,36,WHITE);     
}
//********************************** 
boolean load_usb() {
signed 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]=(signed 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; }
   else if (s=='b') { cur_step=2; load=true; }
     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;  
}
//********************************** 
void play() {
 BAction.Show("STOP"); 
 BSave.Hide();
 BBW.Hide();
 BLoad.Hide();
 BInit.Hide();   
 BPlay.Hide();   
 BEmpty.Hide();
 BDesc.Hide(); 
 clearstatus();       
 for (int i=cur_step-1;i>0;i--) {
  if (steps[i].fig1!=0) backstep(i);
 }
 show_board();
 show_steps();
 boolean st=false;
 unsigned long tim=millis();
 int i=1;
 while (i<cur_step) {
  if (steps[i].fig1!=0) movestep(i);   
  myTouch.calibrateRead();
  int x=map(myTouch.TP_X,3850,250,0,479);
  int y=map(myTouch.TP_Y,280,3850,0,319);  
  if (myTouch.TP_X!=0&&myTouch.TP_Y!=4095)
    if (BAction.IsPressed(x,y)) { st=true; BAction.Show(); } 
  if (millis()-tim>2000||st) {
    tim=millis();
    i++;
    show_board();
    beep(20);              
  }  
 }       
 choice=0; 
 beep(200);                
 kingpositions();        
 clearstatus();
 initscreen();                               
}
//********************************** 
void gui() {   
  myTouch.calibrateRead();
  int x=map(myTouch.TP_X,3850,250,0,479);
  int y=map(myTouch.TP_Y,280,3850,0,319);  
  if (((abs(x-touchx)>5||abs(y-touchy)>5)||drag)&&myTouch.TP_X!=0&&myTouch.TP_Y!=4095) {    
  //  tft.drawPixel(x,y,CYAN);    
  //  Serial.println(x);
  //  Serial.println(y);  
    touchx=x;
    touchy=y;             
    if (solving) {
      if (BAction.IsPressed(x,y)) { //        
        beep(100); 
        solving=false;  
        BAction.Show("stopping");        
        BAction.Hide();        
        return;    
      }   
    } else { //not solve
      if (BAction.IsPressed(x,y)) { // 
       if (!choice) {
        delay(100);        
        solving=true;   
        BAction.Show();         
        animate_step(cur_step-1,true);
        return;
       } else { //   USB
        delay(100);
        BAction.Hide(); 
        BSave.Hide();
        BBW.Hide();
        BLoad.Hide();
        BInit.Hide();   
        BPlay.Hide();   
        BEmpty.Hide();
        BDesc.Hide();        
        show_steps();
        choice=0;         
        if (!load_usb()) return;
        beep(200);                
        kingpositions();        
        clearstatus();
        initscreen();                              
       }
      } else if (BBW.IsPressed(x,y)) {   //-    
       beep(100);         
       if (cur_step==1) cur_step=2;
        else if (cur_step==2) cur_step=1;
         else if (cur_step%2==0) cur_step--; else cur_step++;       
       BBW.Show(cur_step%2);        
       if (choice) { load_choice(); show_choice(); }
       return;
      } else if (cur_step>1&&BBack.IsPressed(x,y)) {  //      
       beep(100);                
       cur_step--;       
       animate_step(cur_step,true);
       lastscore=0;              
       backstep(cur_step);               
       steps[cur_step].fig1=0;
       show_board();       
       show_steps();       
       if (cur_step>1) BBack.Show(); else BBack.Hide();      
       BBW.Show(cur_step%2);        
       clearstatus();       
       return;        
      } else if (BLimit.IsPressed(x,y)) {    //   
       beep(100);  
       limit++; if (limit>7) limit=0;       
       BLimit.Show(limit);        
       return; 
      } else if (BCM.IsPressed(x,y)) {   //                   
       beep(100); 
       checkmatesearch=!checkmatesearch; 
       BCM.Show(checkmatesearch);        
       if (!checkmatesearch) steps[cur_step].fig1=0;
       lastscore=0;
       show_steps();
       return; 
      } else if (BRotate.IsPressed(x,y)) {   //                   
       beep(100); 
       rotate=!rotate; 
       BRotate.Show(rotate);              
       initboard();       
       return;  
      } else if (BSound.IsPressed(x,y)) {   //                  
       if (sound==1) { beep(100); sound=0; } else { sound=1; beep(200); }       
       BSound.Show(sound);        
       return;
      } else if (BDesc.IsPressed(x,y)) {  //
       beep(100); 
       if (!choice) {
        choice=1;
        cur_choice=1;
        load_choice();
        show_choice();        
        BAction.Show("USB(FEN)");         
        BBack.Hide();  
        BInit.Show();  
        BSave.Show();  
        BLimit.Hide(); 
        BEmpty.Show();  
        BRotate.Hide();    
        BPlay.Show();    
        BCM.Hide();          
        BSound.Hide(); 
        BSave.Show();  
        BLoad.Show();    
       } else {
        choice=0;  
        lastscore=0;
        clearstatus();
        kingpositions();        
        initscreen();        
       }       
       BDesc.Show(choice);                                    
       return;
      } else if (BInit.IsPressed(x,y)) {  //        
        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]);         
        choice=0;         
        kingpositions();        
        clearstatus();
        initscreen();                     
      } else if (BEmpty.IsPressed(x,y)) {  //        
        beep(200);        
        cur_step=1;        
        clearstatus();        
        steps[1].fig1=0; steps[2].fig1=0;
        for (int i=0;i<8;i++)
         for (int j=0;j<8;j++) pole[j][i]=(signed char)pgm_read_byte(&polezero[j][i]);                 
        BEmpty.Show();   
        show_board();          
      } else if (BSave.IsPressed(x,y)) { 
        beep(100); 
        for (int i=0;i<8;i++)
         for (int j=0;j<8;j++) dueFlashStorage.write(i*8+j,pole[j][i]);         
        byte2.s=cur_step;
        dueFlashStorage.write(65,byte2.b[0]);        
        dueFlashStorage.write(64,byte2.b[1]);        
        byte2.s=limit;
        dueFlashStorage.write(67,byte2.b[0]);        
        dueFlashStorage.write(66,byte2.b[1]);                
        step_type st;        
        for (int i=1;i<cur_step;i++) {           
          st=steps[i];          
          dueFlashStorage.write(68+i*sizeof(step_type), (byte *)&st, sizeof(step_type));                     
        }
        BSave.Show(); 
      } else if (BLoad.IsPressed(x,y)) { 
        beep(200); 
        for (int i=0;i<8;i++)
         for (int j=0;j<8;j++) pole[j][i]=dueFlashStorage.read(i*8+j);         
        byte2.b[0]=dueFlashStorage.read(65);                 
        byte2.b[1]=dueFlashStorage.read(64);                 
        cur_step=byte2.s;
        if (cur_step<0||cur_step>400) cur_step=1;                
        byte2.b[0]=dueFlashStorage.read(67);                 
        byte2.b[1]=dueFlashStorage.read(66);                         
        limit=byte2.s;
        if (limit<0||limit>7) limit=0;        
        step_type st;
        for (int i=1;i<cur_step;i++) {           
           memcpy(&st, dueFlashStorage.readAddress(68+i*sizeof(step_type)), sizeof(step_type));           
           steps[i]=st;
        }        
        steps[0].fig1=0;         
        steps[cur_step].fig1=0;         
        choice=0;                 
        kingpositions();
        clearstatus();
        initscreen();                                   
      } else if (BPlay.IsPressed(x,y)) {    //   
       beep(100);  
       BPlay.Show();        
       play();       
       return; 
      }
      if (!choice&&ntouch==0) {
       touchx0=touchx;
       touchy0=touchy;
       signed char x1=touchy0/37; 
       signed char y1=(touchx0-10)/37;       
       if (rotate) { x1=7-x1; y1=7-y1; }
       if (getpole(y1,x1)&&(cur_step%2==1&&pole[x1][y1]>0||cur_step%2==0&&pole[x1][y1]<0)) {        
        signed char p=pole[x1][y1];        
        movedfig=p;
        drag=true;        
        pole[x1][y1]=0;
        show_fig(y1,x1);
        pole[x1][y1]=p;                
       } else drag=false; 
      }       
      ntouch++;
      if (drag&&ntouch>1) {
          uint16_t buf[256];          
          int x1=touchy0/37; 
          int y1=(touchx0-10)/37;       
          if (rotate) { x1=7-x1; y1=7-y1; }       
          if (abs(pole[x1][y1])>0&&(cur_step%2==1&&pole[x1][y1]>0||cur_step%2==0&&pole[x1][y1]<0)) {
            int x2=touchy/37; 
            int y2=(touchx-10)/37;       
            if (getpole(x2,y2)) {                       
             signed char p=pole[x2][y2];                
             pole[x2][y2]=movedfig;
             show_fig(y2,x2);
             delay(30);             
             pole[x2][y2]=p; 
             show_fig(y2,x2);               
             if (x2==x1&&y2==y1) {
               pole[x2][y2]=0; 
               show_fig(y2,x2);               
               pole[x2][y2]=p; 
             }
            } 
       //   for (int i=0;i<16;i++)
       //     for (int j=0;j<16;j++) buf[i*16+j]=tft.readPixel(touchx-8+i,touchy-8+j);
          //buf[0]=tft.readPixel(touchx-8,touchy-8);  
       //   uint16_t color,color_cont;    
       //   color=BLACK; color_cont=GRAY;
       //   if (pole[x1][y1]>0) { color=WHITE; color_cont=BLACK; }             
       //   tft.drawBitmap(touchx-8, touchy-8,&fig[abs(pole[x1][y1])-1][0], 16, 16,color);          
       //   tft.drawBitmap(touchx-8, touchy-8,&fig_cont[abs(pole[x1][y1])-1][0], 16, 16,color_cont);       
       //   delay(30);
       //   for (int i=0;i<16;i++)
       //     for (int j=0;j<16;j++) tft.drawPixel(touchx-8+i,touchy-8+j,buf[i*16+j]);            
          }  
      } else if (choice) {
        int x1=touchy/37; 
        int y1=(touchx-10)/37;                     
        if (rotate) { x1=7-x1; y1=7-y1; } 
        if (touchy+touchx!=0&&choice&&getpole(y1,x1)) {        
         pole[x1][y1]=polechoice[cur_choice];
         show_board(); 
        }       
        if (touchx>=416&&touchx<=441&&touchy>=35&&touchy<=210) {
         cur_choice=(touchy-35)/25;
         show_choice();                       
        }
      }
      lasttouch=millis();
    } //not solve      
    if (!drag) { beep(10); ntouch=0; animate_step(cur_step-1,true); }     
  } else { //touching
    if (!solving&&!choice&&drag!=0&&ntouch>0&&(myTouch.TP_X==0||myTouch.TP_Y==4095)&&millis()-lasttouch>300) { //drag 
     signed char x1=touchy0/37; 
     signed char y1=(touchx0-10)/37;     
     signed char x2=touchy/37; 
     signed char y2=(touchx-10)/37; 
     if (rotate) { x1=7-x1; y1=7-y1; x2=7-x2; y2=7-y2; }    
     if (getpole(y1,x1)) show_fig(y1,x1);
     if (getpole(y1,x1)&&getpole(y2,x2)) {      
       start_var=cur_step+1;
       only_action=false;   
       load_variants(cur_step);     
       for (int i=cur_step+1;i<cur_step+cur_var+1;i++)  
        if (steps[i].x1==x1&&steps[i].y1==y1&&steps[i].x2==x2&&steps[i].y2==y2) {
         steps[cur_step]=steps[i];          
         movestep(cur_step); cur_step++; steps[cur_step].fig1=0;
         int len=100;
         if (!sound) len=2;  
         for (int i=2;i>=1;i--) {
          tone(400+300*i,len); 
          delay(100); }
         initscreen();
         animate_step(cur_step-1,false);
...

This file has been truncated, please download it to see its full contents.

Credits

Sergey_Urusov

Sergey_Urusov

0 projects • 72 followers

Comments