Java Program Overview You are to write a program that simulates playing the soli
ID: 3825692 • Letter: J
Question
Java Program
Overview
You are to write a program that simulates playing the solitaire card game Clock. We provide several sites at the end of this document that describe and demonstrate the rules; we suggest you familiarize yourself with the game first. Here’s how we want you to implement the simulation.
Part 1 - Required Classes Create a Card class that can represent each of the 52 playing cards: Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King … in each of the four suits: Spades, Hearts, Diamonds, and Clubs.
Implement the following methods:
constructors getSuit() getValue()
String toString(): to print, e.g., “10 of Hearts” or “Queen of Diamonds” or “Ace of Spades” Update: We are thinking that printing cards more compactly -- e.g., “10H” or “QD” or “AS” -- i.e. a one (or two) character value, followed by a one-character suit -- will make both debugging and our grading easier.
Create a Deck class that represents a standard deck of 52 playing cards.
Implement the following methods:
constructors void shuffle(): randomly interchanges cards in the deck to simulate shuffling
Card dealCard() int cardsLeft()
String toString(): iterate through your deck array, printing all the cards, in a way that’s convenient to check what cards are there; we think it’ll be best to print all the cards on one line (or print them on four lines, if you want to get fancy); for cards that have been dealt, either don’t print them, or print them separately, labeled as “dealt”
Create a Pile class that contains no more than five cards… some face down, and some face up.
Implement the following methods:
constructors void addCardFaceDown( Card card) Card removeCard() - removes and returns the “top” face down card (null if there are none)
int getNumberOfFaceDown() void addCardFaceUp( Card card) int getNumberOfFaceUp()
String toString() - print the cards in the Pile; print the contents of a pile on one or two lines; label the portion of the pile that’s face up versus face down
Part 2 - The Clock Solitaire Game Implement the Clock Solitaire Game simulation, with all the following capabilities. We strongly suggest you don’t ignore handling command line arguments, as this feature is simply to implement, and will be a great help in your debugging process, and in our grading. Name your primary class -- the one with the main() method -- ClockSolitaire.
Command-Line Arguments
Your program will accept two command line arguments. (These arguments are optional, and your program will use the “default” values if the argument(s) are not specified. And, implementing handling of command line arguments is not optional.)
1. Print level - one of the following three values: a. verbose b. normal (the default) c. silent
2. Number of games to play (default: 1)
Setup Tasks
create thirteen Piles - these should be stored in an array of Piles (rather than thirteen discrete variables)
create and shuffle a Deck of Cards
deal out the deck to populate (initialize) the thirteen Piles with four face-down cards each - You may deal one card for each of the thirteen Piles, and then a second card, and so on… -or, you may deal four cards to fill the first Pile, four for the second Pile, and so on…
print the thirteen Piles -- the game board (this will mainly uses Pile.toString() ), if the print level is not “silent”; label each pile with its clock position; for simplicity, you can print one pile per line (you can get more creative, if you like)
print the “score”: the number of Piles with at least one face-down card, if the print level is not “silent”; note a game is won when the “score” is zero this will be 13 at the beginning of each game
Playing the Game
1. remove (top, face-down) card from Pile 13, the Kings Pile
2. add it, face-up, to the (“bottom” of the) correct Pile
3. if the print level is “verbose”, print the game board -- the thirteen Piles -- as above
a. also, keep track of and print the “step number,” a counter that you increment each time you “remove-and- add” a card
4. remove (top, face-down) card from that same Pile
a. one needs to check that there are face-down cards remaining b. if there are no face-down cards remaining, the game is over, if you’re on Pile 13 c. (if there are no face-down cards remaining, and you’re not on Pile 13, then there’s an error)
5. repeat this process by going to step 2
When Each Game is Done
print the thirteen Piles -- the game board (as above), if the print level is not “silent”
print the “score”: the number of Piles with at least one face-down card, if the print level is not “silent”
a score of “zero” is a “win”; note this is rare
increment a counter in a Scores array for the number of Piles with at least one face-down card
repeat, from the top (the Setup), according to how many games to play, as specified in the command-line arguments
When You’ve Completed Playing the Required Number of Games
print the number of games played
print the Scores array, along with percentages, as follows; this will be 14 lines, with both the number and percentage of games that resulted in each score
(print this for all print levels, including “silent”)
References: Rules of the Game
Here are some sites that describe the rules of Clock, and one that allows you to “play” it online:
https://www.thespruce.com/clock-solitaire-rules-412468
https://en.wikipedia.org/wiki/Clock_Patience
https://youtu.be/6AEJEf8L95g ; https://youtu.be/yUj320C9210
http://cardgameheaven.com/single-player-games/clock.html
http://www.novelgames.com/en/clocksolitaire/ (this site lets you play online)
Explanation / Answer
PROGRAM:
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
class Attach
{
private Object Value;
private Attach List_nextAttach;
public Attach (Object newValue, Attach List_next)
{
Value = new Value;
List_nextAttach = List_next;
}
public Object value()
{
return Value;
}
public Attach List_next()
{
return List_nextAttach;
}
}
class AttachedList
{
private Attach Attach_first;
public AttachedList()
{
Attach_first = null;
}
public boolean Is_Empty()
{
return Attach_first == null;
}
public void Add_ob (Object newValue)
{
Attach_first = new Attach(newValue, Attach_first);
}
public Object front()
{
if (Attach_first == null)
return null;
return Attach_first.value();
}
public Object pop()
{
if (Attach_first == null)
return null;
Object result = Attach_first.value();
Attach_first = Attach_first.List_next();
return result;
}
public Iterator_of_List iterator()
{
return new Iterator_of_List(Attach_first);
}
}
class Iterator_of_List
{
private Attach nowAttach;
public Iterator_of_List (Attach Attach_first)
{
nowAttach = Attach_first;
}
public boolean End_OF_List()
{
return nowAttach == null;
}
public void List_next()
{
if (nowAttach != null)
nowAttach = nowAttach.List_next();
}
public Object now()
{
if (nowAttach == null)
return null;
return nowAttach.value();
}
}
class Card_OF_Game
{
final static int width = 50;
final static int height = 70;
final static int red = 0;
final static int black = 1;
final static int heart = 0;
final static int spade = 1;
final static int diamond = 2;
final static int club = 3;
final static int ace = 0;
final static int king = 12;
private static String names[] = {"A", "2", "3", "4", "5", "6",
"7", "8", "9", "10", "J", "Q", "K"};
private boolean Card_faceUP;
private int Card_rank;
private int Card_suit;
Card_OF_Game (int s, int r)
{
Card_suit = s;
Card_rank = r;
Card_faceUP = false;
}
public int Card_rank()
{
return Card_rank;
}
public int Card_suit()
{
return Card_suit;
}
public boolean faceUp()
{
return Card_faceUP;
}
public void Flip_card()
{
Card_faceUP = ! Card_faceUP;
}
public boolean isAce()
{
return Card_rank == ace;
}
public boolean isKing()
{
return Card_rank == king;
}
public int Card_color()
{
if (Card_suit() == heart || Card_suit() == diamond)
return red;
return black;
}
public void Draw_card (Graphics g, int x, int y) {
g.clearRect(x, y, width, height);
g.setColor(Color.black);
g.Draw_cardRect(x, y, width, height);
if (faceUp())
{
if (Card_color() == red)
g.setColor(Color.red);
else
g.setColor(Color.black);
g.Draw_cardString(names[Card_rank()], x+3, y+15);
if (Card_suit() == heart)
{
g.Draw_cardLine(x+25, y+30, x+35, y+20);
g.Draw_cardLine(x+35, y+20, x+45, y+30);
g.Draw_cardLine(x+45, y+30, x+25, y+60);
g.Draw_cardLine(x+25, y+60, x+5, y+30);
g.Draw_cardLine(x+5, y+30, x+15, y+20);
g.Draw_cardLine(x+15, y+20, x+25, y+30);
}
else if (Card_suit() == spade)
{
g.Draw_cardLine(x+25, y+20, x+40, y+50);
g.Draw_cardLine(x+40, y+50, x+10, y+50);
g.Draw_cardLine(x+10, y+50, x+25, y+20);
g.Draw_cardLine(x+23, y+45, x+20, y+60);
g.Draw_cardLine(x+20, y+60, x+30, y+60);
g.Draw_cardLine(x+30, y+60, x+27, y+45);
}
else if (Card_suit() == diamond)
{
g.Draw_cardLine(x+25, y+20, x+40, y+40);
g.Draw_cardLine(x+40, y+40, x+25, y+60);
g.Draw_cardLine(x+25, y+60, x+10, y+40);
g.Draw_cardLine(x+10, y+40, x+25, y+20);
}
else if (Card_suit() == club)
{
g.Draw_cardOval(x+20, y+25, 10, 10);
g.Draw_cardOval(x+25, y+35, 10, 10);
g.Draw_cardOval(x+15, y+35, 10, 10);
g.Draw_cardLine(x+23, y+45, x+20, y+55);
g.Draw_cardLine(x+20, y+55, x+30, y+55);
g.Draw_cardLine(x+30, y+55, x+27, y+45);
}
}
else
{
g.setColor(Color.yellow);
g.Draw_cardLine(x+15, y+5, x+15, y+65);
g.Draw_cardLine(x+35, y+5, x+35, y+65);
g.Draw_cardLine(x+5, y+20, x+45, y+20);
g.Draw_cardLine(x+5, y+35, x+45, y+35);
g.Draw_cardLine(x+5, y+50, x+45, y+50);
}
}
}
class Card_game
{
protected int x;
protected int y;
protected AttachedList Card_OF_Game_OF_GameList;
Card_game(int xl, int yl)
{
x = xl;
y = yl;
Card_OF_Game_OF_GameList = new AttachedList();
}
public final boolean Is_Empty()
{
return Card_OF_Game_OF_GameList.Is_Empty();
}
public final Card_OF_Game top()
{
return (Card_OF_Game)Card_OF_Game_OF_GameList.front();
}
public final Card_OF_Game pop()
{
return (Card_OF_Game)Card_OF_Game_OF_GameList.pop();
}
public boolean Card_Include (int tx, int ty)
{
return x <= tx && tx <= x + Card_OF_Game.width &&
y <= ty && ty <= y + Card_OF_Game.height;
}
public void Card_select (int tx, int ty)
{
}
public void Add_obCard_OF_Game (Card_OF_Game aCard_OF_Game)
{
Card_OF_Game_OF_GameList.Add_ob(aCard_OF_Game);
}
public void Card_display (Graphics g)
{
g.setColor(Color.black);
if (Card_OF_Game_OF_GameList.Is_Empty())
g.Draw_cardRect(x, y, Card_OF_Game.width, Card_OF_Game.height);
else
top().Draw_card(g, x, y);
}
public boolean Card_can_TAKE (Card_OF_Game aCard_OF_Game)
{
return false;
}
public int getNoCard_OF_Games()
{
int count = 0;
Iterator_of_List iterator = Card_OF_Game_OF_GameList.iterator();
while (!iterator.End_OF_List())
{
count++;
iterator.List_next();
}
return count;
}
}
class Card_deck extends Card_game
{
Card_deck (int x, int y)
{
super(x, y);
Card_gamepileOne = new Card_OF_GamePile(0, 0);
Card_gamepileTwo = new Card_OF_GamePile(0, 0);
int count = 0;
for (int i = 0; i < 4; i++)
for (int j = 0; j <= 12; j++)
{
pileOne.Add_obCard_OF_Game(new Card_OF_Game(i, j));
count++;
}
for (; count > 0; count--)
{
int limit = ((int)(Math.random() * 1000)) % count;
for (int i = 0; i < limit; i++)
pileTwo.Add_obCard_OF_Game(pileOne.pop());
Add_obCard_OF_Game(pileOne.pop());
while (!pileTwo.Is_Empty())
pileOne.Add_obCard_OF_Game(pileTwo.pop());
}
}
public void Card_select(int tx, int ty)
{
if (Is_Empty())
{
while (!Solitaire.disCard_OF_Game_OF_GamePile.Is_Empty())
{
Add_obCard_OF_Game(Solitaire.disCard_OF_Game_OF_GamePile.pop());
top().Flip_card();
}
}
else
Solitaire.disCard_OF_Game_OF_GamePile.Add_obCard_OF_Game(pop());
}
}
class DisCard_OF_Game_OF_GamePile extends Card_game
{
DisCard_OF_Game_OF_GamePile (int x, int y)
{
super (x, y);
}
public void Add_obCard_OF_Game (Card_OF_Game aCard_OF_Game)
{
if (!aCard_OF_Game.faceUp())
aCard_OF_Game.Flip_card();
super.Add_obCard_OF_Game(aCard_OF_Game);
}
public void Card_select (int tx, int ty)
{
if (Is_Empty())
return;
Card_OF_Game topCard_OF_Game = top();
for (int i = 0; i < Solitaire.no_Card_suit_piles; i++)
if (Solitaire.Card_suitPile[i].Card_can_TAKE(topCard_OF_Game))
{
Solitaire.Card_suitPile[i].Add_obCard_OF_Game(pop());
return;
}
for (int i = 0; i < Solitaire.no_table_piles; i++)
if (Solitaire.tableau[i].Card_can_TAKE(topCard_OF_Game))
{
Solitaire.tableau[i].Add_obCard_OF_Game(pop());
return;
}
}
}
class SuitPile extends Card_game
{
SuitPile (int x, int y)
{
super(x, y);
}
public boolean Card_can_TAKE (Card_OF_Game aCard_OF_Game)
{
if (Is_Empty())
return aCard_OF_Game.isAce();
Card_OF_Game topCard_OF_Game = top();
return (aCard_OF_Game.Card_suit() == topCard_OF_Game.Card_suit()) &&
(aCard_OF_Game.Card_rank() == 1 + topCard_OF_Game.Card_rank());
}
public void Card_select (int tx, int ty)
{
if (Is_Empty())
return;
Card_OF_Game topCard_OF_Game = top();
for (int i = 0; i < Solitaire.no_table_piles; i++)
if (Solitaire.tableau[i].Card_can_TAKE(topCard_OF_Game))
{
Solitaire.tableau[i].Add_obCard_OF_Game(pop());
return;
}
}
}
class TablePile extends Card_game
{
final static int ydist = 25;
TablePile (int x, int y, int c)
{
super(x, y);
for (int i = 0; i < c; i++)
Add_obCard_OF_Game(Solitaire.deckPile.pop());
top().Flip_card();
}
public boolean Card_can_TAKE (Card_OF_Game aCard_OF_Game)
{
if (Is_Empty())
return aCard_OF_Game.isKing();
Card_OF_Game topCard_OF_Game = top();
if (!topCard_OF_Game.faceUp())
return false;
return (aCard_OF_Game.Card_color() != topCard_OF_Game.Card_color()) &&
(aCard_OF_Game.Card_rank() == topCard_OF_Game.Card_rank() - 1);
}
public boolean Card_Include (int tx, int ty)
{
if (Is_Empty())
return false;
return x <= tx && tx <= x + Card_OF_Game.width &&
y <= ty;
}
public void Card_select (int tx, int ty)
{
if (Is_Empty())
return;
Card_OF_Game topCard_OF_Game = top();
if (!topCard_OF_Game.faceUp())
{
topCard_OF_Game.Flip_card();
return;
}
for (int i = 0; i < Solitaire.no_Card_suit_piles; i++)
if (Solitaire.Card_suitPile[i].Card_can_TAKE(topCard_OF_Game))
{
Solitaire.Card_suitPile[i].Add_obCard_OF_Game(pop());
return;
}
Card_gamebuild = new Card_OF_GamePile(0, 0);
while (!Is_Empty())
{
if (!top().faceUp())
break;
build.Add_obCard_OF_Game(pop());
}
if (build.top().isKing() && Is_Empty())
{
while (!build.Is_Empty())
Add_obCard_OF_Game(build.pop());
return;
}
if (build.top() == topCard_OF_Game)
{
Add_obCard_OF_Game(build.pop());
for (int i = 0; i < Solitaire.no_table_piles; i++)
if (Solitaire.tableau[i].Card_can_TAKE(topCard_OF_Game))
{
Solitaire.tableau[i].Add_obCard_OF_Game(pop());
return;
}
}
else
{
topCard_OF_Game = build.top();
for (int i = 0; i < Solitaire.no_table_piles; i++)
if (Solitaire.tableau[i].Card_can_TAKE(topCard_OF_Game))
{
while (!build.Is_Empty())
Solitaire.tableau[i].Add_obCard_OF_Game(build.pop());
return;
}
while (!build.Is_Empty())
Add_obCard_OF_Game(build.pop());
}
}
private void stackDisplay(Graphics g)
{
int localy = y;
AttachedList reverseCard_OF_GameList = new AttachedList();
Iterator_of_List iterator = Card_OF_Game_OF_GameList.iterator();
while (!iterator.End_OF_List())
{
reverseCard_OF_GameList.Add_ob(iterator.now());
iterator.List_next();
}
iterator = reverseCard_OF_GameList.iterator();
while (!iterator.End_OF_List())
{
((Card_OF_Game)iterator.now()).Draw_card(g, x, localy);
localy += ydist;
iterator.List_next();
}
}
public void Card_display (Graphics g)
{
stackDisplay(g);
}
}
public class Solitaire extends Applet
{
final static int no_Card_OF_Game_OF_Game_piles = 13;
final static int no_Card_suit_piles = 4;
final static int no_table_piles = 7;
final static int topMargin = 40;
final static int leftMargin = 5;
final static int distTable = 5;
final static int distSuit = 10;
static Card_deck deckPile;
static DisCard_OF_Game_OF_GamePile disCard_OF_Game_OF_GamePile;
static TablePile tableau[];
static SuitPile Card_suitPile[];
static Card_gameallPiles[];
protected void initialize()
{
allPiles = new Card_OF_GamePile[no_Card_OF_Game_OF_Game_piles];
Card_suitPile = new SuitPile[no_Card_suit_piles];
tableau = new TablePile[no_table_piles];
int xDeck = leftMargin + (no_table_piles - 1) * (Card_OF_Game.width + distTable);
allPiles[0] = deckPile = new Card_deck(xDeck, topMargin);
allPiles[1] = disCard_OF_Game_OF_GamePile = new DisCard_OF_Game_OF_GamePile(xDeck - Card_OF_Game.width - distSuit,
topMargin);
for (int i = 0; i < no_Card_suit_piles; i++)
allPiles[2+i] = Card_suitPile[i] =
new SuitPile(leftMargin + (Card_OF_Game.width + distSuit) * i, topMargin);
for (int i = 0; i < no_table_piles; i++)
allPiles[6+i] = tableau[i] =
new TablePile(leftMargin + (Card_OF_Game.width + distTable) * i,
Card_OF_Game.height + distTable + topMargin, i+1);
showStatus("Welcome to Solitaire!");
}
protected boolean gameEnded()
{
if (!deckPile.Is_Empty())
return false;
if (!disCard_OF_Game_OF_GamePile.Is_Empty())
return false;
for (int i = 0; i < no_table_piles; i++)
if (!tableau[i].Is_Empty())
return false;
showStatus("Congratulations! You have won this game.");
return true;
}
public void init()
{
Button b = new Button("New game");
b.Add_obActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
initialize();
repaint();
}
});
Add_ob(b);
Add_obMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e)
{
if (gameEnded())
return;
showStatus("Neat click!");
int x = e.getX();
int y = e.getY();
for (int i = 0; i < no_Card_OF_Game_OF_Game_piles; i++)
if (allPiles[i].Card_Include(x, y))
{
allPiles[i].Card_select(x, y);
repaint();
}
}
});
initialize();
}
public void paint(Graphics g)
{
for (int i = 0; i < no_Card_OF_Game_OF_Game_piles; i++)
allPiles[i].Card_display(g);
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.