0

I'm trying to learn java using the basic tictactoe example, but just for fun I wanted to design an ai later.

I'm having an issue flattening the char[] to Array. I'm so confused is there a better way to do this? Do I need to create another method to specific convert this char[] to array?

ERROR:

The method mapToCharater(Charater.class::cast) is undefined for the type Stream<Object>

CONSOLE OUTPUT

EDIT:

Exception in thread "main" java.lang.ClassCastException: Cannot cast [C to java.lang.Character
    at java.base/java.lang.Class.cast(Class.java:3610)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    at java.base/java.util.stream.Streams$StreamBuilderImpl.forEachRemaining(Streams.java:411)
    at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:658)
    at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:274)
    at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:550)
    at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260)
    at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:517)
    at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:523)
    at aiPackage.game.Board.<init>(Board.java:17)
    at aiPackage.game.Tester.main(Tester.java:15)

    package aiPackage.game;

    import java.util.*;
    import java.util.stream.*;

    public class Board {
        //declaration of private members
        private int score;
        private Board previousB = null;
        private char[][] thisBoard;

        // ------------------------------------------------------;

        public Board (char [][] inBoard) {
            //what
            //char[] flats = flatten(inBoard).map
            Object[] flats = flatten(inBoard).map(Character.class::cast).toArray(); //mapToCharater(Charater.class::cast).toArray();

            int[] flat = flatten(inBoard).mapToInt(Integer.class::cast).toArray();
            int flatSize = flat.length;


            // ------------------------------------------------------;

            //check if square
            if (Math.sqrt(flatSize)==3) {
                if(inBoard.length == 3) {
                    thisBoard = inBoard;
                }
                else {
                    System.out.println("The array isnt a square.");
                }
            }
            else {
                System.out.println("It doesnt match the dimensions of a tictactoe board.");
            }

            //we'll assume its not gonna break from the input atm
            setThisBoard(inBoard);
        }

        //https://stackoverflow.com/questions/31851548/flatten-nested-arrays-in-java
        private static Stream<Object> flatten(Object[] array) {
            return Arrays.stream(array)
                    .flatMap(o -> o instanceof Object[]? flatten((Object[])o): Stream.of(o));
        }

        public Board getPreviousB() {
            return previousB;
        }

        public void setPreviousB(Board previousB) {
            this.previousB = previousB;
        }

        public int getScore() {
            return score;
        }

        public void setScore(int score) {
            this.score = score;
        }

        public char[][] getThisBoard() {
            return thisBoard;
        }

        public void setThisBoard(char[][] thisBoard) {
            this.thisBoard = thisBoard;
        }

        //if there are even elements on the board, its x's turn
        public ArrayList<Board> getChildren(){

            return null;
        }

        public void checkIfEnded() {
            for (int i = 0; i < 3; i++) {
                //check row wins
                if (thisBoard[i][0] != '-' &&
                        thisBoard[i][0] == thisBoard[i][1] &&
                        thisBoard[i][1] == thisBoard[i][2]) {

                    //updates score based on winner
                    if (thisBoard[0][2] == 'x') {
                        updateScore(1);
                    }
                    else {
                        updateScore(-1);
                    }

                    return;
                }

                //check column wins
                if (thisBoard[i][0] != '-' &&
                        thisBoard[0][i] == thisBoard[1][i] &&
                        thisBoard[1][i] == thisBoard[2][i]) {

                    //updates score based on winner
                    if (thisBoard[0][2] == 'x') {
                        updateScore(1);
                    }
                    else {
                        updateScore(-1);
                    }

                    return;
                }


            }

            //check diagnals
            if (thisBoard[0][0] != '-' &&
                    thisBoard[0][0] == thisBoard[1][1] &&
                    thisBoard[1][1] == thisBoard[2][2]) {

                //updates score based on winner
                if (thisBoard[0][2] == 'x') {
                    updateScore(1);
                }
                else {
                    updateScore(-1);
                }

                return;
            }
            if (thisBoard[0][2] != '-' &&
                    thisBoard[0][2] == thisBoard[1][1] &&
                    thisBoard[1][1] == thisBoard[2][0]) {

                //updates score based on winner
                if (thisBoard[0][2] == 'x') {
                    updateScore(1);
                }
                else {
                    updateScore(-1);
                }

                return;
            }
        }

        //outputs the board's contents as a string
        public String toString() {
            String result = "";

            //gets the previous board's info to output first
            result = "" + previousB;

            //gets this boards info to output
            for(int i = 0; i < 3; i++) {
                for(int j = 0; j < 3; j++) {
                    result += thisBoard[i][j] + " ";
                }

                //adds newline char at end of row
                result += "\n";
            }
            //adds an extra newline char at end of board
            result += "\n";

            return result;
        }

        private void updateScore(int win) {
            if (win > 0) {
                score = 1;
            } else if(win == 0){
                score = 0;
            }else {
                score = -1;
            }
        }
    }
package aiPackage.game;

import java.util.*;

public class Tester {
    private static Board start;
    private static Board finish;

    public static void main(String[] args) {
        char temp [][] = {
            {'o','-','x'},
            {'-','-','-'},
            {'-','-','-'}};

        start = new Board(temp);
        finish = minMax(start.getChildren());
        System.out.println();

    }

    public static Board minMax(ArrayList<Board> resultList) {


        return null;
    }



}
4
  • I updated it to Object[] flats = flatten(inBoard).map(Character.class::cast).toArray(); and added the error I'm getting the console now Commented Apr 23, 2020 at 18:18
  • That worked, but now I'm getting: Cannot cast java.lang.Character to java.lang.Integer (Board line 18) Commented Apr 23, 2020 at 18:28
  • "Type mismatch: cannot convert from int[] to char[]" Commented Apr 23, 2020 at 18:31
  • You might just need to use an old-fashioned for-loop, since Java streams just don't have very good support for chars Commented Apr 23, 2020 at 18:33

3 Answers 3

3

The reason it fails is because Arrays.stream() does not accept char[] The following should work.

Arrays.stream(inBoard)
      .flatMap(x -> (Stream<Character>)new String(x).chars().mapToObj(i->(char)i))
      .collect(Collectors.toList())

check out Want to create a stream of characters from char array in java for and Why is String.chars() a stream of ints in Java 8? for better understanding.

Sign up to request clarification or add additional context in comments.

Comments

2

Your problem is here:

private static Stream<Object> flatten(Object[] array) {
    return Arrays.stream(array)
            .flatMap(o -> o instanceof Object[]? flatten((Object[])o): Stream.of(o));
}

You are using the comparation with Object[] to decompose the array, but in reality is a char[].

That makes that your result instead of being an Stream Object is a Stream char[].

The main point is that you can't use a Stream to work with primitives. Stream only works with Objects and char is a primitive.

you can manually flatten the char[][] using a classic loop.

Comments

0

flattening char[][] or impossible doesn't count

char[] array = Stream.of( inBoard ).flatMap( arr -> Stream.of( String.valueOf( arr ) ) )
    .collect( Collectors.joining() ).toCharArray();  // [o, -, x, -, -, -, -, -, -]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.