HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Simple TicTacToe game, played by two simple A.I. players

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
simpletictactoeplayerstwogameplayed

Problem

I made two player objects (p1 and p2):

public class tttmodimproved{
    static int turn=0;
    public static void main(String[] args){
        System.out.println("Let's play TicTacToe");
        char isWin=' ';
        Board b= new Board();
        Player p1=new Player('X');
        Player p2= new Player('O');
        Player p;
        for(b.tc=0;b.tc2){
            move=check(mark,b);
            if(move==9){
                move=check(markOpo,b);
            }
        }
        while((move>8) || (b.s[move]!=' ')){
            move=(int)(Math.random()*9);
        }
        return move;
    }
    int check(char m,Board b){
        int mo;
        mo=checkArray(6,7,8,m,b);

        if(mo!=9)
            return mo;
        mo=checkArray(3,4,5,m,b);

        if(mo!=9)
            return mo;
        mo=checkArray(0,1,2,m,b);

        if(mo!=9)
            return mo;
        mo=checkArray(0,3,6,m,b);

        if(mo!=9)
            return mo;
        mo=checkArray(1,4,7,m,b);

        if(mo!=9)
            return mo;
        mo=checkArray(2,5,8,m,b);

        if(mo!=9)
            return mo;
        mo=checkArray(0,4,8,m,b);

        if(mo!=9)
            return mo;
        mo=checkArray(2,4,6,m,b);

        if(mo!=9)
            return mo;
        else
            return mo;

        }
    int checkArray(int a,int d,int c,char m,Board b){
        if((m==(b.s[a]&b.s[d]))&((b.s[c])==' ')){
            return c;
        }
        else if(((b.s[a]&b.s[c])==m)&&(b.s[d]==' '))
            return d;
        else if(((b.s[d]&b.s[c])==m)&&(b.s[a]==' '))
            return a;
        else
            return 9;
        }

    }

Solution

Bugs

if(m==((s[1]&s[4]&s[7])
        |(s[0]&s[3]&s[6])
        |(s[2]&s[5]&s[8])
        |(s[6]&s[7]&s[8])
        |(s[3]&s[4]&s[5])
        |(s[0]&s[1]&s[2])
        |(s[2]&s[4]&s[6])
        |(s[0]&s[4]&s[8]))){


Does this even work? It seems to me that you are trying to test m to each of the above values, but what you are really doing is a binary math operation of & and |. Let me explain...

& "and"s each of the bits in the number, e.g.:

13&19

13:   0 1 1 0 1
17: & 1 0 0 0 1
      0 0 0 0 1


See what happened? 1 and 1 becomes 1, and every other combination becomes 0.

| "or"s the bits:

13:   0 1 1 0 1
17: | 1 0 0 0 1
      1 1 1 0 1


Similar to &, but 0 and 0 result in 0, and every other combination 1.

What is happening is that the char ASCII values are &'d and |'d. Is this really what you want? In this case, you have to do it the tedious way: test each of them to m:

if (((m == board[1] && m == board[4] && m == board[7])
            || (m == board[0] && m == board[3] && m == board[6])
            || (m == board[2] && m == board[5] && m == board[8])
            || (m == board[6] && m == board[7] && m == board[8])
            || (m == board[3] && m == board[4] && m == board[5])
            || (m == board[0] && m == board[1] && m == board[2])
            || (m == board[2] && m == board[4] && m == board[6])
            || (m == board[0] && m == board[4] && m == board[8]))) {
        return m;
    }


Same here:

if((m==(b.s[a]&b.s[d]))&((b.s[c])==' ')){
    return c;
}
else if(((b.s[a]&b.s[c])==m)&&(b.s[d]==' '))
    return d;
else if(((b.s[d]&b.s[c])==m)&&(b.s[a]==' '))
    return a;
else
    return 9;
}


Becomes:

int checkArray(int a, int d, int c, Mark m, Board b) {
    if ((m == b.getBoard()[a] && m == b.getBoard()[d]) && ((b.getBoard()[c]) == Mark.NONE)) {
        return c;
    } else if ((m == b.getBoard()[a] && m == b.getBoard()[c]) && (b.getBoard()[d] == Mark.NONE)) {
        return d;
    } else if ((m == b.getBoard()[d] && m == b.getBoard()[c]) && (b.getBoard()[a] == Mark.NONE)) {
        return a;
    }
    return 9;
}


Formatting

I can't even read your code. Format it better; in an IDE, you can find a formatting option. In eclipse, it's Source->Format.

If you don't use an IDE, I suggest you install one. Eclipse is available here. Choose the installer, or the "Eclipse IDE for Java Developers" option.

Naming

public class tttmodimproved{

tttmodimproved is not only a bad name, it is also hard to read and understand. Cramming too much information in names is bad. Sure, names like class are bad, but so is thisclassdoesfooandbarwhilealsodoingotherstuff. That's what class-level javadoc comments are for.

As for readability, java class names are in PascalCase, and method and variable names in camelCase.

I suggest TicTacToe, and you can add a short comment about the class at the beginning, like so:

/**
 * ...
 */
public class TicTacToe {
    // ...


Other naming fixes:

  • cp -> changePlayer



  • p1 -> player1



  • p2 -> player2



  • b -> board



  • p -> currentPlayer



  • s -> board



  • tc: What does this even do?



  • ...



I give up. Let's see what we have so far:

```
public class TicTacToe {

static int turn = 0;

public static void main(String[] args) {
System.out.println("Let's play TicTacToe");
char isWin = ' ';
Board board = new Board();
Player player1 = new Player('X');
Player player2 = new Player('O');
Player currentPlayer;
for (board.tc = 0; board.tc 2) {
move = check(mark, b);
if (move == 9) {
move = check(markOpo, b);
}
}
while ((move > 8) || (b.board[move] != ' ')) {
move = (int) (Math.random() * 9);
}
return move;
}

int check(char m, Board b) {
int mo;
mo = checkArray(6, 7, 8, m, b);

if (mo != 9)
return mo;
mo = checkArray(3, 4, 5, m, b);

if (mo != 9)
return mo;
mo = checkArray(0, 1, 2, m, b);

if (mo != 9)
return mo;
mo = checkArray(0, 3, 6, m, b);

if (mo != 9)
return mo;
mo = checkArray(1, 4, 7, m, b);

if (mo != 9)
return mo;
mo = checkArray(2, 5, 8, m, b);

if (mo != 9)
return mo;
mo = checkArray(0, 4, 8, m, b);

if (mo != 9)
return mo;
mo = checkArray(2, 4, 6, m, b);

if (mo != 9)
return mo;
else
return mo;

}

int checkArray(int a, int d, int c, char m, Board b) {
if ((m == (b.board[a] & b.board[d])) & ((b.board[c]) == ' ')) {
return c;
} else if (((b.board[a] & b.board[c]) == m) && (b.board[d] == ' '))
return d;
else if (((b.board[d] & b.board[c]) == m) && (b.board[a] == ' '))

Code Snippets

if(m==((s[1]&s[4]&s[7])
        |(s[0]&s[3]&s[6])
        |(s[2]&s[5]&s[8])
        |(s[6]&s[7]&s[8])
        |(s[3]&s[4]&s[5])
        |(s[0]&s[1]&s[2])
        |(s[2]&s[4]&s[6])
        |(s[0]&s[4]&s[8]))){
13:   0 1 1 0 1
17: & 1 0 0 0 1
      0 0 0 0 1
13:   0 1 1 0 1
17: | 1 0 0 0 1
      1 1 1 0 1
if (((m == board[1] && m == board[4] && m == board[7])
            || (m == board[0] && m == board[3] && m == board[6])
            || (m == board[2] && m == board[5] && m == board[8])
            || (m == board[6] && m == board[7] && m == board[8])
            || (m == board[3] && m == board[4] && m == board[5])
            || (m == board[0] && m == board[1] && m == board[2])
            || (m == board[2] && m == board[4] && m == board[6])
            || (m == board[0] && m == board[4] && m == board[8]))) {
        return m;
    }
if((m==(b.s[a]&b.s[d]))&((b.s[c])==' ')){
    return c;
}
else if(((b.s[a]&b.s[c])==m)&&(b.s[d]==' '))
    return d;
else if(((b.s[d]&b.s[c])==m)&&(b.s[a]==' '))
    return a;
else
    return 9;
}

Context

StackExchange Code Review Q#111824, answer score: 6

Revisions (0)

No revisions yet.