Hi there. My name is Raluca Gaina and in this video I'll give a brief overview of the TAG framework, showing how to go about beginning to implement a new game. In this case, I'll be implementing the game Dots and Boxes, which starts with a 2-dimensional grid with dots in the corners of all grid cells. Players take turn drawing lines between the dots, gaining points when they draw the last edge of a cell, and also getting another turn. The player with the most points at the end wins. This video is structured in 5 parts, starting with setting up the project and base files for a new game. Then we'll look at implementing the game state and forward model classes, including all the state representation and game logic, respectively. We'll then finish registering our new game in the framework and run it. Finally, we'll do a bit of customization of the graphical user interface for a better display of our game, and let the artificial players have some fun! First things first, we need to set up the project. You'll need to download the code from GitHub if you haven't already done so, and open it in your IDE of choice. I'm using IntelliJ here. It's important to note that this is a Maven project, so make sure it is all set up appropriately. Next, make sure that you can run the framework by opening the Game class in the core package. You'll find its main method at the bottom of the file, which you can run to make sure everything compiles. We'll start our game implementation by registering it in the framework, which is done in the GameType class in the games package. Here we need add a new enum value with our game and corresponding mechanics and categories. Then we can create a new sub-package for our game in the games package, and add here the core classes of the game, the game state, the forward model, and the game parameters. All of these should extend from the corresponding abstract classes in the framework and implement all suggested methods. The game parameters class is not essential, but we can store here and easily modify later the grid width and height in the case of the Dots & Boxes game, which are our main parameters. In the second part of this tutorial, we'll implement the state representation and all methods required for the game state. I start by modifying the constructor, as we can set the turn order directly from our class. We can make use here of the ready-made Alternating Turn Order from the framework, which will repeatedly iterate through the players in the game. Our main state representation is a grid board with specific cell objects which we'll further customize. So we'll create a new cell object, which in this game needs to keep track of its owner (or the player who completed it, -1 meaning the cell is not complete), a list of edges, the cell's position in the grid and the number of edges completed for this cell, a variable simply used for faster computation. We then finish the constructor of this class by initiating all variables to their starting state. For cell edges, we keep track of the two points between which the line is drawn, and the owner of the edge, where -1 here means that the edge does not yet exist on the board. We add equals and hasCode methods so that the class is compatible with HashMaps, but we modify the default options proivded by the IDE to show that owner is not important in this comparison, and that the edge does not have a direction. We also added copy methods in both the edge and cell classes so that we can make deep copies of the board. Finally we add some more variables in the game state class to help speed up computation. However, the grid board is our only component and we can return this in the getAllComponents method. In the copy method we copy all variables, making sure to keep deep copies of the board to avoid accidentally modifying the wrong game states. We do not define a scoring function for now. No components are hidden in this game, so we return an empty list in the getUnknownComponentIds method. We can then add all variables in the reset() function in their initial states with no values, and use the IDE to generate our equals function for us, transferring the contents into the one required by the framework. In the third part, we're looking at the Forward Model. We start by implementing the setup function, which needs to initialise our grid board. We'll keep handy variables of our custom game state and game parameters classes for this. We can then initialise the grid board according to the game's parameters, and then set up our mapping from edges to neighbouring cells, so we can easily find these later, as well as the initial state for each particular cell with our custom constructors. Lastly we initialise all other variables in our game state. To compute the next game state, we'll first keep track of the current number of completed cells, to check if the current player finished one through their action and gets another turn. We can then execute the action within the game state received, and then check our end of game condition. In this case, the game ends when all cells have been completed. If the game is over, we need to set the game status to GAME_END and then find the winner and set the corresponding player results. If the game is not over, we check if the action did not complete a new cell, in which case we move to the next player according to our turn order. The copy function can just return a new instance of this object. Finally, we need to compute the actions available for a player in a given game state. In this game, actions are drawing lines between the dots, or placing edges of cells on the grid board. This action does not exist in the framework, so we create a new class that extends from the AbstractAction class and will implement the logic of our action. The action is to place an edge on the grid, so we keep track of this edge. The action is always successfully executed, and to mark this edge as placed we need to find the neighbouring cells in the grid board and mark this edge as completed in those cells by setting the owner to the currently acting player. We'll also check here if adding this edge completes any of the neighbouring cells and increase the respective counters in the game state. We finish our action class by adding its copy method, equals and hashCode as generated by the IDE and a simple string for any printing purposes. With this class finished, we can complete the action computation in the Forward Model by iterating through all grid cells and finding those cell edges which do not yet exist in the board, using them to create our action objects. As edges may border more than one cell, we need to actually store these in a HashSet instead to avoid duplicating actions and transform this to a list at the end. Now it's time to finish registering the game in the GameType class within the games package, adding cases for our new game in the stringToGameType, createGameInstance and createGUI methods. In this last method, we'll use the PrototypeGUI available in the framework to display our game. With everything set up, we can go back to the Game class in the core package and run our new game! But this doesn't look the best just yet - a simple fix is to adjust the toString method in our cell class, and print its owner, so we can see when a cell has been completed. However, this is still hard to see all the information we'd like, so in this last part of the video I will customize our game's GUI a bit more by copying over the prototype classes of the Prototype GUI and also the grid board view and modify these to suit our particular use case a little bit better. So in the GUI class, the main GUI class, we need to remove several variables that are not actually needed in our case, so everything will be much more simplified. Our view is simply a grid board view, and we do not need anything but the info panel at the top, which shows the current round, the current player acting and so on. In our update function we just need to update our grid board view to pass on the game state. With everything set up, we just need to check that everything still works as before - and it does! So we can go into the grid board view and modify how the cells are being drawn so that we're actually drawing the Dots and Boxes game! You've seen me put a new variable at the top for the size of the dots. And now for each of the cells, we're going to start painting their backgrounds according to the color of the particular owner. Then we're going to draw 4 dots in the corners of each cell and we'll draw the cell owner in the middle to keep track of player IDs. For the edges, we'll draw them if they exist - and if they do exist, we'll use the color of the owner to actually display them. Now the game looks like this! There are actual colours going on, and it is much easier to tell which player has placed what edge and where. But we can do a little bit better by moving the whole grid a little bit more to the right and down, so that we can see the lines on the very edges of the grid a bit more clearly. Now we can run Game to actually see the agents play the game to completion. If we look back into the Game class, we can match up the player IDs that we're seeing on the board with the order in which we've added the players in the players array list. And that's it! The game is fully implemented and can be played by humans as well, although the GUI might need further customization to allow for more intuitive human interaction, such as selecting 2 dots between which to draw the line. But these are all the basics required for the game, and it is now fully compatible with all the AI players and game analysis systems in the framework. The implementation took about an hour in real time, so it is very quick and easy to get a new game fully set up in the framework. If you found this interesting, please check out the project on GitHub and associated publications linked. Thank you for watching!