Homework 4 - 15 points + 10 points extra-credit


Let the adventure begin

Purpose

The purpose of this assignment is to gain experience with the following topics:

Your mission in this assignment is to write a simple text-based adventure game (details). This assignment was designed by Eric Roberts from Stanford University.

Starter files: AdvCommand.java, Adventure.java, AdvMotionCommand.java, AdvMotionTableEntry.java, AdvObject.java, AdvRoom.java, adventurestub.jar

Text files: CrowtherObjects.txt, CrowtherRooms.txt, Crowthersynonyms.txt, SmallObjects.txt, SmallRooms.txt, SmallSynonyms.txt, TinyRooms.txt

or all at once Adventure.zip

 

Testing

Add to your project the file AdventureTest.java, and the text files SmallTest.txt, and CrowtherTest.txt.

Make sure that the code in your Adventure class uses the field scan for any input from the console. Test your code by running main in AdventureTest.java. The program should start printing all the actions corresponding to the commands listed in SmallTest.txt. It will end by having the player fall into a pit. The program continues with the list of all of the actions in CrowtherTest.txt. It will lead to a successful completion of the game.

 

Extra credit (10 points)

 

The adventure game is all text-based. In the extra-credit section, you get to use an AI component that adds images to the game. The idea is to feed the description of each room to OpenAI and retrieve the images of the rooms so that they can be shown to the player as they move from room to room. The program should be in charge of querying OpenAI. Do not type in the room descriptions by hand to retrieve the images.

To be able to access the OpenAI API, you will need to create an OpenAI account. Just go to https://auth.openai.com/create-account to sign up. To generate images with the OpenAI API, an API key is required (a long string that uniquely identifies your account). Unfortunately, that key is not free. Before obtaining a key, you will need to enter your credit card information. For this extra credit part, the cost can be kept very reasonable. Each image costs 4 cents. You may only run the extra credit part on the small test case which has 10 rooms, meaning that the total cost will be 40 cents. However, I understand that this can be an issue for some students. If that is the case, I am asking you to visit my face to face office hours so that I can run your program with my API key. Let's turn now to how to do the implementation of the extra credit part.

The first step is to add to the AdvRoom class a field that points to the image file of the room (private File imageFile). I would recommend that you store all of the images in a folder within your project. Do so by creating a folder in your project named "images". Also, use the conventtion that the name of the image file of a room is "roomName.png". For example, the image file for the Debris room is named "Debris room.png".

Then create a class named ImageGenerator. This is the class that contains the methods to query openAI and retrieve the image of a room given its description. This class contains only one public method:

Method

Description

public static File getImage(AdvRoom room) throws Exception

Returns the image file for the given room or null if there should not be any image for that room (that is a room with only "FORCED" directions).

Throws an Exception if the image could be not created.

This method should be called from the AdvRoom.readFromFile(Scanner s), e.g. as room.imageFile = ImageGenerator.getImage(room).

The method getImage should query openAI only if there is not an image file for that room yet. Check if the folder images contains already the image file for that room. If it does, just return the corresponding file (use the exists method from the File class to check if the file is present).

Also, if the room is a room with only "FORCED" directions, then no image is needed since the player is automatically pushed through such a room. If that is the case, just return null.

If there is no image file yet for the given room, we need to query openAI to generate the image, by sending it a prompt that is the description of the room. Make sure that before sending the prompt you remove any special character from the description. OpenAI doesn't seem to work well with double quotes (") and newlines.

To query openAI, use the following code (you will need to import the relevant classes from the package java.net)

		String requestBody = String
				.format("{\"prompt\": \"%s\", \"model\": \"dall-e-3\", \"n\": 1, \"size\": \"1024x1024\"}", prompt);

		HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://api.openai.com/v1/images/generations"))
				.header("Content-Type", "application/json").header("Authorization", "Bearer " + OPENAI_API_KEY)
				.POST(HttpRequest.BodyPublishers.ofString(requestBody)).build();

       HttpClient client = HttpClient.newHttpClient();		
       HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
		String body = response.body();

	

The requestBody string contains the query sent to OpenAI. In plain english, we are asking OpenAI to generate one (n= 1) image of size 1024 pixels x 1024 pixels with the model dall-e-3 following the description given in the prompt. The requestBody string is wrapped in an HttpRequest object. The constant OPENAI_API_KEY is a string that should contain your OpenAI API key to access the OpenAI services.

If all goes well (that is if response.statusCode() is 200), the body of the response contains a URL where you can retrieve the image. Typically, the body looks like this (part of the URL given below has been left out as indicated by the ellipses)

{
  "created": 1759103840,
  "data": [
    {
      "revised_prompt": "An ominous, pitch-black scene, filled with a sense of palpable danger. Should any journey continue, it is almost certain that a deep, unseen pit lies in wait. A warning to lend the cautious pause, a dare to the foolhardy, a testament to the unseen threats that exist when darkness engulfs all.",
      "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-..." 
    }
  ]
}

Extract the string value of the URL (that is "https://oai...") and use an InputStream to that URL to retrieve the image and save it to the images folder (Review the programs we wrote when we learned about streams).

Once all of the images for each room have been created, they can be shown to the player as they move from room to room. In the Adventure class, add code to create a JFrame that contains a JPanel to display an image. Whenever the player gets into a new room, display the image file for that room in the JPanel.

The grading of the extra-credit part will be done during my face to face hours (T,Th after class). I will ask you to demonstrate your program and explain what you did.

 

Individual evaluation report (should be typed and turned in on Canvas)

Evaluate this project:

 

Good Luck and start early!