JavaRush /Java Blog /Random EN /multiplayer console game in java
timurnav
Level 21

multiplayer console game in java

Published in the Random EN group
Hello everyone, I’ve already finished writing the game a long time ago, but I still haven’t gotten around to writing an article, it’s a logical continuation of this piece of writing . If you haven’t yet tried to do anything other than JavaRush tasks, then getting acquainted with the game will be exactly where you want to start you will need to start preparing for the test tasks of a real project, in which I strongly recommend everyone to participate. And in general, it’s time to stop being a spherical programmer in a vacuum and start learning something outside of java-core. In order to simply watch the game, you must have MySQL installed, if you have not used it yet, do not hesitate - install it, this is one of those databases that you will use in your work and personal projects! I won’t give a description of installing and working with the database; there are a ton of tutorials and videos on the Internet; I recommend figuring this out on your own, this is also one of the most important skills of a programmer - figuring it out on your own :) In life, you will need the ability to write queries in sql, natively , and through JDBC, hibernate , spring, spring data, perhaps the list can be continued, but my knowledge ends there. Now stop reading this article and figure out MySQL, it’s actually not difficult at all, you need to install the server itself, the only settings there are login and password. then read about what commands are used when working. Commands for working with the server: create , show, use, and others, command help- will give a complete list of commands. Queries for working with a specific table: select , insert, deleteand others. Don’t go too deep, there’s a chance that you’ll remember only a small part from simply reading the commands. you will learn everything over time. You can play in the MySQL terminal, create a database, create tables, fill them in, make a request to display data, add query criteria. Most likely, this will take you no more than 2-3 hours; if it’s longer, don’t worry, with experience you will master new material faster. If you have no problems with the databases, then you can start developing the game, based on the game that I already wrote about Tic Tac Toe. For a very long time I could not figure out how to implement multiplayer, I found a solution in using a database. The game process assumes that players take turns, all changes in the game are recorded in the database. already based on this, we understand that we have a player and there is a playing field that contains links to players, it is in the playing field that the logic should be tied in which one player is waiting for the second player to make a move and after which their roles change and The first player makes a move, and the second waits. And since all changes must be duplicated in the database, after each move we need to save the field. So we came to the first conclusion, there must be a playing field in the Database and since we are talking about multiplayer, we need to add players there. Let's create tables in MySQL, I did it natively, through the mysql terminal window. the playing field contains links to players, so it would be logical to first create a table with the players. Our players have:
  • id– sequence number, we make it the primary key;
  • name– common name, string;
  • wins– number of victories;
  • loses– number of lesions;
  • games– the total number of games played.
Game table:
  • id– sequence number, we make it the primary key;
  • x– id of the player playing х– secondary key;
  • o– id of the player playing o– secondary key;
  • field– the field itself, its format will be described below;
  • status– this is necessary for the multiplayer to work correctly, the status characterizes the state of the game:
    created, playing, game over

  • current– also for multiplayer, specifically during the game this field controls whose turn it is now,
    and after the end it declares the winner or draw

We've sorted out the tables, now we need to create Java classes with the corresponding fields - Gameand User.
public class Game {
    private Integer id;
    private Integer x;
    private Integer y;
    private Integer field;
    private String status;
    private String current;
}
public class User {
    private Integer id;
    private String name;
    private Integer wins;
    private Integer loses;
    private Integer games;
    private Boolean busy;
}
Let's add an empty constructor without parameters - for working with the database and another constructor with which we will create objects. Let's add setters and getters for all fields. Now let's deal with hibernate :) it's not getting any easier from hour to hour. It's a little more complicated than with MySQL, I'll quickly go over the general structure. Again, not everything is so complicated, the basics can be learned through any tutorial in a couple of hours, and it’s better to study in depth while writing your projects. Working with a database from JAVA involves using JDBC, read about it on the wiki . But if you use it in writing code, it will bring a lot of pain in the anus, some complexity in writing DAO classes ( also a wiki ), hibernate will improve the situation a little, with it you will have much less repetitive (template) code. In order for hibernate to work, you need to connect a library to the project, this is done very simply: Ctrl+Alt+Shift+S(File-Project Structure), go to the Libraries tab, click "+" and add a pre-downloaded library ( as an option, from here ). In order to link classes Useryou Gameneed to use annotations - they are very easy to use, with them the code looks like this:
@Entity
@Table(name="games")
public class Game {
    private Integer id;
    private Integer x;

    @Id
    @GeneratedValue
    @Column(name = "id")
    public Integer getId() {
        return id;
    }

    @Column(name = "x")
    public Integer getX() {
        return x;
    }
}
It's simple here
  • @Entity– says that the class is an “entity”, in simple words, it is tied to a table in the database.
  • @Table(name="games")– says which table, games– the name of the table in the database
  • @Id, @GeneratedValue, @Column(name = "id")– with these three annotations we denote that this field is an identification field, it is generated automatically, and the column in the database is called id.
  • @Column(name = "x")– name of the column in the database.
Next, you need to build levels - the DAO level and the service level. If we simplify everything to vacuum conditions, then work with data goes through the service level, this is one of the abstraction levels, it allows you to make the application work more independent, so that the developer of the game logic does not go into details of setting up access to the database, or for example, if suddenly we instead of simple hibernate decided to use spring, the changes will not go beyond the service layer, without which half the application would have to be rewritten! this is one of the design patterns. Let's start writing the DAO level.
public class UserDAO {

    public void addUser(User user) throws SQLException {
        Session session = null;
        try{
            session = HibernateUtil.getSessionFactory().openSession();
            session.beginTransaction();
            session.save(user);
            session.getTransaction().commit();
        } catch (Exception e){
            e.printStackTrace();
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
    }
}
This is what the operation of adding a new user to the database looks like. Please note that only an object of the entity class is passed to the method; no additional information is required here. This is ensured by the fact that we receive a ready-made communication session with the database from the HibernateUtil class. Let's consider it.
public class HibernateUtil {
    private static SessionFactory sessionFactory = null;

    static {
        try {

            sessionFactory = new Configuration().configure().buildSessionFactory();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}
As you can see, everything here is also very simple SessionFactory- this is an interface from the hibernate library, which we connected to our project. For correct operation, all that remains is to fill out the hibernate.cfg.xml configuration file
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/tictactoe</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
        <property name="connection.pool_size">100</property>
        <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
        <property name="show_sql">false</property>
        <property name="hbm2ddl.auto">update</property>
        <property name="hibernate.connection.autocommit">false</property>
        <property name="current_session_context_class">thread</property>
        <property name="hibernate.enable_lazy_load_no_trans">true</property>
        <mapping class="entity.User" />
        <mapping class="entity.Game" />
    </session-factory>
</hibernate-configuration>
If you glance at the tags, it becomes clear what and how we are setting up here. Another feature of hibernate is that if we suddenly decide to change the database from MySQL to some other one, we only need to change the driver inside the tag property name="connection.driver_class" DAO layer is ready, let’s create a service layer. To avoid creating DAO objects in the service layer, we use the factory pattern.
public class Factory {
    private static UserDAO userDAO = null;
    private static Factory instance = null;
    private Factory() {
    }

    public static synchronized Factory getInstance() {
        if (instance == null) {
            instance = new Factory();
        }
        return instance;
    }

    public UserDAO getUserDAO() {
        if (userDAO == null) {
            userDAO = new UserDAO();
        }
        return userDAO;
    }
}
And here is one of the service level methods
public class UserService {
    static void setUserBusy(User user){
        user.setBusy(true); //делаем его занятым
        //и обновляем его в БД
        Factory.getInstance().getUserDAO().updateUser(user);
    }

}
The code for working with the database is completed, we rewrite the game logic taking into account the changes. First, let's separate the main launching method into a separate class Main, it will only be a control class - a game menu in which you can start the game or view statistics. Let's create a class GameLogicthat will describe all the logic of the game and checking the playing field. He will delegate the saving of all changes on the playing field and player statistics after the game to the service layer. There is an interesting feature: we contain the playing field in the form of arrays, they can be saved in the database, but at this stage I decided to reinvent the wheel and in my database the field is contained as an int, namely a 9-digit number, which is parsed by two using class methods GameLogic, I don’t recommend doing this, I will improve in the next releases of the game :) Good luck to everyone in learning JAVA! You can download the project here .
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION