Tic Tac Toe

Early Handin: Thursday, September 26, 11:59pm EST
Regular Handin: Saturday, September 28, 11:59pm EST
Late Handin: Monday, September 30, 11:59pm EST

Watch the demo here!

Assignment Roadmap

Silly Premise

Uncle Iroh just invited you to play a friendly game of Tic Tac Toe over a lovely cup of jasmine tea. The only problem is: Momo stole his artisanal hand-carved Tic Tac Toe set! Rather than simply draw a Tic Tac Toe board in the sand like a peasant, you are going to build an awesome Tic Tac Toe game in Java. Let's get started, the tea is getting cold!

Reference: Avatar the Last Airbender, Nickelodeon

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Collaboration Policy Reminder

If you ever have questions about the collaboration policy, refer to the collaboration policy or ask a TA!

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

New Concepts Covered

  • Association
  • Accessor/mutator (“get”/”set”) methods
  • Writing classes from scratch
  • Implementing interfaces

Helpful Resources

Installing Stencil Code

Click here to get the stencil from GitHub — refer to the CS15 GitHub Guide for help with GitHub and GitHub Classroom. Once you have the URL of your personal GitHub repository, open the IntelliJ terminal. Move into your local src/ folder, then use the command git clone <URL>

Once you’ve cloned your personal repository from GitHub, you’ll need to rename your local folder from tictactoe-<yourGitHubLogin> to just tictactoe. You will have issues running your code until you make the change.

Grading

The grade for this assignment will be determined by functionality (55%), design (30%), and style (15%). See each of those sections for more details of this grading breakdown. An ‘A’ project would meet mostly all full functionality requirements with good design and style.


Functionality

Watching the demo will give you a better understanding of your task; we strongly recommend you do this as soon as you can.

For this assignment you’ll be implementing your very own game of Tic Tac Toe! Your game will have two TicTacToePlayers competing against each other by placing their respective symbols (“X”s and “O”s) on a TicTacToeBoard. You’ll use a Controller as a “referee” of the game to switch turns, check for a winner, and display updates about the gameplay.

The table below summarizes what update should be displayed on each game condition. The wording doesn’t have to be identical, but the general meaning should be the same:

Game Condition (automatically checked by support code) Relevant Method (automatically called by support code) Message to Display Note
When a player selects a square so their turn ends selectSquare “Player X finished their turn!” The player’s “name” (here “X”) must match that player’s designated symbol.
When a player selects a square that’s been taken invalidSquareChosen “Square chosen has already been taken! Try again.” In addition, the selected square should flash some color.
When a player wins playerWins “Player X wins!” The player's “name” (here “X”) must match that player’s designated symbol. In addition, the winning squares should be highlighted some color.
When the game ends in a tie noWinner "It's a tie!"
When the game starts or restarts restartGame “Select a square to start playing!” In addition on game restart, the board symbols and highlights should be cleared. Be sure to call playAgain on restart or the game will act buggy!

The support code will automatically check for these game conditions (just like how the support code checks when the user presses the “Up” key or when the ball moves offscreen in Pong), so you should never call any of these methods. Instead, you just need to define what should happen in their method bodies. Read more in the Javadocs.

Coding Incrementally

After you’ve watched the demo, thoroughly read this handout and the Javadocs in full to make sure you understand the project. Before you start coding, make sure you complete the TicTacToe JavaDocs Diagnostic. Once you’re done with that, start coding! It is important to code incrementally, meaning completely accomplishing one logical task before moving on to the next one.

Compiling and Running Your Code

Most importantly, incremental coding means that you run your code after each step to ensure it’s working as you want it to! Refer to the Rattytouille handout for more detailed instructions on how to compile and run your code. Here is a summary:

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

  1. cd tictactoe
  2. javac *.java
  3. cd ..
  4. java tictactoe.App
  5. Repeat!

Suggested Order for Incremental Coding

Step 1. Run the stencil code and complete the TicTacToe JavaDocs Diagnostic.

  • The stencil will appear as a mostly-gray background with a Quit and Restart button.

Step 2. Write a top-level logic class that implements the CS15TicTacToeGame interface, and make the game show up in the App frame. We highly recommend getting something to show up on the screen before doing anything else.

  • Java will ask you to declare method signatures required by an interface before successfully compiling. For now, these method definitions can be left empty.
  • After successful completion of this step, you will see two separate, white portions of the screen for the Controller and CS15TicTacToeBoard, with a dark blue portion at the bottom for the buttons.
  • Make sure you write all of your new code in the App class beneath the line that reads CS15TicTacToeFrame frame = new CS15TicTacToeFrame(stage);

Step 3. In your top level logic class, instantiate a CS15TicTacToeBoard and a Controller so that the screen appears ready to start a round of tic tac toe. When the game starts, you should make the Controller display the message “Select a square to start playing!”.

Step 4. Create a class to represent the players, implementing the CS15TicTacToePlayer interface. Think about what each player needs to know about, take a look here for some tips!

Step 5. Create two instances of your player class (one using the "X" symbol and one using the "O" symbol) and add them to the game via the Controller.

Note: if you do not use X and O, our ✨magic support code✨ won’t run properly, so be sure to use those letters!

Step 6. Implement the selectSquare method so that when the user clicks, the player’s symbol (i.e. “X” or “O”) appears in that square. Be sure to update the Controller’s message per the table above and then (after updating the message) tell the controller that this turn is over.

Step 7. Implement the four remaining methods in the top-level logic class to deal with various game scenarios described in the table above.

Saving Your Work on GitHub

Refer to the CS15 GitHub Guide for more detailed instructions on how to save snapshots of your work to GitHub. We recommend doing this around once an hour to make sure you’re maintaining a copy of your code. Here is a summary:

  1. Move into the tictactoe directory
  2. git add -A
  3. git commit -m “<some descriptive message>”
  4. git push
  5. Repeat!

Minimum Functionality Requirements

MF Policy Summary: In order to pass CS15, you will have to meet minimum functionality requirements for all projects. If you don’t meet them the first time around, you may hand the project in again until you succeed, but you will keep your original grade. MF requirements are not the same as the requirements for full credit on the project. You should attempt the full requirements on every project to keep pace with the course material. An ‘A’ project would meet all of the requirements on the handout and have good design and code style.

To meet MF for Tic Tac Toe:

  • Both players’ symbols show up on click (i.e. “X” and “O”)
  • Controller text updates appropriately for game winning and ties
  • Winning squares are highlighted in a color

Full Functionality Requirements

Beyond the minimum functionality requirements, the rest of the functionality grade will depend on the following criteria:

  • Game properly restarts when the “Restart” button is clicked
  • Controller box text updates appropriately for invalid square selection
  • Invalid square selection flashes a color
  • No minor bugs

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →


Implementation

Support Code Interfaces

Rather than providing stencil classes with stencil methods for this project, we’re providing two interfaces for you to implement in two separate classes you must write from scratch. In order for the support code to connect to your code for this project, you must make sure that you create:

  • one top-level logic class that implements the CS15TicTacToeGame interface
  • one class that models a player and implements the CS15TicTacToePlayer interface

As discussed in lecture, an interface can be thought of as a “contract” signed by one or more classes. This contract outlines specific methods that must be written by whatever classes implement the interface. Take a look at the “Interfaces and Polymorphism” lecture for a reminder on the syntax for an interface.

As a reminder, by implementing an interface, the class promises to define all of the methods declared in the interface. Keep that rule in mind when you’re writing your classes (and don’t forget the @Override tags!). All of these methods will be called ✨automagically✨ by the support code in the appropriate situations.

To create a new Java class in IntelliJ, right-click on the tictactoe package folder on the left-hand “Project” tab, then select New > Java Class. This will create a new .java file with the class declaration written for you. Make sure each class has a name that describes its purpose in the context of the project.

Refer to the Javadocs for descriptions of the CS15TicTacToePlayer and CS15TicTacToeGame interface methods that you will need to implement.

Important: Each of those methods is already automatically called by the support code in the relevant scenario (summarized in the table above Coding Incrementally). For example, when all squares have been selected but there is no 3-in-a-row, the noWinner method will be called. Or, when a player clicks on a square, the selectSquare method will be called. Your job is to write the code to determine what should happen in each situation!

In short, we’ve written most of the code for a tic tac toe game to operate in the support code. Your job is to connect all the pieces together by implementing the methods defined in the support code interfaces.

Javadocs

The Javadocs have a list of all the classes in the support code and what they do, including support classes and methods, which you cannot see but must use to implement this project! The Javadocs provide detailed documentation of the support code that you need to use in this project. Reading them should help you understand how to connect all the components in this project to create a game.

The Javadocs contain information that you cannot find in this handout — you will have much trouble implementing this project if you haven’t thoroughly read the Javadocs. When in doubt, first check the handout, then the Javadocs.

Using JavaFX Colors

Java has its own form of built-in support code called “libraries”, which consist of a collection of related packages. The JavaFX library is a set of packages used for creating graphics in Java — you’ll get very familiar with JavaFX starting during the Graphics lectures.

The package javafx.scene.paint contains one very useful class called Color and defines a series of constants that represent color values. You can find a full list of colors in the javafx.scene.paint.Color Javadocs here. In order to use any of these colors in a class, you should import the class javafx.scene.paint.Color at the top of the file and then reference a call like Color.ALICEBLUE or Color.FUCHSIA.

You’ll find methods in the support code that require a Color as an argument. You can choose any of the JavaFX Colors as long as the color change is clear and the tic tac toe board is still visible!

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

A Note on getWinningPlayer

In the playerWins method, you’ll need to know which player has won in order to include the winning player’s symbol in the controller message, so you can use the getWinningPlayer method, which the Javadocs say returns type CS15TicTacToePlayer, i.e. any class that implements the CS15TicTacToePlayer interface. Our support code uses this generic return type because we can’t know what you will name your class, but using the interface as a return type guarantees that in your code, any class that implements this interface will be accepted (polymorphism in action)!

Remember that implementing an interface does not limit the methods that you can have in that class. You are still allowed to explicitly declare and define any methods you need that are not required by the interface. In other words, your class that implements CS15TicTacToePlayer can have more methods than just selectSquare, if you so wish.

Consider this block of code you might write:

CS15TicTacToePlayer player = this.controller.getWinningPlayer();
player.methodThatYouWrote(); // your methods should be named more clearly

This code is a great example of a polymorphic declared type versus an actual type. While the declared type of this player variable is CS15TicTacToePlayer, its actual type would be the class that you wrote to represent the player. But, because methodThatYouWrote isn’t defined in the interface, this code would cause a compiler error (try it!).

Luckily, because of some support code ✨ magic ✨, you can use your own player class as the declared type for the returned player from getWinningPlayer. For example, if your class is called TicTacToePlayer, the following code block would work:

TicTacToePlayer player = this.controller.getWinningPlayer();
player.methodThatYouWrote();

Design

Design Tips

Association: Imagine a tic tac toe game where you open the box and pull out a board to start playing with, but both players also bring boards of their own. You wouldn’t actually be playing the game together! Instead, each player needs to know about the same Board they will be playing on. The same idea goes for the Controller!

Player Symbols: How will each player know what letter to put down on the board? We can think of each symbol as a property of that player – when creating (i.e., instantiating) a player, it needs to be told what its symbol is (remember that the symbols would be of type String). Think about how this can be stored so the player knows its symbol (as long as it exists). What special type of method can you write so that the top-level logic class can also know the player’s symbol while keeping the information private in the player class?

Check out the Working with Objects II lecture for helpful concepts (especially association)! We also recommend using lab1 as a reference for using concepts like local vs. instance variables and creating class diagrams.

Like Pong, you’ll need to create a class diagram that represents the design of this program and submit it in your final submission. This diagram will be factored into the “design” portion of the grade.

The following classes must be present in your class diagram for full points:

  • Your top-level logic class that implements CS15TicTacToeGame
  • Your player class that implements CS15TicTacToePlayer
  • CS15TicTacToeBoard
  • CS15TicTacToeController
  • CS15TicTacToeSquare

You can read more about how to make a class diagram here. You are not required to make an interface/inheritance diagram for this project. To make your diagram, we recommend using Google Docs/Slides/Drawing or paper and pencil. Be sure to upload your diagram to your GitHub repository. Make sure your diagram is a .pdf, .jpg/.jpeg, or .png file. If you submit a different file format, it may be unsupported so you will receive no credit for the diagram.


Style

Refer to the CS0150 Style Guide for the specific style guidelines along which your code will be graded for the “style” portion.

Handing In

README

In CS15, you’re required to hand in a README file (must be named README) that documents any notable design choices or known bugs in your program. Remember that clear, detailed, and concise READMEs best allow your TAs to understand your thought process, helping them better understand your project as well.

You are expected to create your own README file. Please refer to the README guide for information on how to create a README, what information your README should contain, and how you must format it.

For this project, you should include the following information (in 1-2 sentences each) under the Design Choices section of the README:

  1. Where did you use association? Why was this necessary?
  2. Did you write any accessor or mutator methods? Where? Why was this necessary?

At the bottom of your README, add the approximate number of hours you spent on this assignment. This will be used only to average how long the assignments are taking students this semester, and it is completely anonymous.

Handin

To hand in your assignment, follow these steps:

  1. In a terminal, move into the tictactoe folder as if you were about to compile your code
  2. Type the command rm *.class (Mac) or del *.class (Windows)
    a. This will remove the .class files that are created when compiling so that your submission only includes .java code files.
  3. Add your diagram to your repository
    a. Drag and drop or upload your class diagram to your tictactoe folder
  4. Add, commit, and push your code to GitHub
  5. Go to CS15 2024 on Gradescope.
  6. In the submission for TicTacToe on Gradescope, click on GitHub.
  7. Select your Tic Tac Toe repository and the main branch
  8. Upload! Double check that you have uploaded to Gradescope properly and your diagram appears on the submission.

You can submit as many times as you want prior to the deadline, and only your most recent handin will be graded. If you handin before the deadline and again after the deadline, the submission will be counted as late.

Do not include any identifying information on your handin (name, login, Banner ID) as we grade anonymously. Including identifying information will result in a deduction from your assignment.