Total novice: text-based chess-opening database

edited February 2017 in Questions about Code

Hi everybody!

I'm quite new to programming, and completely new to processing.

I have written down my chess opening repertoire (with hand on paper) for a couple of moves, and thought, it would be great, if I had a simple program, that tells me, depending on the opponents move (lets say I play with white), which move I (usually) play in response.

Lets assume, you know about chess notation, if my first move is 1.e4, there are a variety of possible (legitimate) answers my opponent can play (i. e. e5, c5, d5, Sf6 and so on).

So my idea is, that I open the program, there is written "1.e4" and I type in one of the above moves. Depending on which move i write in, the program gives me the next move (that I wrote in the code) i. e. "2.Sf3".

First of all, I have no idea, if Processing is the right thing to use, as I would need something text-based, and graphics aren't of any importance.

So yesterday (with a little help from a friend, who introduced me to Processing) I tried starting writing something, but already on move 2 I have no idea how to continue, as the possibilities of moves (that I already have written down by hand) become very wide quite fast. I have no clue, how (or if ;) ) I should continue. anyway, here is, what we've written so far. It would be greatly appreciated, if you could guide me towards enlightenment :)

English is not my native language, so please don't be to hard on me, regarding grammar and spelling.

Thanks in advance,

Valt

String t = "Chess Opening Database";
String move1 = "";
String move2 = "";
String s1 = "1. e4";
String s2 = "";
String s3 = "";
int q = 1;

void setup() {
  size(800, 800);
  }

void draw() {
 background(250);

fill(0);
textSize(15);
text(t, 50, 40, 470, 63);
textSize(11);
text(s1, 50, 80, 470, 93);
text(s2, 50, 100, 470, 103);
text(s3, 50, 120, 470, 103);
text(move1, 80, 80, 470, 112);
text(move2, 120, 80, 470, 112);
}

void keyPressed(){
  if(key == ENTER)
  {
   if(q == 1) isValid();

   move1 = "";
  }
  else
  {move1 += key;}
}

void isValid()
{
  if(move1.equals("c5"))
    {
      s1 += " " + move1;
      s2 = "2.Sf3";
      q++;
    }
    if(move1.equals("e5"))
    {
      s1 += " " + move1;
      s2 = "2.Sf3";
      q++;
    }
    if(move1.equals("d5"))
    {
      s1 += " " + move1;
      s2 = "2.exd5";
      q++;
    }
}

void isValid2()
{
  if(move2.equals("d6"))
    {
      s1 += " " + move1;
      s2 = "2.Sf3";
      s3 = "3.d6" + move2;
      q++;
    }
    if(move2.equals("e5"))
    {
      s1 += " " + move1;
      s2 = "2.Sq3";
      q++;
    }
}
Tagged:

Answers

  • Post a Foto of your Repertoire you've hand written please

  • edited February 2017

    Thanks a lot for your reply! I wasn't expecting for someone to reply so quickly, so I only have a very sketchy sketch. I try to write it down a little bit more clean, and post it tomorrow. Until then, have fun, trying to read my handwriting ;) thanks again!

    EPSON001

  • edited February 2017

    I think you are lost, when you keep on hacking your data into the code.

    instead try to find a data structure that holds your tree of moves and then let the program just read out the data structure.

    Here is my raw attempt

    the data structure is in tree which holds the human moves and the computer answer moves

    in tree, the first number signifies if we are allowed to look here (0,1,2..., named as currentPossibleHumanMovesIndex, which is basically where you are in your tree); then comes the move DONE BY THE PLAYER. Then a ; follows.

    Thirdly the possible counter moves follow, each with a new signifying number (that tells you where in the tree you are next)

    So this: "0e2e4;d7d5#4;b1c6#5;g1f3#6" says : we are at currentPossibleHumanMovesIndex 0, so only when currentPossibleHumanMovesIndex is 0 we are allowed to look in this line.

    When currentPossibleHumanMovesIndex is 0, let's look in the line.

    When the user did enter e2e4, this is our line.

    Our computer answer moves are either d7d5 OR b1c6 OR g1f3.

    Let's choose one of the three randomly.

    ok , let's say d7d5 has been chosen, we print that out as our official move.

    BUT when we choose e.g. d7d5, it says d7d5#4, we split this up again and get 4, meaning: currentPossibleHumanMovesIndex is now 4 and we are allowed to look for the next human move that's gonna be entered next ONLY in lines that start with a 4. Thus we keep track where we are in the tree.

    And so on.......................

    // let's assume human player always starts with white and PC has to make the 2nd move with black. 
    
    
    String t = "Chess Opening Database";
    String move1 = "";
    String move2 = "";
    
    ArrayList<String> game = new ArrayList(); 
    
    int currentPossibleHumanMovesIndex=0; 
    
    final int wait            = 0;
    final int inputIsFinished = 1;
    int state = wait;
    
    
    String[] tree = {
      "0e2e4;d7d5#4;b1c6#5;g1f3#6", 
      "0d2d4;d7d5#7;", 
      "0b1c3;", 
      "0g1f3;", 
      "4d2d4", 
      "4b1c3", 
      "4g1f3", 
      "5d2d4", 
      "5b1c3", 
      "6g1f3"
    };
    
    String oneLineInTree[]; 
    
    void setup() {
      //
      size(400, 800);
      background(111); // Gray
      println(t);
    }
    
    void draw() {
      //
      background(111); // Gray 
    
      if (state==wait) {
        //
        fill(255, 2, 2); // RED 
        text("please enter your move: \n"
          +move1, 19, 19);
        gameOut();
        //
      } else if (state==inputIsFinished) {
    
        boolean found=false; 
    
        // we loop over all lines 
        for (int i=0; i<tree.length; i++) {
    
          // split the line 
          String[] oneLineInTree=split(tree[i], ';');
    
          // check if the line has the right currentPossibleHumanMovesIndex and 
          // holds also the move move1 at position 0 in oneLineInTree 
          if (oneLineInTree[0].indexOf(trim(str(currentPossibleHumanMovesIndex))) == 0 && 
            oneLineInTree[0].indexOf(move1) >=1 ) {
    
            // found 
            println( "you entered "+move1);
            println( "I know  "+tree[i]);
    
            // choose a computer move from oneLineInTree (except position 0)
            int index=int( random (1, oneLineInTree.length) ); 
            String answer1=oneLineInTree[index];
            println( "I decide "+answer1);
    
            // the responseMove has two parts: the move itself and our new currentPossibleHumanMovesIndex
            String[] responseMove=split(oneLineInTree[index], '#');
            currentPossibleHumanMovesIndex = int(responseMove[1]);
    
            // add to game monitor
            game.add(move1);
            game.add(responseMove[0]);
    
            // reset 
            state=wait;
            println( "I am now at "+currentPossibleHumanMovesIndex);
            move1=""; 
            found = true; 
            break;
          }//if
        }//for
        if (!found) {
          println ("none found");
          game.add("none found");
          state=wait;
        }
      }//else if
    }//func
    
    void gameOut() {
    
      fill(0); // Black 
    
      line(width/2-4, 0, 
        width/2-4, height); 
      text("game: ", width/2, 19);
      int y=19+19; 
      for (String s : game) {
        text(s, width/2, y);
        y+=19;
      }
    }
    
    void keyPressed() {
      if (key == ENTER)
      {
        // if (q == 1) isValid();
        //move1 = "";
        state=inputIsFinished;
      } else if (key == BACKSPACE) {
        move1 = move1.substring(0, move1.length()-1);
      } else
      {
        move1 += key;
      }
    }
    //
    
  • thanks for posting your graph, I saw it only after posting my code

    but you need just to fill your graph into tree

  • new version

    when you hit space bar it shows the tree

        // let's assume human player always starts with white and PC has to make the 2nd move with black. 
    
    
        String t = "Chess Opening Database";
        String move1 = "";
        String move2 = "";
    
        ArrayList<String> game = new ArrayList(); 
    
        int currentPossibleHumanMovesIndex=0; 
    
        final int wait            = 0;
        final int inputIsFinished = 1;
        final int showTree        = 2; 
        int state = wait;
    
    
        String[] tree = {
          "0e2e4;d7d5#4;b1c6#5;g1f3#6", 
          "0d2d4;d7d5#7;", 
          "0b1c3;", 
          "0g1f3;", 
          "4d2d4", 
          "4b1c3", 
          "4g1f3", 
          "5d2d4", 
          "5b1c3", 
          "6g1f3", 
          "7g1f3;d2d4#8", 
          "7g1f8;", 
          "8e2e4"
        };
    
        String oneLineInTree[]; 
    
        void setup() {
          //
          size(1200, 800);
          background(111); // Gray
          println(t);
        }
    
        void draw() {
          //
          background(111); // Gray 
    
          if (state==wait) {
            //
            fill(255, 2, 2); // RED 
            text("please enter your move: \n"
              +move1, 19, 19);
            gameOut();
            //
          } else if (state==inputIsFinished) {
            // after hitting return 
            evaluateInput();
          } else if (state==showTree) {
            //
            background (0);
            showTree('0', 19, 67, 300); // recursive
            // some decoration 
            fill(255);
            text("Hit space bar to go back  ", 19, height-9);
            // we loop over all lines 
            fill(0, 255, 0);
            for (int i=0; i<tree.length; i++) {
              text(tree[i], width-222, i*22+331);
            }
          } // else if
          else {
            // Error
            println("unknown state, error number 64");
            exit();
          } //else
        }//func
    
        // --------------------------------------------------------
    
        void evaluateInput() {
    
          boolean found=false; 
    
          // we loop over all lines 
          for (int i=0; i<tree.length; i++) {
    
            // split the line 
            String[] oneLineInTree=split(tree[i], ';');
    
            // check if the line has the right currentPossibleHumanMovesIndex and 
            // holds also the move move1 at position 0 in oneLineInTree 
            if (oneLineInTree[0].indexOf(trim(str(currentPossibleHumanMovesIndex))) == 0 && 
              oneLineInTree[0].indexOf(move1) >=1 ) {
    
              // found 
              println( "you entered "+move1);
              println( "I know  "+tree[i]);
    
              // choose a computer move from oneLineInTree (except position 0)
              int index=int( random (1, oneLineInTree.length) ); 
              String answer1=oneLineInTree[index];
              println( "I decide "+answer1);
    
              // the response Move has two parts: the move itself and our new currentPossibleHumanMovesIndex
              String[] responseMove=split(oneLineInTree[index], '#');
              currentPossibleHumanMovesIndex = int(responseMove[1]);
    
              // add to game monitor
              game.add(move1);
              game.add(responseMove[0]);
    
              // reset 
              state=wait;
              println( "I am now at "+currentPossibleHumanMovesIndex);
              move1=""; 
              found = true; 
              break;
            }//if
          }//for
          if (!found) {
            println ("none found");
            game.add("none found");
            state=wait;
          }
        }
    
        void showTree(char allowedChar, 
          int x1, int y1, 
          int dist ) {
          //
          // we loop over all lines
          int x=x1; 
          for (int i=0; i<tree.length; i++) {
    
            // split the line 
            String[] oneLineInTree=split(tree[i], ';');
    
            if (tree[i].charAt(0)==allowedChar) {
              //
    
              if (allowedChar=='0') {
                stroke(255);
                line(width/2, 2, x+9, y1);
              }
    
              fill(255); // white 
              //text(tree[i], x, 19, 200, 200);
              text(oneLineInTree[0], x, y1, 200, 200);
    
              branch( tree[i], x, y1 );
    
              x+=dist; // go right
            }//if
          }//for
        }//func
    
        void branch(String branch, int x, int y1) {
          //
          // split the line 
          String[] oneLineInTree=split(branch, ';');
          int y=y1+29;
    
          fill(255, 2, 2);  // RED 
    
          for (int i=1; i<oneLineInTree.length; i++) {
    
            text(oneLineInTree[i], x, y, 200, 200);
    
            // the response Move has two parts: the move itself and our new currentPossibleHumanMovesIndex
            String[] responseMove=split(oneLineInTree[i], '#');
    
            if (responseMove.length>1) {
              char nextMove = responseMove[1].charAt(0); //!!!! works only for  
              showTree(nextMove, x+44, y, 55);
            }
    
            y+=29; // go left
          }//for
        }
    
    
        void gameOut() {
    
          // the main screen game output
    
          fill(0); // Black 
    
          line(width/2-4, 0, 
            width/2-4, height); 
          text("game: ", width/2, 19);
          int y=19+19; 
          for (String s : game) {
            text(s, width/2, y);
            y+=19;
          }
    
          fill(255);
          text("Hit space bar for tree view   ", 19, height-9);
          fill(255);
          text(t, width-154, height-9);
        }
    
        void keyPressed() {
          if (key == ENTER)
          {
            // if (q == 1) isValid();
            //move1 = "";
            state=inputIsFinished;
          } else if (key == BACKSPACE) {
            move1 = move1.substring(0, move1.length()-1);
          } else if (key == ' ') {
            if (state==showTree)
              state=wait;
            else
              state=showTree;
          } // space key 
          else if (key==ESC) {
            // in state showTree we want to go back (and not leave the sketch)
            if (state==showTree) {
              state=wait; // go back 
              key=0; // kill Esc
            }
          } else
          {
            move1 += key;
          }
        }
        //
    
  • thanks a lot for your help! I'm sorry that I didn't respond yesterday, I'm a little bit stressed with studying! I really appreciate it a lot, that you put so much effort, in helping me with my idea! later today, I hopefully have time, to try your code in depth and give you some feedback/ask you some questions. However, thanks a lot, I never thought, that I would get so much help so quickly!

  • entire new version with two classes and you need to enter the tree step by step

        // let's assume human player always starts with white and PC has to make the 2nd move with black. 
    
    
        String t = "Chess Opening Database";
        String move1 = "";
        String move2 = "";
    
        ArrayList<String> game = new ArrayList(); 
    
        int nodeNumber;
    
        final int wait            = 0;
        final int inputIsFinished = 1;
        final int showTree        = 2; 
        int state = showTree;
    
        Tree treeObject = new Tree(); 
    
        void setup() {
          //
          size(1200, 800);
          background(111); // Gray
          println(t);
          defineNodes();
          treeObject.display();
          treeObject.displayByMoveDepthInit();
        }
    
        void draw() {
          //
          background(111); // Gray 
    
          if (state==wait) {
            //
            fill(255, 2, 2); // RED 
            text("please enter your move: \n"
              +move1, 19, 19);
            gameOut();
            //
          } else if (state==inputIsFinished) {
            // after hitting return 
            evaluateInput();
          } else if (state==showTree) {
            //
            background (0);
            treeObject.displayByMoveDepth2(); 
            // some decoration 
            fill(255);
            text("Hit space bar to go back  ", 19, height-9);
          } // else if
          else {
            // Error
            println("unknown state, error number 64");
            exit();
          } //else
        }//func
    
        // --------------------------------------------------------
    
        void evaluateInput() {
    
          //
        }
    
        void gameOut() {
    
          // the main screen game output
    
          fill(0); // Black 
    
          line(width/2-4, 0, 
            width/2-4, height); 
          text("game: ", width/2, 19);
          int y=19+19; 
          for (String s : game) {
            text(s, width/2, y);
            y+=19;
          }
    
          fill(255);
          text("Hit space bar for tree view   ", 19, height-9);
          fill(255);
          text(t, width-154, height-9);
        }
    
        void keyPressed() {
          if (key == ENTER)
          {
            // if (q == 1) isValid();
            //move1 = "";
            state=inputIsFinished;
          } else if (key == BACKSPACE) {
            move1 = move1.substring(0, move1.length()-1);
          } else if (key == ' ') {
            if (state==showTree)
              state=wait;
            else
              state=showTree;
          } // space key 
          else if (key==ESC) {
            // in state showTree we want to go back (and not leave the sketch)
            if (state==showTree) {
              state=wait; // go back 
              key=0; // kill Esc
            }
          } else
          {
            move1 += key;
          }
        }
        //-----------------------------------------------------------------------------
    
        void defineNodes() {
    
          treeObject.nodes.add(new Node("e4", 0, 0, -1 ));
          addChild (0, 1, "e5", "d5", "c5", "e6", "c6", "d6", "Sf6" );
    
          // =====================================
          // appending one child and each of the nodes just defined : (move 2)
          addChild (1, 2, "Sf3" );
          addChild (2, 2, "exd5" ); 
          addChild (3, 2, "Sf3" );
          addChild (4, 2, "Sf3" );
          addChild (5, 2, "d4" );
          addChild (6, 2, "d4" );
          addChild (7, 2, "e5" );
    
          // =====================================
          // appending one child and each of the nodes just defined : 
          addChild (8, 3, "Sc6" ); // on Sf3 
          addChild (8, 3, "Sf6" ); 
          addChild (8, 3, "d6" );
          //
          addChild (9, 3, "Dxd5" ); // on exd5
          addChild (9, 3, "Sf6" );
          //
          addChild (10, 3, "d6" ); // on Sf3 (II) 
          addChild (10, 3, "e6" );
          addChild (10, 3, "Sc6" );
          //
          addChild (11, 3, "d5" );
          //
          addChild (12, 3, "d5" );
          //
          addChild (13, 3, "Sf6" );
          //
          addChild (14, 3, "Sd5" );
    
          // =====================================
          // -------------------------------------
          addChild (15, 4, "Lc4" );
          addChild (16, 4, "Sxe5" );
          addChild (17, 4, "Lc4" );
          addChild (18, 4, "Sf3" );
          addChild (19, 4, "d4" );
          addChild (20, 4, "c3/d4" ); // not sure what / means here
          addChild (21, 4, "c3/d4" ); // not sure what / means here
          addChild (22, 4, "c3/d4" ); // not sure what / means here
          addChild (23, 4, "exd5" );
          addChild (24, 4, "exd5" );
          addChild (24, 4, "Sf3" ); // Sf3 correct?
          addChild (25, 4, "Sc3" ); // correct?
          addChild (26, 4, "c4" ); // correct?
        }
    
        void addChild(int id, int depth, String... arrString) {
          //
          printArray(arrString);
    
          Node parent = treeObject.nodes.get(id);
    
          for (String s1 : arrString) {
            treeObject.nodes.add(new Node(s1, nodeNumber, depth, id));
            parent.childrenID.add(nodeNumber-1);
          }
        }
    
        // ============================================================================
    
        class Tree {
          //
          ArrayList<Node> nodes = new ArrayList();
          int[] depthArr = new int[111]; 
          //
          void display() {
            //
            println("--------------");
            Node parent = nodes.get(0);
            // println( parent.id);
            parent.display();
          }//method
    
          void displayByMoveDepthInit() { // ---
            //
            int x=21;
            int y=21; 
    
            for (int depth=0; depth<100; depth++) {
              x=21;
              for (Node n1 : nodes) {
                if (n1.depth==depth) {
                  depthArr[depth]++; 
                  n1.display2(x, y); 
                  x+=57;
                }//if
              }
              y+=41;
            }
          }//func
    
          void displayByMoveDepth2() { // ---
            //
            int x=21;
            int y=21; 
            for (int depth=0; depth<100; depth++) {
              x=21;
              for (Node n1 : nodes) {
                if (n1.depth==depth) {
                  n1.display2(x, y); 
                  x+=int (width / depthArr[depth]) ;
                }//if
              }
              y+=41;
            }
          }//func
          //
        } // class 
    
        // ============================================================================
    
        class Node {
          //
    
          int id; 
          String move; // "e2e4" 
          ArrayList<Integer> childrenID = new ArrayList(); // or Type Node as well  
          int depth=0; // how many moves
          int parentID; 
          int x, y;
          Node(String move_, int id_, int depth_, int parentID_) {
            move=move_;
            id=id_;
            depth=depth_;
            parentID=parentID_;
            nodeNumber++;
          }
    
          void display() {
            //
            println( id);
            println( move);
            for ( int i1 : childrenID) { 
              Node n1 = treeObject.nodes.get(i1);
              println( n1.id+": "+ n1.move);
    
              n1.display();
            }
          }//method
    
          void display2( int x, int y ) {
            this.x=x;
            this.y=y; 
            text(id+":"+move, x, y);
            Node parent = null;
            if (parentID>=0)
              parent = treeObject.nodes.get(parentID);
    
            if (parent!=null) {
              if (parent.id%2==0) 
                stroke(111);
              else stroke(255, 2, 2);
              line(x+5, y-12, parent.x+13, parent.y+2);
            }
          }
        } // class 
        //
    
Sign In or Register to comment.