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

AltStyle によって変換されたページ (->オリジナル) /