Answers to Problems


Try to solve these problems yourself. Only come look here if your code doesn't work, and you want to see what you did wrong.
 

Nested Loops


  public static void main() {
    int doing, best, chose, score, sum;
    boolean Xwon = false, Owon = false, cats = false;
    int[] board = new int[10];
    for (int nx=1;nx<=9;nx++) board[nx] = 0;
    for (int max=0;max<9;max++) { // do one play from each player..

      // 1. Display the board..
      doing = 0;
      for (int ro=1;ro<=3;ro++) { // do three rows..
        // prepare to display one row..
        System.out.println("");
        if (ro>1) System.out.println("---+---+---");
        for (int co=1;co<=3;co++) { // do 3 squares in that row..
          // display one square...
          if (co>1) System.out.print(" | ");
            else System.out.print(" ");
          doing++;
          if (board[doing]>0) System.out.print("X");
          else if (board[doing]<0) System.out.print("O");
            else System.out.print(doing);
        } // end of 3 squares
      } // end of 3 rows
      System.out.println("");
      System.out.println("");

      // 2. Is game over?
      if (Xwon) break;
      if (Owon) break;
      cats = true;
      for (int nx=1;nx<=9;nx++) if (board[nx]==0) cats = false;
      if (cats) break;
      System.out.println(""); // blank line for clarity

      // 3. Accept X play
      System.out.print("Your play: ");
      while (true) {
        doing = Zystem.ReadInt();
        if (doing>9) doing = 0; // so a single test catches all off-board plays
        if (doing<1) break; // invalid input, user wants out
        if (board[doing] == 0) { // valid play..
          board[doing]++; // mark X as having played this square
          break;}
        System.out.print("Taken! "); // ..then go back for another input
      } // end of input loop
      if (doing<1) break; // invalid input
      if (board[1]>0) if (board[2]>0) if (board[3]>0) Xwon = true; // top row
      if (board[4]>0) if (board[5]>0) if (board[6]>0) Xwon = true; // middle row
      if (board[7]>0) if (board[8]>0) if (board[9]>0) Xwon = true; // bottom row
      if (board[1]>0) if (board[4]>0) if (board[7]>0) Xwon = true; // left column
      if (board[2]>0) if (board[5]>0) if (board[8]>0) Xwon = true; // middle column
      if (board[3]>0) if (board[6]>0) if (board[9]>0) Xwon = true; // right column
      if (board[1]>0) if (board[5]>0) if (board[9]>0) Xwon = true; // down diagonal
      if (board[3]>0) if (board[5]>0) if (board[7]>0) Xwon = true; // up diagonal
      if (Xwon) continue; // display final board then exit
      if (max == 4) continue; // ditto if cats

      // 4. Calculate O play
      best = -1;
      chose = 0;
      for (doing=1;doing<=9;doing++) { // try all available squares
        if (board[doing] !=0) continue; // already played, go to next square
        score = 0;
        if (doing<4) { // in the top row..
          sum = board[1]+board[2]+board[3];
          if (sum == -4) score = 99;
          else if (sum == 2) score = score+22;
          else if (sum == 0) score++;
          else if (sum == -2) score = score+4;
          else if (sum == 1) score = score+2;
          } // end of top row test
        else if (doing>6) { // in the bottom row..
          sum = board[7]+board[8]+board[9];
          if (sum == -4) score = 99;
          else if (sum == 2) score = score+22;
          else if (sum == 0) score++;
          else if (sum == -2) score = score+4;
          else if (sum == 1) score = score+2;
          } // end of bottom row test
        else if (doing>3) if (doing<7) { // in the middle row (last test)..
          sum = board[4]+board[5]+board[6];
          if (sum == -4) score = 99;
          else if (sum == 2) score = score+22;
          else if (sum == 0) score++;
          else if (sum == -2) score = score+4;
          else if (sum == 1) score = score+2;
          } // end of middle row test
        if (doing%3 == 0) { // in the right column..
          sum = board[3]+board[6]+board[9];
          if (sum == -4) score = 99;
          else if (sum == 2) score = score+22;
          else if (sum == 0) score++;
          else if (sum == -2) score = score+4;
          else if (sum == 1) score = score+2;
          } // end of right column test
        else if (doing%3 == 1) { // in the left column..
          sum = board[1]+board[4]+board[7];
          if (sum == -4) score = 99;
          else if (sum == 2) score = score+22;
          else if (sum == 0) score++;
          else if (sum == -2) score = score+4;
          else if (sum == 1) score = score+2;
          } // end of left column test
        else if (doing%3 == 2) { // in the middle column..
          sum = board[2]+board[5]+board[8];
          if (sum == -4) score = 99;
          else if (sum == 2) score = score+22;
          else if (sum == 0) score++;
          else if (sum == -2) score = score+4;
          else if (sum == 1) score = score+2;
          } // end of middle column test
        if (doing%4 == 1) { // in the down diagonal..
          sum = board[1]+board[5]+board[9];
          if (sum == -4) score = 99;
          else if (sum == 2) score = score+22;
          else if (sum == 0) score++;
          else if (sum == -2) score = score+4;
          else if (sum == 1) score = score+2;
          } // end of down diagonal test
        else if ((doing==3)||(doing==5)||(doing==7)) { // in the up diagonal..
          sum = board[3]+board[5]+board[7];
          if (sum == -4) score = 99;
          else if (sum == 2) score = score+22;
          else if (sum == 0) score++;
          else if (sum == -2) score = score+4;
          else if (sum == 1) score = score+2;
          } // end of up diagonal test
        if (score>best) { // best square so far..
          chose = doing;
          best = score;} // otherwise ignore this square, we already have better
      } // end of heuristic loop
      if (chose==0) { // huh? this shouldn't happen..
        System.out.println("Something went wrong");
        break;}
      board[chose] = -2; // mark O as having played this square
      if (best >= 99) Owon = true; // did O win?
      // if (board[1]<0) if (board[2]<0) if (board[3]<0) Owon = true; // top row
      // if (board[4]<0) if (board[5]<0) if (board[6]<0) Owon = true; // middle row
      // if (board[7]<0) if (board[8]<0) if (board[9]<0) Owon = true; // bottom row
      // if (board[1]<0) if (board[4]<0) if (board[7]<0) Owon = true; // left column
      // if (board[2]<0) if (board[5]<0) if (board[8]<0) Owon = true; // middle column
      // if (board[3]<0) if (board[6]<0) if (board[9]<0) Owon = true; // right column
      // if (board[1]<0) if (board[5]<0) if (board[9]<0) Owon = true; // down diagonal
      // if (board[3]<0) if (board[5]<0) if (board[7]<0) Owon = true; // up diagonal
    } // end of double-play for
    // congratulate winner
    if (Xwon) System.out.println("You won, oh well.");
    else if (Owon) System.out.println("I won, I won, I won!");
      else System.out.println("Cat's game.");
  } // end of main
 
 

Methodical Code Re-Use


  public static int Add2score(int eX, int Oh, int both, int aBit, int mask) {
    if ((mask&aBit) ==0) return 0; // the current square is not in this row
    if (((both|aBit)&mask) == mask) return 0; // this row has both X and O
    if ((both&mask)==0) return 1; // the row is empty
    if ((Oh&mask)==0) return 2; // it has one X only
    if ((eX&mask)==0) return 4; // it has one O only
    return 0; // probably can't get here, but the compiler requires a return
  } // end of Add2score

  public static boolean Winner(int playlist) { // <-- header
    if ((playlist&0xE)==0xE) return true; // top row wins
    if ((playlist&0x70)==0x70) return true; // middle row
    if ((playlist&0x380)==0x380) return true; // bottom row
    if ((playlist&0x92)==0x92) return true; // left column
    if ((playlist&0x124)==0x124) return true; // middle col
    if ((playlist&0x248)==0x248) return true; // right column
    if ((playlist&0x222)==0x222) return true; // down diagonal
    if ((playlist&0xA8)==0xA8) return true; // up diagonal
    return false; // there is no winning three
  } // end of Winner

  public static void main() {
    int eX = 0, Oh = 0, both = 0, doing, aBit, best, chose, both, score, mask;
    boolean Xwon = false, Owon = false, logit = false;
    String aLine = "";
    for (int max=0;max<9;max++) { // do one play from each player..
      both = eX|Oh;

      // 1. Display the board..
      aBit = 1;
      doing = 0;
      for (int ro=1;ro<=3;ro++) { // do three rows..
        // prepare to display one row..
        System.out.println("");
        if (ro>1) System.out.println("---+---+---");
        for (int co=1;co<=3;co++) { // do 3 squares in that row..
          // display one square...
          if (co>1) System.out.print(" | ");
            else System.out.print(" ");
          aBit = aBit<<1;
          doing++;
          if ((eX&aBit) != 0) System.out.print("X");
          else if ((Oh&aBit) != 0) System.out.print("O");
            else System.out.print(doing);
        } // end of 3 squares
      } // end of 3 rows
      System.out.println("");
      System.out.println("");

      // 2. Is game over?
      if (Xwon) break;
      if (Owon) break;
      if (eX+Oh == 0x3FE) break;
      System.out.println(""); // blank line for clarity

      // 3. Accept X play
      System.out.print("Your play: ");
      while (true) {
        doing = Zystem.ReadInt();
        if (doing>9) doing = 0; // so a single test catches all off-board plays
        if (doing<1) break; // invalid input, user wants out
        aBit = 1<<doing;
        if (((eX|Oh)&aBit) == 0) { // valid play..
          eX = eX|aBit; // mark X as having played this square
          break;}
        System.out.print("Taken! "); // ..then go back for another input
      } // end of input loop
      if (doing<1) break; // invalid input
      aBit = 1<<doing;
      eX = eX|aBit;
      both = eX|Oh;
      if (Winner(eX)) Xwon = true;
      if (Xwon) continue; // display final board then exit
      if (both == 0x3FE) continue; // ditto if cats

      // 4. Calculate O play
      aBit = 1;
      best = -1;
      chose = 0;
      for (doing=1;doing<=9;doing++) { // try all available squares
        aBit = aBit<<1;
        if ((both&aBit) !=0) continue; // already played, go to next square
        score = 0;
        if (Winner(Oh|aBit)) score = 99; // yay! (a winner)
        if (Winner(eX|aBit)) score = score+22; // prevent a lose, block this one
        // for each row/column/diagonal doing is in, if doing does not fill it...
        score = Add2score(eX,Oh,both,aBit,0xE)+score; // top row
        score = Add2score(eX,Oh,both,aBit,0x70)+score; // 2nd row
        score = Add2score(eX,Oh,both,aBit,0x380)+score; // bottom row
        score = Add2score(eX,Oh,both,aBit,0x92)+score; // left column
        score = Add2score(eX,Oh,both,aBit,0x124)+score; // middle col
        score = Add2score(eX,Oh,both,aBit,0x248)+score; // right column
        score = Add2score(eX,Oh,both,aBit,0xA8)+score; // up diagonal
        score = Add2score(eX,Oh,both,aBit,0x222)+score; // down diagonal
        if (score>best) { // best square so far..
          chose = doing;
          best = score;} // otherwise ignore this square, we already have better
      } // end of heuristic loop
      if (chose==0) { // huh? this shouldn't happen..
        System.out.println("Something went wrong");
        break;}
      aBit = 1<<chose;
      Oh = Oh|aBit; // mark O as having played this square
      // did O win?
      if (Winner(Oh)) Owon = true;
    } // end of double-play while
    // congratulate winner
    if (Xwon) System.out.println("You won, oh well.");
    else if (Owon) System.out.println("I won, I won, I won!");
      else if (both == 0x3FE) System.out.println("Cat's game.");
  } // end of main
 
 

Exchange

A = B-A;
B = B-A;
A = B+A;

 

Revised: 2020 July 22