44
Engr 691 Engr 691 Special Topics in Special Topics in Engineering Science Engineering Science Software Architecture Software Architecture Spring Semester 2004 Spring Semester 2004 Lecture Notes Lecture Notes

Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Embed Size (px)

Citation preview

Page 1: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Engr 691Engr 691Special Topics in Engineering ScienceSpecial Topics in Engineering Science

Software ArchitectureSoftware Architecture

Spring Semester 2004Spring Semester 2004

Lecture NotesLecture Notes

Page 2: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Solitaire Case Study Solitaire Case Study (Budd's UOOPJ, Ch. 9)(Budd's UOOPJ, Ch. 9)

This is a set of slides to accompany chapter 9 of This is a set of slides to accompany chapter 9 of Timothy Budd's textbook Timothy Budd's textbook

Understanding Object-Oriented Programming with Java, Understanding Object-Oriented Programming with Java, Updated EditionUpdated Edition

(Addison-Wesley, 2000)(Addison-Wesley, 2000)

Page 3: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

The Solitaire GameThe Solitaire Game

Good example of inheritance in action Good example of inheritance in action

Constructed from classes for cards, card Constructed from classes for cards, card piles, and the game application piles, and the game application

Page 4: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Class CardClass Card

import java.awt.*; import java.awt.*;

public class Card public class Card { { // public constants for card dimensions // public constants for card dimensions public final static int width = 50; public final static int width = 50; public final static int height = 70; public final static int height = 70;

// public constants for card suits // public constants for card suits public final static int heart = 0; public final static int heart = 0; public final static int spade = 1; public final static int spade = 1; public final static int diamond = 2; public final static int diamond = 2; public final static int club = 3; public final static int club = 3;

Page 5: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Class Card (continued)Class Card (continued)

// constructors // constructors public Card (int sv, int rv) public Card (int sv, int rv) { { s = sv; s = sv; r = rv; r = rv; faceup = false; faceup = false; } }

// mutators // mutators public final void flip() public final void flip() { { faceup = ! faceup; faceup = ! faceup; } }

Page 6: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Class Card (continued)Class Card (continued)

// accessors // accessors public final int rank () public final int rank () { { return r; return r; } }

public final int suit() public final int suit() { { return s; return s; } }

public final boolean faceUp() public final boolean faceUp() { { return faceup; return faceup; } }

Page 7: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Class Card (continued)Class Card (continued) public final Color color() public final Color color() { { if (faceUp()) if (faceUp()) if (suit() == heart || suit() == diamond) if (suit() == heart || suit() == diamond) return Color.red; return Color.red; else else return Color.black; return Color.black; return Color.yellow; return Color.yellow; } }

public void draw (Graphics g, int x, int y) { /* ... */ } public void draw (Graphics g, int x, int y) { /* ... */ }

// internal data fields // internal data fields private boolean faceup; // card face exposed? private boolean faceup; // card face exposed? private int r; // card rank private int r; // card rank private int s; // card suit private int s; // card suit } }

Page 8: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Notes on Class CardNotes on Class Card

Class implements playing card abstraction Class implements playing card abstraction

Textbook code rearranged into our standard formatTextbook code rearranged into our standard format

importimport makes package makes package java.awtjava.awt available to program available to program—part of Java API—part of Java API

Variables and classes can be used before defined Variables and classes can be used before defined (except local variables in methods)(except local variables in methods)

Page 9: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Notes on Class Card (continued)Notes on Class Card (continued)

Java has no global variables, constants, or enumerated Java has no global variables, constants, or enumerated data typesdata types

staticstatic data fields (i.e., class variables) used for global data fields (i.e., class variables) used for global finalfinal data fields used for constants – assigned once, then not redefined data fields used for constants – assigned once, then not redefined Three internal data fields Three internal data fields

rankrank and and suitsuit are read-only – accessors but no mutators are read-only – accessors but no mutators faceupfaceup can be modified – can be modified – flip()flip() mutator mutator

drawdraw is complex method – accessor with side effects is complex method – accessor with side effects finalfinal methods – accessors methods – accessors rank(),rank(), suit(),suit(), faceup(),faceup(), and and color(),color(), and and

mutator mutator flip()flip() cannot be overridden in subclasses cannot be overridden in subclasses can be optimized – expanded inline like a macro – efficient but inhibits reuse! can be optimized – expanded inline like a macro – efficient but inhibits reuse!

drawdraw is not final – implementation may be somewhat platform dependent is not final – implementation may be somewhat platform dependent

Page 10: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Card ImagesCard Images

See Figure 9.3 on page 145 of Budd's See Figure 9.3 on page 145 of Budd's

UOOPJUOOPJ. .

Page 11: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Method drawMethod draw

import java.awt.*; import java.awt.*;

public class Card public class Card { { // ... // ... public void draw (Graphics g, int x, int y) public void draw (Graphics g, int x, int y) { { String names[] = {"A", "2", "3", "4", "5", "6", "7", "8", "9", String names[] = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"}; "10", "J", "Q", "K"};

// clear rectangle, draw border // clear rectangle, draw border g.clearRect(x, y, width, height); g.clearRect(x, y, width, height); g.setColor(Color.blue); g.setColor(Color.blue); g.drawRect(x, y, width, height); g.drawRect(x, y, width, height);

// draw body of card // draw body of card g.setColor(color()); g.setColor(color());

Page 12: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Method draw (continued)Method draw (continued)if (faceUp()) if (faceUp()) { { g.drawString(names[rank()], x+3, y+15); g.drawString(names[rank()], x+3, y+15); if (suit() == heart) if (suit() == heart) { g.drawLine(x+25, y+30, x+35, y+20); g.drawLine(x+35, y+20, x+45, y+30); { g.drawLine(x+25, y+30, x+35, y+20); g.drawLine(x+35, y+20, x+45, y+30); g.drawLine(x+45, y+30, x+25, y+60); g.drawLine(x+25, y+60, x+5, y+30); g.drawLine(x+45, y+30, x+25, y+60); g.drawLine(x+25, y+60, x+5, y+30); g.drawLine(x+5, y+30, x+15, y+20); g.drawLine(x+15, y+20, x+25, y+30); g.drawLine(x+5, y+30, x+15, y+20); g.drawLine(x+15, y+20, x+25, y+30); } else if (suit() == spade) { } else if (suit() == spade) { g.drawLine(x+25, y+20, x+40, y+50); g.drawLine(x+40, y+50, x+10, y+50); g.drawLine(x+25, y+20, x+40, y+50); g.drawLine(x+40, y+50, x+10, y+50); g.drawLine(x+10, y+50, x+25, y+20); g.drawLine(x+23, y+45, x+20, y+60); g.drawLine(x+10, y+50, x+25, y+20); g.drawLine(x+23, y+45, x+20, y+60); g.drawLine(x+20, y+60, x+30, y+60); g.drawLine(x+30, y+60, x+27, y+45); g.drawLine(x+20, y+60, x+30, y+60); g.drawLine(x+30, y+60, x+27, y+45); } else if (suit() == diamond) { } else if (suit() == diamond) { g.drawLine(x+25, y+20, x+40, y+40); g.drawLine(x+40, y+40, x+25, y+60); g.drawLine(x+25, y+20, x+40, y+40); g.drawLine(x+40, y+40, x+25, y+60); g.drawLine(x+25, y+60, x+10, y+40); g.drawLine(x+10, y+40, x+25, y+20); g.drawLine(x+25, y+60, x+10, y+40); g.drawLine(x+10, y+40, x+25, y+20); } else if (suit() == club) { } else if (suit() == club) { g.drawOval(x+20, y+25, 10, 10); g.drawOval(x+25, y+35, 10, 10); g.drawOval(x+20, y+25, 10, 10); g.drawOval(x+25, y+35, 10, 10); g.drawOval(x+15, y+35, 10, 10); g.drawLine(x+23, y+45, x+20, y+55); g.drawOval(x+15, y+35, 10, 10); g.drawLine(x+23, y+45, x+20, y+55); g.drawLine(x+20, y+55, x+30, y+55); g.drawLine(x+30, y+55, x+27, y+45);g.drawLine(x+20, y+55, x+30, y+55); g.drawLine(x+30, y+55, x+27, y+45); } } }}

Page 13: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Method draw (continued)Method draw (continued)

else { else {

// face down // face down

g.drawLine(x+15, y+5, x+15, y+65); g.drawLine(x+15, y+5, x+15, y+65);

g.drawLine(x+35, y+5, x+35, y+65); g.drawLine(x+35, y+5, x+35, y+65);

g.drawLine(x+5, y+20, x+45, y+20); g.drawLine(x+5, y+20, x+45, y+20);

g.drawLine(x+5, y+35, x+45, y+35); g.drawLine(x+5, y+35, x+45, y+35);

g.drawLine(x+5, y+50, x+45, y+50); g.drawLine(x+5, y+50, x+45, y+50);

} }

} }

}}

Page 14: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Notes on Method drawNotes on Method draw

Displays the card on screenDisplays the card on screen

Parameter is current graphics contextParameter is current graphics context

argument is object of class argument is object of class java.awt.Graphicsjava.awt.Graphics class class GraphicsGraphics in Java API provides many drawing primitives in Java API provides many drawing primitives methods for printing bit-maps available for more sophisticated methods for printing bit-maps available for more sophisticated

visuals visuals

Constants such as Constants such as Color.redColor.red and and Color.blackColor.black defined defined in class in class java.awt.Colorjava.awt.Color

drawdraw is instance method – every card responsible for is instance method – every card responsible for drawing itself drawing itself

Page 15: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

The GameThe Game

See Figure 9.4 on page 145 of Budd's See Figure 9.4 on page 145 of Budd's UOOPJUOOPJ. .

Page 16: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Class CardPileClass CardPile

import java.awt.*; import java.awt.*; import java.util.Stack; import java.util.Stack; import java.util.EmptyStackException; import java.util.EmptyStackException;

public class CardPile public class CardPile { { // constructors // constructors public CardPile (int xl, int yl) public CardPile (int xl, int yl) { { x = xl; x = xl; y = yl; y = yl; thePile = new Stack(); thePile = new Stack(); }}

Page 17: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Class CardPile (continued)Class CardPile (continued)

//mutators //mutators public final Card pop() public final Card pop() { { try { try { return (Card) thePile.pop(); return (Card) thePile.pop(); } catch (EmptyStackException e) { } catch (EmptyStackException e) { return null; return null; } } } }

public void addCard (Card aCard) // sometimes overridden public void addCard (Card aCard) // sometimes overridden { { thePile.push(aCard); thePile.push(aCard); } }

public void select (int tx, int ty) // sometimes overridden public void select (int tx, int ty) // sometimes overridden { /* do nothing */ }{ /* do nothing */ }

Page 18: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Class CardPile (continued)Class CardPile (continued)// accessors // accessors public final Card top() public final Card top() { return (Card) thePile.peek(); } { return (Card) thePile.peek(); }

public final boolean isEmpty() public final boolean isEmpty() { return thePile.empty(); } { return thePile.empty(); }

public boolean includes (int tx, int ty) // sometimes overridden public boolean includes (int tx, int ty) // sometimes overridden { { return x <= tx && tx <= x + Card.width return x <= tx && tx <= x + Card.width && y <= ty && ty <= y + Card.height; && y <= ty && ty <= y + Card.height; } }

public boolean canTake (Card aCard) // sometimes overridden public boolean canTake (Card aCard) // sometimes overridden { return false; } { return false; }

public void display (Graphics g) // sometimes overridden public void display (Graphics g) // sometimes overridden {{ g.setColor(Color.blue); g.setColor(Color.blue); if (isEmpty()) if (isEmpty()) g.drawRect(x, y, Card.width, Card.height); g.drawRect(x, y, Card.width, Card.height); else else top().draw(g, x, y); top().draw(g, x, y); }}

Page 19: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Class CardPile (continued)Class CardPile (continued)

// protected data fields // protected data fields // coordinates of the card pile // coordinates of the card pile protected int x; protected int x; // (x,y) is upper left corner// (x,y) is upper left corner protected int y; protected int y; // cards in the pile// cards in the pile protected Stack thePile;protected Stack thePile;}}

Page 20: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Notes on Class CardPileNotes on Class CardPile

Implementation of card deck abstraction Implementation of card deck abstraction – – base class extended for specific behaviors base class extended for specific behaviors

Uses generic container Uses generic container StackStack from Java API for pile of cards from Java API for pile of cards empty initially empty initially StackStack operations implement operations implement CardCard operations – adapter pattern operations – adapter pattern Cast objects back to Cast objects back to CardCard when taken from stack when taken from stack

Uses global symbolic constants Uses global symbolic constants Card.widthCard.width and and Card.height Card.height – – access to static fields using class name, not instance name (actually, either works)access to static fields using class name, not instance name (actually, either works)

poppop, , toptop, and , and isEmptyisEmpty implementation for subclasses -- final methods implementation for subclasses -- final methods

addCardaddCard, , selectselect, , includesincludes, , canTakecanTake, and , and displaydisplay part of abstraction, but part of abstraction, but implementation varies among subclassesimplementation varies among subclasses

protectedprotected data fields accessible by subclasses data fields accessible by subclasses

Instructor's comment: Instructor's comment: – protectedprotected data fields usually bad practice – trusts subclasses (perhaps in different package) data fields usually bad practice – trusts subclasses (perhaps in different package)

to manipulate internal fields correctly – safer to provide appropriate protected mutators and to manipulate internal fields correctly – safer to provide appropriate protected mutators and accessors instead (perhaps accessors instead (perhaps finalfinal) )

Page 21: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Informal Specification of Informal Specification of CardPile's Non-final MethodsCardPile's Non-final Methods

Methods may need to be overridden to give the card deck the appropriate behaviors. Methods may need to be overridden to give the card deck the appropriate behaviors.

addCard(c)addCard(c) – adds card c to the card pile adds card c to the card pile

select(x,y)select(x,y) – performs an action in response to mouse click at (x,y) performs an action in response to mouse click at (x,y)

includes(x,y)includes(x,y) – determines whether (x,y) within boundary of the pile determines whether (x,y) within boundary of the pile

canTake(c)canTake(c) – determines whether the pile can take card c (according to the rules governing the pile) determines whether the pile can take card c (according to the rules governing the pile)

display(g)display(g) – displays the pile using graphics context g displays the pile using graphics context g

Page 22: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Class SuitPileClass SuitPile

class SuitPile extends CardPile class SuitPile extends CardPile { // constructors { // constructors public SuitPile (int x, int y) public SuitPile (int x, int y) { super(x, y); } { super(x, y); }

// accessors // accessors public boolean canTake (Card aCard) public boolean canTake (Card aCard) // overrides parent // overrides parent { if (isEmpty()) { if (isEmpty()) return aCard.rank() == 0; return aCard.rank() == 0; Card topCard = top(); Card topCard = top(); return (aCard.suit() == topCard.suit()) return (aCard.suit() == topCard.suit()) && (aCard.rank() == 1 + topCard.rank()); && (aCard.rank() == 1 + topCard.rank()); } } } }

Page 23: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Notes on Class SuitPileNotes on Class SuitPile

Represents one of the (4) piles of cards at top of playing Represents one of the (4) piles of cards at top of playing surface – built up in suit from Ace (1) to King (13) surface – built up in suit from Ace (1) to King (13)

Keyword extends indicates inheritance from Keyword extends indicates inheritance from CardPileCardPile

super indicates parent – in constructor used to call super indicates parent – in constructor used to call parent's constructor for initialization – first statement only parent's constructor for initialization – first statement only

Method Method canTakecanTake overridden by replacement – overridden by replacement – canTakecanTake if pile empty or card is next higher of same suit if pile empty or card is next higher of same suit

Page 24: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Class DeckPileClass DeckPile

import java.util.Random ; import java.util.Random ;

class DeckPile extends CardPile class DeckPile extends CardPile { // constructors { // constructors public DeckPile (int x, int y) public DeckPile (int x, int y) { // first initialize parent { // first initialize parent super(x, y); super(x, y); // then create the new deck, first put them into a local pile // then create the new deck, first put them into a local pile for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++) for (int j = 0; j <= 12; j++) for (int j = 0; j <= 12; j++) addCard(new Card(i, j)); addCard(new Card(i, j)); // then shuffle the cards // then shuffle the cards Random generator = new Random(); Random generator = new Random(); for (int i = 0; i < 52; i++) { for (int i = 0; i < 52; i++) { int j = Math.abs(generator.nextInt() % 52); int j = Math.abs(generator.nextInt() % 52); // swap the two card values // swap the two card values Object temp = thePile.elementAt(i); Object temp = thePile.elementAt(i); thePile.setElementAt(thePile.elementAt(j), i); thePile.setElementAt(thePile.elementAt(j), i); thePile.setElementAt(temp, j); thePile.setElementAt(temp, j); } } } }

// mutators // mutators public void select(int tx, int ty) { public void select(int tx, int ty) { if (isEmpty()) return; if (isEmpty()) return; Solitaire.discardPile.addCard(pop()); Solitaire.discardPile.addCard(pop()); } } }}

Page 25: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Notes on Class DeckPileNotes on Class DeckPileRepresents the original deck of cards Represents the original deck of cards

Uses super in constructor for basic initialization, new code for Uses super in constructor for basic initialization, new code for specific initialization specific initialization

Accesses Accesses staticstatic (class) methods – absolute value function (class) methods – absolute value function Math.abs()Math.abs()

Overrides method select by replacement – if pile nonempty, add top Overrides method select by replacement – if pile nonempty, add top card to discard pile card to discard pile

Java API Java API StackStack extends extends VectorVector – select uses the "ranked – select uses the "ranked sequence" methods of sequence" methods of VectorVector

Instructor's comment: Instructor's comment: – StackStack extending extending VectorVector is poor design in the Java API! Similarly, the is poor design in the Java API! Similarly, the

choice of choice of StackStack is a questionable design. Better to just use is a questionable design. Better to just use VectorVector directly directly

Page 26: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Notes on Class DeckPile Notes on Class DeckPile (continued)(continued)

Accesses utility class Accesses utility class java.util.Randomjava.util.Random to generate to generate pseudo-random numbers pseudo-random numbers

Accesses Accesses staticstatic (class) variables to share single copies (class) variables to share single copies– Solitaire.discardPile Solitaire.discardPile – Author has only one discard pile, so made this class access that Author has only one discard pile, so made this class access that

instance directly instance directly

Instructor's comment:Instructor's comment:– Hard-coding of reference to Hard-coding of reference to staticstatic discard pile inhibits discard pile inhibits

reusability of the deck reusability of the deck – Probably better to pass discard deck to constructor of Probably better to pass discard deck to constructor of DeckPileDeckPile, ,

store reference, manipulate it store reference, manipulate it

Page 27: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Notes on Class DeckPileNotes on Class DeckPile(continued)(continued)

Manipulates protected field Manipulates protected field thePilethePile from parent from parent class class CardPileCardPile

Possible alternatives to use of Possible alternatives to use of protectedprotected data data fields: fields: Add (Add (protectedprotected?) "ranked sequence" get and set ?) "ranked sequence" get and set

operations to operations to CardPileCardPile abstraction? abstraction? Add constructor or (Add constructor or (protectedprotected?) set operation to ?) set operation to

CardPileCardPile that takes a sequence (vector, array, etc.) that takes a sequence (vector, array, etc.) of cards to (re)initialize pile? get method? of cards to (re)initialize pile? get method?

Add Add shuffleshuffle operation to operation to CardPileCardPile abstraction? abstraction?

Page 28: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Class DiscardPileClass DiscardPile

import java.util.Random; import java.util.Random; class DiscardPile extends CardPile class DiscardPile extends CardPile { { // constructors // constructors public DiscardPile (int x, int y) public DiscardPile (int x, int y) { { super (x, y); super (x, y); } } // mutators // mutators public void addCard (Card aCard) public void addCard (Card aCard) { { if (! aCard.faceUp()) if (! aCard.faceUp()) aCard.flip(); aCard.flip(); super.addCard(aCard); super.addCard(aCard); }}

Page 29: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Class DiscardPile (continued)Class DiscardPile (continued) //mutators//mutators public void select (int tx, int ty) public void select (int tx, int ty) { { if (isEmpty()) if (isEmpty()) return; return; Card topCard = pop(); Card topCard = pop(); for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++) if (Solitaire.suitPile[i].canTake(topCard)) { if (Solitaire.suitPile[i].canTake(topCard)) { Solitaire.suitPile[i].addCard(topCard); Solitaire.suitPile[i].addCard(topCard); return; return; } } for (int i = 0; i < 7; i++) for (int i = 0; i < 7; i++) if (Solitaire.tableau[i].canTake(topCard)) { if (Solitaire.tableau[i].canTake(topCard)) { Solitaire.tableau[i].addCard(topCard); Solitaire.tableau[i].addCard(topCard); return; return; } } // nobody can use it, put it back on our list // nobody can use it, put it back on our list addCard(topCard); addCard(topCard); } } } }

Page 30: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Notes on Class DiscardPileNotes on Class DiscardPile

Represents the discard pile in a Solitaire game Represents the discard pile in a Solitaire game

Constructor refines parent's constructor – uses Constructor refines parent's constructor – uses supersuper call in call in initialization initialization

select method overrides and select method overrides and replacesreplaces one in parent one in parent– checks whether topmost card can be played any suit pile or tableau pile checks whether topmost card can be played any suit pile or tableau pile

addCardaddCard method overrides and method overrides and refinesrefines one in parent one in parent – executes parent method (executes parent method (super.addCardsuper.addCard), but also adds new behavior ), but also adds new behavior – flips card flips card faceupfaceup when put on discard pile when put on discard pile

Hard-coded access to Hard-coded access to staticstatic variables for the (4) suit piles and (7) variables for the (4) suit piles and (7) tableau piles tableau piles – probably better to pass these to constructor, store references, and probably better to pass these to constructor, store references, and

manipulate via local references manipulate via local references

Page 31: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Class TablePileClass TablePile

import java.util.Enumeration ; import java.util.Enumeration ;

class TablePile extends CardPile class TablePile extends CardPile { { // constructors // constructors public TablePile (int x, int y, int c) public TablePile (int x, int y, int c) { // initialize the parent class { // initialize the parent class super(x, y); super(x, y); // then initialize our pile of cards // then initialize our pile of cards for (int i = 0; i < c; i++) { for (int i = 0; i < c; i++) { addCard(Solitaire.deckPile.pop()); addCard(Solitaire.deckPile.pop()); } } // flip topmost card face up // flip topmost card face up top().flip(); top().flip(); }}

Page 32: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Class TablePile (continued)Class TablePile (continued)// mutators // mutators public void select (int tx, int ty) { public void select (int tx, int ty) { if (isEmpty()) return; if (isEmpty()) return; // if face down, then flip // if face down, then flip Card topCard = top(); Card topCard = top(); if (! topCard.faceUp()) { if (! topCard.faceUp()) { topCard.flip(); topCard.flip(); return; return; } // else see if any suit pile can take card } // else see if any suit pile can take card topCard = pop(); topCard = pop(); for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++) if (Solitaire.suitPile[i].canTake(topCard)) { if (Solitaire.suitPile[i].canTake(topCard)) { Solitaire.suitPile[i].addCard(topCard); Solitaire.suitPile[i].addCard(topCard); return; return; } // else see if any other table pile can take card } // else see if any other table pile can take card for (int i = 0; i < 7; i++) for (int i = 0; i < 7; i++) if (Solitaire.tableau[i].canTake(topCard)) { if (Solitaire.tableau[i].canTake(topCard)) { Solitaire.tableau[i].addCard(topCard); Solitaire.tableau[i].addCard(topCard); return; return; } // else put it back on our pile } // else put it back on our pile addCard(topCard); addCard(topCard);

}}

Page 33: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Class TablePile (continued)Class TablePile (continued)

// accessors // accessors public boolean canTake (Card aCard) { public boolean canTake (Card aCard) { if (isEmpty()) if (isEmpty()) return aCard.rank() == 12; return aCard.rank() == 12; Card topCard = top(); Card topCard = top(); return (aCard.color() != topCard.color()) && return (aCard.color() != topCard.color()) && (aCard.rank() == topCard.rank() - 1); (aCard.rank() == topCard.rank() - 1); } } public boolean includes (int tx, int ty) { public boolean includes (int tx, int ty) { // don't test bottom of card // don't test bottom of card return x <= tx && tx <= x + Card.width && y <= ty; return x <= tx && tx <= x + Card.width && y <= ty; } } public void display (Graphics g) { public void display (Graphics g) { int localy = y; int localy = y; for (Enumeration e = thePile.elements(); e.hasMoreElements();) { for (Enumeration e = thePile.elements(); e.hasMoreElements();) { Card aCard = (Card) e.nextElement(); Card aCard = (Card) e.nextElement(); aCard.draw (g, x, localy); aCard.draw (g, x, localy); localy += 35; localy += 35; } } } } } }

Page 34: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Notes on Class TablePileNotes on Class TablePile

Represents one of the (7) tableau piles on the lower part of the playing surface Represents one of the (7) tableau piles on the lower part of the playing surface Initialized with cards from deck – constructor argument gives number needed Initialized with cards from deck – constructor argument gives number needed Top card is face up Top card is face up Add card to empty pile only if King Add card to empty pile only if King Add card to nonempty pile only if opposite color to top and one rank lower Add card to nonempty pile only if opposite color to top and one rank lower Selection action moves any cards from this table pile to suit pile or another table Selection action moves any cards from this table pile to suit pile or another table

pilepile

Uses Uses supersuper in constructor for basic initialization, new code for specific initialization in constructor for basic initialization, new code for specific initialization

Methods Methods selectselect, , canTakecanTake, , includesincludes, and , and displaydisplay override and override and replacereplace ones in ones in parent parent

Method Method displaydisplay Uses Uses java.util.Enumerationjava.util.Enumeration object returned by the object returned by the StackStack to iterate through the to iterate through the

tableau pile tableau pile Displays each card slightly offset from the one below it Displays each card slightly offset from the one below it Accesses Accesses protectedprotected field field thePilethePile from parent class from parent class CardPileCardPile Perhaps define (Perhaps define (protectedprotected?) ?) elements()elements() method in method in CardPileCardPile to return a pile- to return a pile-

EnumerationEnumeration object – to avoid object – to avoid protectedprotected fields fields Another alternative: method to return cards in pile as sequence (e.g., array or Another alternative: method to return cards in pile as sequence (e.g., array or

vector) vector)

Page 35: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

The Game Class: SolitaireThe Game Class: Solitaire

import java.awt.*; import java.awt.*; import java.awt.event.*; import java.awt.event.*;

public class Solitaire public class Solitaire { // public class variables for the various card piles of game { // public class variables for the various card piles of game static public DeckPile deckPile; static public DeckPile deckPile; static public DiscardPile discardPile; static public DiscardPile discardPile; static public TablePile tableau [ ]; static public TablePile tableau [ ]; static public SuitPile suitPile [ ]; static public SuitPile suitPile [ ]; // single array to alias all above piles -- aids polymorphism // single array to alias all above piles -- aids polymorphism static public CardPile allPiles [ ]; static public CardPile allPiles [ ];

Page 36: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

The Game Class: Solitaire The Game Class: Solitaire (continued)(continued)

// application entry point // application entry point static public void main (String[] args) static public void main (String[] args) { { Solitaire world = new Solitaire(); Solitaire world = new Solitaire(); } }

// constructors // constructors public Solitaire () public Solitaire () { { window = new SolitaireFrame(); window = new SolitaireFrame(); init(); init(); window.show(); window.show(); }}

Page 37: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

The Game Class: Solitaire The Game Class: Solitaire (continued)(continued)

//mutators //mutators public void init () public void init () { // first allocate the arrays { // first allocate the arrays allPiles = new CardPile[13]; allPiles = new CardPile[13]; suitPile = new SuitPile[4]; suitPile = new SuitPile[4]; tableau = new TablePile[7]; tableau = new TablePile[7]; // then fill them in // then fill them in allPiles[0] = deckPile = new DeckPile(335, 30); allPiles[0] = deckPile = new DeckPile(335, 30); allPiles[1] = discardPile = new DiscardPile(268, 30); allPiles[1] = discardPile = new DiscardPile(268, 30); for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++) allPiles[2+i] = suitPile[i] = new SuitPile(15 + allPiles[2+i] = suitPile[i] = new SuitPile(15 +

(Card.width+10) * i, 30); (Card.width+10) * i, 30); for (int i = 0; i < 7; i++) for (int i = 0; i < 7; i++) allPiles[6+i] = tableau[i] allPiles[6+i] = tableau[i] = new TablePile(15 + (Card.width+5) * i, = new TablePile(15 + (Card.width+5) * i,

Card.height + 35, i+1); Card.height + 35, i+1); }}

Page 38: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

The Game Class: Solitaire The Game Class: Solitaire (continued)(continued)

// inner classes // inner classes

private class SolitaireFrame extends Frame private class SolitaireFrame extends Frame

{ /* expanded later */ } { /* expanded later */ }

// internal data fields // internal data fields

private Frame window;// the application window private Frame window;// the application window

}}

Page 39: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Notes on Class SolitaireNotes on Class Solitaire

Class declares and allocates class (Class declares and allocates class (staticstatic) variables for piles of cards on ) variables for piles of cards on playing surface playing surface

Class sets up Class sets up allpilesallpiles array to "alias" all other piles, regardless of subclass array to "alias" all other piles, regardless of subclass

Control goes initially to class method Control goes initially to class method mainmain

mainmain creates an instance of creates an instance of SolitaireSolitaire application (its only action) application (its only action)

SolitaireSolitaire constructor creates window for application, initializes the playing constructor creates window for application, initializes the playing surface, and displays window surface, and displays window

SolitaireFrameSolitaireFrame is an inner class is an inner class inner class (from the glossary to Budd's UOOPJ textbook): inner class (from the glossary to Budd's UOOPJ textbook):

– a class definition that appears inside another class. Inner classes are allowed a class definition that appears inside another class. Inner classes are allowed access to both the private data fields and the methods of the surrounding class. access to both the private data fields and the methods of the surrounding class. Inner classes are frequently used in building listener objects for handling events. Inner classes are frequently used in building listener objects for handling events.

SolitaireFrameSolitaireFrame manages the application window manages the application window

Page 40: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Inner Class SolitaireFrameInner Class SolitaireFrame

// part of Class Solitaire // part of Class Solitaire private class SolitaireFrame extends Frame private class SolitaireFrame extends Frame { { private class RestartButtonListener implements private class RestartButtonListener implements

ActionListener ActionListener { { public void actionPerformed (ActionEvent e) public void actionPerformed (ActionEvent e) { { init(); init(); window.repaint(); window.repaint(); } } } }

Page 41: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Inner Class SolitaireFrameInner Class SolitaireFrame(continued)(continued)

private class MouseKeeper extends MouseAdapter private class MouseKeeper extends MouseAdapter { { public void mousePressed (MouseEvent e) public void mousePressed (MouseEvent e) { { int x = e.getX(); int x = e.getX(); int y = e.getY(); int y = e.getY(); for (int i = 0; i < 13; i++) for (int i = 0; i < 13; i++) if (allPiles[i].includes(x, y)) if (allPiles[i].includes(x, y)) { { allPiles[i].select(x, y); allPiles[i].select(x, y); repaint(); repaint(); } } }}} }

Page 42: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Inner Class SolitaireFrameInner Class SolitaireFrame(continued)(continued)

public SolitaireFrame() public SolitaireFrame() { { setSize(600, 500); setSize(600, 500); setTitle("Solitaire Game"); setTitle("Solitaire Game"); addMouseListener (new MouseKeeper()); addMouseListener (new MouseKeeper()); Button restartButton = new Button("New Game"); Button restartButton = new Button("New Game"); restartButton.addActionListener(restartButton.addActionListener( new RestartButtonListener()); new RestartButtonListener()); add("South", restartButton); add("South", restartButton); } } public void paint(Graphics g) public void paint(Graphics g) { { for (int i = 0; i < 13; i++) for (int i = 0; i < 13; i++) allPiles[i].display(g); allPiles[i].display(g); } } } }

Page 43: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Notes on Class SolitaireFrameNotes on Class SolitaireFrame

GUI window for the GUI window for the SolitaireSolitaire game application game application

Extends Extends java.awt.Framejava.awt.Frame class class

Event-driven program – system GUI manager in control, Event-driven program – system GUI manager in control, user code "called back" in response to GUI events user code "called back" in response to GUI events

SolitaireFrameSolitaireFrame constructor constructor sets window size, title sets window size, title adds mouse listener "callback" code to respond to mouse events adds mouse listener "callback" code to respond to mouse events adds restart button at bottom of window ("South") and "callback" adds restart button at bottom of window ("South") and "callback"

code to respond to button events code to respond to button events

Page 44: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

Notes on Class SolitaireFrame Notes on Class SolitaireFrame (continued)(continued)

Inner class Inner class MouseKeeperMouseKeeper's method 's method mousePressedmousePressed called on called on mouse click event mouse click event determines which pile selected determines which pile selected performs performs selectselect operation for that pile operation for that pile

note use of polymorphism note use of polymorphism action depends on pile type (i.e., on which subclass) action depends on pile type (i.e., on which subclass)

repaints window repaints window

Inner class Inner class RestartButtonListenerRestartButtonListener method method actionPerformedactionPerformed called on button event called on button event reinitializes game reinitializes game repaints window repaints window

Method paint of Method paint of SolitaireFrameSolitaireFrame called by GUI when frame needs called by GUI when frame needs to be displayedto be displayed note use of polymorphism note use of polymorphism