5
\$\begingroup\$

I'm a beginner in Java programming. At the start, I wanted to make something easy and then develope it more and more. I chose to do TicTacToe game. At this point I added some menu, playing with bot, bigger map. This is my first bigger OOP project, so I'm the most curious ,if I did it correctly. Could You tell me some advice how to improve my skills. Thank you in advance.

Code is anable in my github: https://github.com/NeverGiveUPek/TicTacToe

I will also copy it below:

public class Game {
public static void main(String[] args) {
    Play game1 = new Play();
    game1.do_game();
    }
}

*

public class Play {
private Map board;
private Settings settings = new Settings();
private Player player1;
private Player player2;

private byte play_state = 0;
private char tmp_icon;


public void set_game() {
   if(play_state == 0) {
       GameSettings menu = new GameSettings();
       menu.select_settings();

       set_board(menu.get_board_size());
       set_game_mode(menu.get_number_game_mode(),menu.get_bot_lvl());
       set_icons(menu.get_player1_icon());
       set_starting_icon(menu.get_number_starting_icon());


       save_game(menu.get_board_size(), menu.get_number_game_mode(), menu.get_number_starting_icon(), menu.get_player1_icon());
   }
   else if(play_state == 1){
       board.clean();
       set_starting_icon(settings.get_last_starting_icon());
   }
}

private void set_starting_icon(int starting_icon){
    if(starting_icon==1){
        tmp_icon = 'X';
    }
    else if(starting_icon==2){
        tmp_icon = 'o';
    }
}
private void set_game_mode(int game_mode, int bot_lvl){
    player1 = new PlayerHuman(settings.get_standart_data_style(),board.get_map_size());
    if(game_mode==1) {
        player2 = new PlayerHuman(settings.get_standart_data_style(),board.get_map_size());
        System.out.println("PvsP");
    }
    else if(game_mode==2) {

        player2 = new Bot(bot_lvl);
        System.out.println("PvsB");
    }
}
public void set_icons(int player1_icon) {

    if(player1_icon == 1){
        player1.set_icon('X');
        player2.set_icon('o');
    }
    else if(player1_icon == 2) {
        player1.set_icon('o');
        player2.set_icon('X');
    }
}
public void set_board(int board_size) {
    int winning_length = 3;
    if(board_size == 4) winning_length = 4;
    else if(board_size > 4) winning_length = 5;
    board = new Map(board_size,winning_length);
    board.clean();
}
public void change_player(){
    if(tmp_icon == 'X') tmp_icon = 'o';
    else if(tmp_icon == 'o') tmp_icon = 'X';
}
public void make_move(Player player){
    player.do_move(board);
    if(board.check_cell_empty(player.x,player.y)){
        System.out.println(player.x + " " + player.y);
        board.set_cell_icon(player.x,player.y,player.icon);
    }
    else{
        board.print_map();
        System.out.println("You wrote wrong cords, do it again");
        make_move(player);
    }
}
public void annouce_game_ending(int game_condition){
    if(game_condition == 0) System.out.println("It's TIE !");
    else if(game_condition == 10) {
        System.out.println("'X' is a WINNER !");
    }
    else {
        System.out.println("'o' is a WINNER !");
    }
}
public void save_game(int map_size,int game_mode,int starting_icon, int player1_icon){
    settings.set_last_board_size(map_size);
    PlayerHuman human_player1 = (PlayerHuman) player1;
    settings.set_last_data_style(human_player1.get_data_style());
    settings.set_last_game_mode(game_mode);
    settings.set_last_starting_icon(starting_icon);
    settings.set_last_player1_icon(player1_icon);
}
public void do_game(){
    while(true) {
        Menu start = new Menu(settings, play_state);
        start.run_menu();
        play_state = start.get_play_state();
        set_game();

        board.print_map();
        while (board.check_game_condtion() == 2) {
            System.out.println("Teraz kolej: " + tmp_icon);
            if (tmp_icon == player1.icon) {
                make_move(player1);
            } else if (tmp_icon == player2.icon) {
                make_move(player2);
            }
            board.print_map();
            change_player();
        }
        annouce_game_ending(board.check_game_condtion());
        play_state = 1;
    }
}
}

*

public abstract class Player {
char icon = 'P';
int x = -1, y = -1;

public void set_icon(char icon) {
    this.icon = icon;
}

public char get_icon() {
    return icon;
}

protected boolean check_cords(int x, int y, int map_size){
    return x >= 0 && x < map_size && y >= 0 && y < map_size;
}

public abstract void do_move(Map map);
}

*

import java.util.InputMismatchException;
import java.util.Scanner;

public class PlayerHuman  extends Player {
private byte data_style;

public PlayerHuman(byte data_style, int board_size){
    if(data_style == 2 && board_size > 3) this.data_style = 1;
    else this.data_style = data_style;
}


@Override
public void do_move(Map map) {
    int map_size = map.get_map_size();
    get_cords(data_style);
    if (!check_cords(x,y,map_size)) {
        System.out.println("Your cords should be beetween 0-" + (map_size-1));
        map.print_map();
        do_move(map);
    } else if (map.check_cell_empty(x, y) == false) {
        System.out.println("This cell is already occupied");
        map.print_map();
        do_move(map);
    }
}
public byte get_data_style(){return data_style;}


private void get_cords(byte data_style){
    if(data_style == 1) get_cords_in_seq();
    else if(data_style == 2) get_cords_as_board();
}

private void get_cords_in_seq(){

    boolean good = false;
    while(!good) {
        try {
            Scanner input = new Scanner(System.in);

            System.out.println("x: ");
            x = input.nextInt();
            System.out.println("y: ");
            y = input.nextInt();
            good = true;
        } catch (InputMismatchException e) {
            System.out.println("Wrong input");
        }
    }
}

private void get_cords_as_board(){

    boolean good = false;
    while(!good) {
        try {
            Scanner input = new Scanner(System.in);
            int number = input.nextInt();
            x = (number-1) % 3;
            y = 2 - ((number-1)/3);
            System.out.println("x: " + x + "y: " + y);
            good = true;
        } catch (InputMismatchException e) {
            System.out.println("Wrong input");
        }
    }
}
}

*

import java.util.LinkedList;
import java.util.Random;
import java.util.List;

public class Bot extends Player {
private int[] move = new int[2];// {x , y}
private byte best_score = -10;
private int bot_lvl;


public Bot(int bot_lvl){
    this.bot_lvl = bot_lvl;
}

@Override
public void do_move(Map map) {
    if(bot_lvl == 1){ //worst bot
        get_random_move(map);
    }
    else if(bot_lvl == 2){ // average bot
        get_average_move(map);
    }
    else { // unbeatable bot
        get_best_move(map);
    }

    set_cords(move);
}
private void get_best_move(Map map){
    byte score;
    int map_size = map.get_map_size();
    first:
    for (int i = 0; i < map_size; i++) {
        for (int j = 0; j < map_size; j++) {
            if (map.check_cell_empty(j, i)) {
                map.set_cell_icon(j, i, icon);
                score = minimax(map, (byte) 0, false, false);
                map.set_cell_icon(j, i, ' ');
                if (score > best_score) {
                    move[0] = j;
                    move[1] = i;
                    best_score = score;
                    if (best_score == 10) {
                        break first;
                    }
                }
            }
        }
    }
    best_score = -10;
}

private void get_random_move(Map map) {
    int map_size = map.get_map_size();
    List<Integer> possible_moves = new LinkedList<>();
    int counter=0;

    for (int i = 0; i < map_size; i++) {
        for (int j = 0; j < map_size; j++) {
            if (!map.check_map_full()) {
                if (map.check_cell_empty(j, i)) {
                    possible_moves.add(i*10 + j);//y * 10 + x
                    counter++;

                }
            }
        }
    }

    int rand_number;
    Random rand = new Random();
    rand_number = rand.nextInt(counter); //getting random move which won't end in next 2 rounds
    int score_move = possible_moves.get(rand_number);
    move[0] = score_move%10; // x
    move[1] = score_move/10; // y


}

private void get_average_move(Map map){

    byte counter = 0;
    List<Integer> possible_moves = new LinkedList<>();
    byte score;
    int map_size = map.get_map_size();

    for (int i = 0; i < map_size; i++) {
        for (int j = 0; j < map_size; j++) {
            if (map.check_cell_empty(j, i)) {
                map.set_cell_icon(j, i, icon);
                score = minimax(map, (byte) 0, false, true);
                map.set_cell_icon(j, i, ' ');
                if (score >= 5) {
                    counter++;
                    possible_moves.add(i*10 + j);//y * 10 + x

                }
            }
        }
    }
    if(counter == 0) {
        get_random_move(map);
    }
    else {
        int rand_number;
        Random rand = new Random();
        rand_number = rand.nextInt(counter); //getting random move which won't end in next 2      rounds
        int score_move = possible_moves.get(rand_number);
        move[0] = score_move%10; // x
        move[1] = score_move/10; // y
    }
    best_score = -10;
    }


    protected byte minimax(Map map, byte depth, boolean isMaximazing, boolean isAverage) { //isAverage needed to get_average_move

    byte result = map.check_game_condtion();
    if (result != 2) {
        return (byte) (adapt_game_condition(result) - depth);
    }
    if(depth == 2 && isAverage == true){ // return 5 when bot can't lose in next 2 moves
        return 5;
    }

    int map_size = map.get_map_size();

    byte number = get_isMaximazing_number(isMaximazing);

    for (int i = 0; i < map_size; i++) {
        for (int j = 0; j < map_size; j++) {
            if (map.check_cell_empty(j, i)) {
                if (!isMaximazing) map.set_cell_icon(j, i, another_icon());
                else map.set_cell_icon(j, i, icon);
                byte score = minimax(map, (byte) (depth + 1), !isMaximazing, isAverage);
                map.set_cell_icon(j, i, ' ');
                if (!isMaximazing) {
                    if (score < number) {
                        number = score;
                    }
                } else {
                    if (score > number) {
                        number = score;
                    }
                }
            }
        }
    }
    return number;
}

private byte get_isMaximazing_number(boolean isMaximazing) {
    if (isMaximazing) return -20;
    return 20;
}

private void set_cords(int[] best_move) {
    x = best_move[0];
    y = best_move[1];
}

private byte adapt_game_condition(byte score) {
    if (icon == 'o') score = (byte) (-1 * score);
    return score;
}

private char another_icon() {
    if (icon == 'X') return 'o';
    else return 'X';
}
}

*

import java.util.InputMismatchException;
import java.util.Scanner;

public class Menu {

private Settings settings;
private byte play_state = 0; //before first game or after {0;1}

public Menu(Settings settings,byte play_state){
    this.settings = settings;
    this.play_state = play_state;
}

public byte get_play_state() {
    return play_state;
}

private void print_menu(){

    System.out.println("---MENU---");
    System.out.println("1. New Game");
    System.out.println("2. Settings");
    System.out.println("3. Scoreboard");//not working yet
    System.out.println("4. Exit");
}
private void print_end_menu(){  //after game lose
    System.out.println("---MENU---");
    System.out.println("1. Play Again");
    System.out.println("2. New Game");
    System.out.println("3. Settings");
    System.out.println("4. Scoreboard");//not working yet
    System.out.println("5. Exit");

}
public void run_menu(){
    if(play_state == 0) {
        print_menu();
    }
    else{
        print_end_menu();
    }
    boolean flag=true;
    boolean exception_flag=false;
    int value;



    do {
        do {
            try {
                Scanner input = new Scanner(System.in);
                value = input.nextInt() - play_state;
                exception_flag = true;
            }catch(InputMismatchException e){
                value = -1;
            }
            if (value < (1 - play_state)|| value > 4 || !exception_flag) {
                System.out.println("You wrote wrong input. Do it again: ");
            }
        } while (value < (1 - play_state) || value > 4);
        if(value == 2) {  //enters game settings
            settings.change_settings();
        }
        else if(value == 3){ //enters scoarboard
            System.out.println("SCOREBOARD");
        }
        else if(value == 4){
            System.exit(1);
        }

        if(play_state == 0){
            if(value == 1) flag = false;
            else print_menu();
        }
        else if(play_state == 1){
            if(value == 0 || value == 1) {
                flag = false;
                if(value == 1) play_state = 0; //changing play_state to execute right set_game function
            }
            else print_end_menu();
        }

    }while(flag);//player must select game or exit
}
}

*

import java.util.InputMismatchException;
import java.util.Scanner;

public class Settings {
private byte standart_data_style=1;//data_style --> way of getting icons position from players
private String[] data_styles = new String [2];
private byte last_data_style;

//datas required to make option "play again" with last set settings
private int last_board_size;
private int last_game_mode;
private int last_starting_icon;
private int last_player1_icon;

public Settings(){
    data_styles[0] = "sequence";
    data_styles[1] = "numberpad (works only with board size 3)";
}

public byte get_standart_data_style() {
    return standart_data_style;
}

public void set_last_data_style(byte last_data_style) {
    this.last_data_style = last_data_style;
}

public void set_last_board_size(int last_board_size) {
    this.last_board_size = last_board_size;
}

public void set_last_game_mode(int last_game_mode) {
    this.last_game_mode = last_game_mode;
}

public int get_last_starting_icon() {
    return last_starting_icon;
}

public void set_last_starting_icon(int last_starting_icon) {
    this.last_starting_icon = last_starting_icon;
}

public void set_last_player1_icon(int last_player1_icon) {
    this.last_player1_icon = last_player1_icon;
}

public void print_settings(){
    System.out.println("---SETTINGS---");
    System.out.println("1. Data_style: " + data_styles[standart_data_style-1]);
    System.out.println("2. Exit");
    System.out.println("");
    System.out.println("If you want to change them. Write a number of chosen setting and then   write another value");
}

public void print_data_styles(){
    System.out.println("---DATA STYLES---");
    System.out.println("1. " + data_styles[0]);
    System.out.println("2. " + data_styles[1]);
}
private int get_valu_2(){
    int value;

    do {
        System.out.println("Write new value");
        try {
            Scanner input = new Scanner(System.in);
            value = input.nextInt();
        }catch(InputMismatchException e){
            value = -1;
        }
        if(value!=1 && value!=2) {
            System.out.println("You wrote wrong number. Do it again: ");
        }
    }while(value != 1 && value != 2);
    return value;
}
private int get_value(int min, int max){
    int value = -1;

    boolean flag = false;
    boolean exception_flag = false;

    while(!flag){
        try{
            Scanner input = new Scanner(System.in);
            value = input.nextInt();
            exception_flag = true;
        }catch(InputMismatchException e){
            System.out.println("Wrog input!");
        }
        if(exception_flag && value >= min && value <= max) flag = true;
        if(value < min || value > max){
            System.out.println("Number should be between " + min +" and " + max);
        }
    }
    return value;
}
public void change_settings(){
    int value;

    do {
        print_settings();
        value = get_value(1,2);
        if(value == 1) {
            print_data_styles();
            standart_data_style = (byte)get_value(1,2);
        }
    }while(value!=2);
}
}

*

import java.util.Scanner;
import java.util.InputMismatchException;

public class GameSettings {
private int number_game_mode;
private int number_starting_icon;
private int player1_icon; //1. X   2. o
private int board_size;
private int bot_lvl=0;

public int get_board_size(){
    return board_size;
}
public int get_player1_icon(){
    return player1_icon;
}
public int get_number_game_mode(){
    return number_game_mode;
}
public int get_number_starting_icon(){
    return number_starting_icon;
}
public int get_bot_lvl(){return bot_lvl;}

private void print_game_mode(){
    System.out.println("Set your game mode");
    System.out.println("1. Player vs Player");
    System.out.println("2. Player vs bot");
}
private void print_starting_icon() {
    System.out.println("Who starts?");
    System.out.println("1. X");
    System.out.println("2. o");
}
private void print_player1_icon(){
    System.out.println("Select icon for P1: ");
    System.out.println("1. 'X'");
    System.out.println("2. 'o'");
}
private void print_bot_lvl(){
    System.out.println("Choose bot difficulty: ");
    System.out.println("1. 'God' ");
    System.out.println("2. 'Average' ");
    System.out.println("3. 'Easy' ");
}
private void print_board_size(){
    System.out.println("Board is always a square");
    System.out.println("Enter a size of side <3-10> : ");
    System.out.println("Playing with bot is anable only with board size 3");
}

private int get_value(int min, int max){
    int value = -1;

    boolean flag = false;
    boolean exception_flag = false;

    while(!flag){
        try{
            Scanner input = new Scanner(System.in);
            value = input.nextInt();
            exception_flag = true;
        }catch(InputMismatchException e){
            System.out.println("Wrog input!");
        }
        if(exception_flag && value >= min && value <= max) flag = true;
        if(value < min || value > max){
            System.out.println("Number should be between " + min +" and " + max);
        }
    }
    return value;
}


public void select_settings() {
    print_board_size();
    board_size = get_value(3,10);
    if(board_size==3){
        print_game_mode();
        number_game_mode = get_value(1,2);
    }
    else{
        number_game_mode = 1;
    }
    if(number_game_mode == 2){
        print_bot_lvl();
        bot_lvl = get_value(1,3);
    }
    print_starting_icon();
    number_starting_icon = get_value(1,2);
    print_player1_icon();
    player1_icon = get_value(1,2);
}
}

*

public class Map {
private int size;
private int winning_length;
private char[][] board;

Map(int size, int winning_length){
    this.size = size;
    this.winning_length = winning_length;
    board = new char[size][size];
}


public void print_map() {
    {
        System.out.println("WINNING LENGTH: " + winning_length);

        //drawing first row
        for(int j=0; j<size-1;j++){
            System.out.print(board[0][j] + "|");
        }
        System.out.println(board[0][size-1]);

        //drawing all middle rows
        for(int i=1; i<size-1;i++){
            for(int l=0;l<size-1;l++){
                System.out.print("-+");
            }
            System.out.println("-");
            for(int k=0;k<size-1;k++){
                System.out.print(board[i][k] + "|");
            }
            System.out.println(board[i][size-1]);
        }
        for(int l=0;l<size-1;l++){
            System.out.print("-+");
        }
        System.out.println("-");

        //drawing last row
        for (int j=0; j<size-1;j++){
            System.out.print(board[size-1][j] + "|");
        }
        System.out.println(board[size-1][size-1]);

    }
}
public void clean(){
    for(int i=0;i<size;i++){
        for(int j=0;j<size;j++){
            board[i][j] = ' ';
        }
    }
}
public boolean check_cell_empty(int x,int y){
    if(board[y][x]=='X') return false;
    else if(board[y][x]=='o')return false;
    return true;
}
public int get_map_size(){return size;}
public void set_cell_icon(int x, int y, char icon) {
    board[y][x] = icon;
}
public char get_cell_icon(int x, int y) { return board[y][x]; }
public boolean check_map_full(){
    for(int i=0;i<size;i++){
        for(int j=0;j<size;j++){
            if(board[i][j]!='X'&&board[i][j]!='o') return false;
        }
    }
    return true;
}
public boolean check_horizontal(int x,int y, char given_icon){
    for(int i=0;i<winning_length;i++)
    {
        if(board[y][x+i]!=given_icon) return false;
    }
    return true;
}
public boolean check_vertical(int x, int y, char given_icon){
    for(int i=0;i<winning_length;i++)
    {
        if(board[y+i][x]!=given_icon) return false;
    }
    return true;
}
public boolean check_diagonally_right(int x, int y, char given_icon){
    for(int i=0;i<winning_length;i++)
    {
        if(board[y+i][x+i]!=given_icon) return false;
    }
    return true;
}
public boolean check_diagonally_left(int x, int y, char given_icon){
    for(int i=0;i<winning_length;i++)
    {
        if(board[y+i][x-i]!=given_icon) return false;
    }
    return true;
}

public boolean check_win(char icon){
    boolean flag = false;

    for(int i=0;i<size;i++) {
        for(int j=0;j<size;j++){
            if(j<=size-winning_length) {
                if(check_horizontal(j,i,icon)) flag = true;
            }
            if(i<=size-winning_length) {
                if(check_vertical(j,i,icon)) flag = true;
            }
            if(j<=size-winning_length && i<=size-winning_length) {
                if(check_diagonally_right(j,i,icon)) flag = true;
            }
            if(j>=winning_length-1 && i<=size-winning_length) {
                if(check_diagonally_left(j,i,icon)) flag = true;
            }
        }
    }
    return flag;
}
public byte check_game_condtion(){
    if(check_win('X')) return 10;//X won
    if(check_win('o')) return -10;//o won
    if(check_map_full()) return 0; //tie
    return 2; //still playing
}
}
\$\endgroup\$
  • 1
    \$\begingroup\$ ... so much to review, so little time ... \$\endgroup\$ – akuzminykh May 7 at 10:47
  • \$\begingroup\$ thank you very much for sharing your project!!! happy Coding! \$\endgroup\$ – Martin Frank May 15 at 10:56
9
\$\begingroup\$

Building the application structure for your project was a challenge.

Project

After I copied your classes into a Java project I created on my Eclipse IDE, your code has 11 compiler warnings.

Compiler warnings

When I tried to move the Player, PlayerHuman, and Bot classes into their own package to organize the code better, I got 9 compiler errors in the Play class. This tells me that you're referencing package-private variables. This is not a good practice. Keep all class variables private and use getters to get the values.

You named one of your classes Map. This confused me because I thought you were referring to a java.util.Map interface. Don't name your classes the same as standard Java classes. GameMap might be a better class name.

Hyphenated field names and method names like play_state aren't the Java coding convention. Generally, Java field names and method names are camelCase, like playState.

I ran your code once. I wasn't sure how to input a move. Fortunately, I let the bot go first, so I saw that you typed coordinates. It would be easier for the player to enter one number, 1 - 9 for a 3x3 board, 1 - 16 for a 4x4 board, and so on. The code would translate that into two coordinates.

I liked that you separated the concerns of the application into individual classes. I liked the Game class. I liked that you created an abstract Player class, and extended it to create the PlayerHuman and Bot classes.

In your Menu class, you have two separate menus. It would have been easier on your part and more consistent for the players if you combined them into one menu. Something like this.

private void printMenu(boolean endMenu) {
    System.out.println("---MENU---");
    System.out.println("1. New Game");
    System.out.println("2. Settings");
    System.out.println("3. Scoreboard");// not working yet
    if (endMenu) {
        System.out.println("4. Play Again");
    }
    System.out.println("9. Exit");
}

Overall, a really good effort at separation of concerns. Keep it up.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Hello ! I really appreciate your comment. Firstly I know I need to focus on a package in java. I just don't want anyone to have problem with opening my project. About java.util.Map interface I haven't heard before. I will keep it in mind. The mistake with calling variables and function etc. I read when I was in the middle of doing it. I didn't want to change every name, so I continue to do my own convention (Of course I will change it in next work). \$\endgroup\$ – NeverGiveUPek May 7 at 15:16
  • \$\begingroup\$ There are 2 way of inputing moves. I didn't explain it (that's why it might be confusing). In settings it's possible to enter a moves as a number pad(simmilar what You mention), but it only works with 3x3 map. Once more I want to thank you. That was my first code share, I didn't know what should I expect. I will keep in mind every advice. \$\endgroup\$ – NeverGiveUPek May 7 at 15:16
  • \$\begingroup\$ Board would be an obvious choice of name for something that represents that state of the Tic Tac Toe game board. And yes, agreed, move entry should be set up so you can play using the num pad, whose shape matches a 3x3 TTT board. \$\endgroup\$ – Peter Cordes May 7 at 18:58
3
\$\begingroup\$

Coding style guide

well, simply one: Java uses CamelCase for methods not underlines eg. game1.do_game(); would be game1.doGame();

naming

  • i have a little problem with your namings, see for example Play game1 = new Play(); is it a game or is it a play?
  • same applies here: private Map board; - should the class be renamed? or is the name of the variable chosen poorly?
  • same applies here: Menu start = new Menu; - since it's the only menu in this context
  • Menu.run_menu(); should be renamed into Menu.printRunMenu as all other methods have such an suffix - and: It is far more precise than a mere runMenu()
  • Play.do_game() is misleading, you play a party, so why don't you name it this way? Play.playParty() - but now it's obvious that Play should be renamed into Game as you realized on your own, when you named the instance of Play game1
  • naming pun: Play.make_move(Player player) vs Player.do_move(...); - they should share the same name because they do (technically) the same thing!
  • Player.check_coords(x,y); is misleading since it's not clear WHAT you check. maybe it should be renamed into Player.isInside(x,y); which leads to the next question: Why is it on Player and not on the Board ?
  • in your loops you could use the proper names for your variables - instead of for (int i = 0; i < map_size; i++) and for (int j = 0; j < map_size; j++) you could use for (int x = 0; x < map_size; x++) and for (int y = 0; y < map_size; y++)

primitive obssesion

  • private byte play_state = 0; instead of using cryptic bytes as states use an Enum - such an enum contains cleary readable state names, that anyone can handle... what is state 0?
  • why not se a class for your Icon? is a char really good enough for an icon (char tmp_icon;) - this also violates the open/closed priniciple
  • further on Icon as class: it could replace the method Bot.another_icon()
  • this draws further circles where icon is mis-used: int starting_icon ... now it's an int - that confuses me further - instead use a proper class for that (an Enum would be sufficent here as well)
  • same applied for int bot_level - instead give your bot class an enum of level - Bot.Level.POOR would be far more precise!
  • same for game_mode (i wont DRY here)
  • same for game_condition
  • same for data_style

segregation of concerns

  • the HumanPlayer class should not be responsible for input handling get_cords_in_seq(), get_cords_as_board() - write a class for this responsibility
  • same for Settings.get_value and Settings.get_valu_2 (also: typo here)
  • same for GameSettings.

program logic

it would be more easy to read if you reformat the condition at PlayerHuman.do_move() - first come the check conditions then comes the code executed (removes redundancy):

if (map.isOutside(x,y)) {//abort criteria
    System.out.println("Your cords should be beetween 0-" + (map.map_size-1));
    return; //aborts as expected
} 
if (map.isCellOccupied(x, y)) { //another abort criteria
    System.out.println("This cell is already occupied");
    return; //aborts as expected
}

map.print_map();
do_move(map); 
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Thank you for all of your suggestions. I've already changed some parts of a code, which was mentioned in a previous answer. I will do the same with your advices. Once again, thank you a lot. \$\endgroup\$ – NeverGiveUPek May 16 at 17:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.