Lab: Putting a GUI on internal class structure

In this lab, we'll use the simple example from class to look at how to connect a Forms-based GUI with a set of classes that implement the state and logic of the program. You will create a new Windows Forms Application, a simple form, and then connect it with the 2-card "game" we worked on.

Create your new project (Remember to select .NET Framework in Visual Studio 2017) and then download and add this file: GameClasses.cs. It provides complete enough versions of:

  • Card
  • Deck
  • Hand
  • Game

Also, download and uncompress CardImages.zip inside your project.

Implement the following steps to complete the lab.

1) Add four label controls to the form, these will display the two hands.

2) The Tag property of a control is used to store arbitrary data as a string. Set the tag for each of the four labels to identify them:

  • "00": first player, first card
  • "01": first player, second card
  • "10": second player, first card
  • "11": second player, second card

3) In the initialization for the form (when it is created and ready), create the new Game object and call Setup() to create the objects and deal out the cards.

4) Now, we want to see the cards! Either the GUI Form knows about the internal Game classes, or the Game knows about the GUI, but not both. It is generally better to think of the GUI as something that lays over the Game and interfaces with the user, which is why we set up the prior step with the Form owning the Game object. After Setup() is done, we need to update the GUI to show the cards.

In the Hand class, write a method to retrieve the card information for a specified card position (e.g. position 0). This shouldn't change the hand, we're just looking at the card. Your method sould return a CardOrientation object, a wrapper around a Card that includes a faceup boolean.

In the Game class, write a method to retrieve the card information for a specified player and card position (e.g. player 0, position 1). This should use the method you just wrote in Hand. Thinking about the Tags that we put on the Form Label controls, have this method take a string rather than two integers (i.e. "00" rather than 0 and 0). Inside the method you'll need to split that string into two integers to use in calling the Hand method.

Back in the Form initialization, after the call to Setup(), use the Game method you just wrote to get the card info (value-suit-faceup) and set the proper image for each Label control, based on their Tags. You'll need a method to convert from the card info to a filename. Since the images are part of the GUI, that method can be part of the Form.

At this point, your program should display the four cards! Alter the default face-down to face-up in the code to verify that it's working correctly.

5) To close the loop, make it so that clicking on a card toggles it face-down/face-up. Remember that the Game classes hold state, so the GUI's job is to update the Game when the user does something, then update itself based on the updated state. the process for a click should look like:

  • Add a click handler to the Form Labels. In that handler:
    1. Call a new method on the Game object to pass in the Tag of the Label that was clicked
    2. ...That method should update the internal state (i.e. flip that card over)
    3. Call the method you already wrote on the Game object to get the updated card info for the Label that was clicked
    4. Update the Label image to reflect that card info

Commit your work!

https://cssvn.utrgv.edu/svn_etomai/201810_3328/lab06_ui_state/<username>