You are on page 1of 57

Solitaire Game

(Android)

By

Maaz Khan
(14-Arid-0668)

Bachelor of Science in Computer Science

BS(CS)

Barani Institute of Information Technology


PMAS Arid Agriculture University Rawalpindi

August 2018

i
Solitaire Game

A report submitted in partial fulfillment of the


requirement for the degree of
Bachelor of Science in Computer Science

Submitted By
Maaz Khan
(14-Arid-0668)

Supervised By
Mr.Zeeshan

Barani Institute of Information Technology


PMAS Arid Agriculture University Rawalpindi

August 2018
ii
CERTIFICATE

It is certified that the contents and form of thesis entitled Solitaire Game submitted by
Maaz Khan have been found satisfactory for the requirement of the degree.

SUPERVISORY COMMITTEE

PROJECTSUPERVISOR:

Mr.Zeeshan

REPORTCOORDINATOR:

Ms. Kainat

WRITUP COMMITEEHEAD:

Ms. Noor UlAin

iii
ACKNOWLEDGMENT

All praise to Allah which is unique, the most Beneficent and most merciful. I
really thankful to Allah who gives me the knowledge and Wisdom. Furthermore, a
very special thanks to my parents, especially my mother who always encourage me
and pray for me. I am most grateful to my project supervisor Mr. Zeeshan for the
guidance, inspiration and constructive suggestion that helped me in the preparation
of this project. I greatly acknowledged him for kind help , best co-operation and
valuable suggestion. I am also thankful to my fellows, who helped me.

Maaz Khan

iv
ABSTRACT

The Android-Base application "Solitaire Game" is made so that it will


entertain user to some extent. It is a game of cards which can be played by a single
player.. This game is accessible to people of all ages.

Most of the People Play Games to relax their mind and this game is the best
source of it .Every kind of user can play this game, this is not made for any specific
kind of user. This Game can help both adults and children to improve their motor
skills.

v
TABLE OF CONTENTS
Contents Page No:

ACKNOWLEDGEMENT .................................................................................................. iv
ABSTRACT ..........................................................................................................................v
TABLE OF CONTENTS .................................................................................................... vi
LIST OF FIGURES .......................................................................................................... viii

CHAPTER 1- INTRODUCTION
1.1 Introductory Background ............................................................................................01
1.2 Purpose and Advantages .............................................................................................01
1.3 Objectives and Scope ..................................................................................................01

CHAPTER 2- BACKGROUND

2.1 Related Projects ......................................................................................................... 02


2.1.1 Landscape………..…………………………………………………….. .......... 03
2.1.2 Portrait…………………………………………………………………………03
2.2 Related Software in Market ....................................................................................... 05
2.2.1 Free Solitaire 24/7………..……………………………………………………05
2.2.2 Simple Classic Solitaire…………………………………………………….…06

CHAPTER 3- DESIGN

3.1 Requirement Elicitation ............................................................................................... 07


3.2 Requirement Specification ........................................................................................... 07
3.2.1 Functional Requirements .................................................................................... 07
3.2.2 Non-Functional Requirements ............................................................................ 07
3.3 Requirement Modeling ................................................................................................ 07
3.3.1 Data Flow Diagram(DFD) .................................................................................. 08
3.3.2 Conceptual Diagram ........................................................................................... 10

CHAPTER 4- IMPLEMENTATION
4.1 Tools and Technology..................................................................................................11
4.2 Pseudo Code.................................................................................................................12
4.3 Screen Shots .................................................................................................................20

vi
CHAPTER 5- FUTURE DIRECTION
5.1 Future Direction ...........................................................................................................30
5.2 Limitation.....................................................................................................................30
5.3 Conclusion ...................................................................................................................30

REFERENCES .................................................................................................................31

ANNEXURE .....................................................................................................................32

viii
LIST ListOF
of Figures FIGURES

Figures No Page No.

Figure 2.1: Representation of Landscape Style ............................................................. 03


Figure 2.2: Representation of Portrait style. ................................................................. 04
Figure 2.3: Representation of Levels of Game ............................................................. 05
Figure 2.4: Data Flow Diagram ..................................................................................... 09
Figure 2.5: Conceptual Diagram .................................................................................... 10
Figure 2.6: Representation of Main Screen ................................................................... 13
Figure 2.7: Output of Main Screen ................................................................................ 14
Figure 2.8: Representation of Movement of Cards ........................................................ 18
Figure 2.9: Output of Movement of Cards..................................................................... 19
Figure 3.1: Splash Screen .............................................................................................. 20
Figure 3.2: Main Screen. ................................................................................................ 21
Figure 3.3: Movement of Cards. .................................................................................... 22
Figure 3.4: General Statistics ......................................................................................... 23
Figure 3.5: Highscore Statistics ..................................................................................... 24
Figure 3.6: Menu Screen ................................................................................................ 25
Figure 3.7: Save Game Screen ....................................................................................... 26
Figure 3.8: Load Game Screen ...................................................................................... 27
Figure 3.9: Support dialog box ...................................................................................... 28
Figure 3.10: Settings Screen .......................................................................................... 29
Figure 3.11: Final Output of Main Screen ..................................................................... 37
Figure 3.12: Final Output of Movement of Cards ......................................................... 49

ix
CHAPTER 1

INTRODUCTION

1.1 Introductory Background

The Android-Base application "Solitaire Game" is a game of cards which can be


played by a single player. Most of the People Play Games to relax their mind and this game is
the best source of it . Every kind of user can play this game, this is not made for any specific
kind of user.

1.2 Purpose and Advantages


The main Purpose of this gaming application is to develop a game that will entertain user to
some extent. This game can help both adults and children to improve their motor skills. This Card
Game is accessible to people of all ages.

1.3 Scope and Objectives


The main objective of this game is to provide the user friendly environment and to give all the
possible facilities to the user. This game is made considering many objectives. User can play,
achieve high scores, Undo its moves, saves and loads games. Guides user with how to play option.
To Provides user the possible hints. Allows user to change the game setting according to its own
choice.

1
CHAPTER 2
BACKGROUND

This chapter contains background about this project and related projects that was developed in
the past by BIIT student. This chapter also contains discussion about design of the project and also
related software available in the market.

2.1 Related Project

You can drag and drop cards and partial stacks if you want to. You can drag and drop cards and
partial stacks if you want to. Once you get all the cards ready to go in the stacks, the Auto Play
button appears to quickly move all your cards onto the Aces and to victory. Draw 3 cards at a time,
or change to draw 1 at a time if you want an easier game. and intuitive controls - Just tap on a card
or stack and watch as it magically moves where.

2.1.1 Simply Solitaire

No. 1 Solitaire game in over 70 stores worldwide. Get immersed in this uniquely styled version
of Solitaire. With its natural card layout, feature rich content and polished visual style Simply
Solitaire HD is the only Solitaire game you need on your iPhone, iPod Touch and i-Pad. Simply
Solitaire lets you customize your game with unique card backs and backgrounds, adjustable deck
position and rotatable screen orientation giving you the freedom to play Solitaire how you want.

• Auto Complete and Auto Save

• Unique Visual Style.

• Natural Card Layout.

• Shiny Special Effects

2
2.1.2 Landscape

Landscaping refers to any activity that modifies the visible features of an area of land including:
living elements. In this application user play game in different styles Landscape style is one of them,
in which cards will display as like other styles.

Figure 2.1: Representation of Landscape Styles

2.1.3 Portrait

A portrait is a painting, photograph, sculpture, or other artistic or other artistic representation of


a person, Simply Solitaire HD is the only Solitaire game you need on your iPhone, iPod Touch and i-
Pad. Simply Solitaire lets in which the face and its expression is predominant. The display
orientation of the game maybe locked. In the game, tap the settings button in toolbar. In the settings
display scroll down to the lock orientation. Your device maybe locked in the portrait direction.
Landscape style is one of them in which cards will display as like others.

3
Figure 2.2: Representation of Portrait Styles

Game Level

This game has 30 levels. Level 1 to level 10 is one suit spider solitaire which means as
the king of all solitaire games. One must be skilled at manipulating the cards they've been dealt
with. Level 11 to level 20 is two suit spider solitaire. Level 21 to Level 30 is four suit spider
solitaire which means is a card game that uses two decks of cards. The level design is from easy
to difficulty.

4
Figure 2.3: Representation of Levels of Game

2.1 Related Software in Market


There are many great apps for solving the problems explained above but every app solves one
problem and for other people need another app witch don’t do the things which pervious app does.
So there isn’t a system or app which does all the work. This leads to the requirement of a system
which is capable of doing all these things. Some of the names of application are under following:

 Solitaire Deluxe

 Full house Casino

 Pyramid solitaire saga

 Fairway Solitaire Blast

2.2.1 Free Solitaire 24/7


24/7 Games is the best resource for free games online! Play card games, casino games, mahjong
games, freecell, hearts, spades, and more. 24/7 Solitaire is 100% FREE, AD FREE, and comes with 9
great solitaire card games: Klondike Solitaire, Spider Solitaire, FreeCell Solitaire, and more. Be the
best all by yourself with 24/7 Solitaire's beautiful, easy-to-read cards and an easy-to-use interface.
There's no greater value--and no better collection of card games.

5
• Classic Solitaire (Klondike)
• Free cell
• Spider Solitaire
• 9 GREAT games in all
• Playable in landscape AND portrait mode
• Undo Button

2.2.2 Simple Classic Solitaire

Classic Solitaire (known only as simply “Solitaire” by some, and “Klondike Solitaire”. Classic Solitaire
is a game of sorting cards. You move cards between columns in an attempt to put them in order into 4
piles of cards separated by suit. If you like solitaire games, you're going to love this app. The classic
solitaire game plus the ability to control card movements naturally by just swiping or tapping the cards
on your iPhone/iPod touch/iPad. Think you have the best solitaire score around? You can check the
Game Center leaderboard to see how your solitaire skills stack up against players all around the world.

o Unlimited hints
o Unlimited undo
o Klondike
o Custom backgrounds
o Autocomplete

6
CHAPTER 3

DESIGN

The most important part of the application is design phase, in this chapter we'll discuss about
what are the requirements, functional requirements and non functional requirements and how to
gather requirements, Conceptual Diagram, Data Flow Diagram and Entity Relationship Diagram.

3.1 Requirements Elicitation


The most important part of developing any system is to gather requirements for the system. The
main source of gathering requirements is the client who is demanded that system and the users of the
system. If proper requirements are not gathered then there will be conflict between client and
developer of the system. So all the requirements required for Solitaire Game are gathered from
Director of institution and project supervisor.

3.2 Requirement Specification


A System Requirements Specification (SRS), (also known as a Software Requirements
Specification) is a document or set of documentation that describes the features and behavior of a
system or software application. Usually a combination of problems and opportunities are needed to
provide motivation for a new system.

3.2.1 Functional Requirements


Users can perform the following tasks:

 User can interact and play a game.


 User can Load and Save its game.
 User can achieve and view its scores.
 User can change the setting according to its needs.

3.2.2 Non-Functional Requirements


In systems engineering and requirements engineering, non-functional requirement (NFR) is
a requirement that specifies criteria that can be used to judge the operation of a system, rather than
specific behaviors. Non-functional requirements are often called "quality attributes" of a system.

7
 Performance Requirements
This system is full of speed and accuracy, there is no unwanted delays in the Game and user
does not have to wait for any response.

 Availability
User can play this game anytime because it does not need any internet connection.

 User Friendly

The structure of this game is completely all according to the need of users. It provides the
best end to end user and system interaction. User can change the game according to its own setting
which allows user to set all the structure according to itself i.e like changing the card colors,
changing the background, hiding the hint option for difficulty etc.

3.3 Data Flow Diagram(DFD)

A data flow diagram is a graphical representation of the "flow" of data through an information
system, modeling its process aspects. A DFD is often used as a preliminary step to create an
overview of the system without going into great detail, which can later be elaborated. DFDs can also
be used for the visualization of data processing.

Level 0

CLICK Solitaire
USER Game
RESPONSE

Figure 3.1: Data flow diagram level 0

This is the first level of application in which user will request application and application will
respond to the user request.

Approved by: Mr. Zeeshan

8
Level 1

Figure 2.4: Data flow diagram level 1

Approved by: Mr. Zeeshan

In this level the overall working of the application and all actions of users are showed clearly.
Users can Play, undo, see Statistics, do settings and load and save.

9
3.3.1 Conceptual Diagram
A conceptual diagram is a visual representation of a system, made of the composition of
concepts which are used to help people know, understand, or simulate a subject the model
represents. It is also a set of concepts. The below mentioned diagram is describing how Solitaire
Game works:

Conceptual Diagram

Figure 2.5: Conceptual Diagram

Approved by: Mr. Zeeshan

In (Figure 3.10) the overall working of application is showed in simple pictorial form to help general
people and client to understand how the application works. As showed in figure the application
works by getting user request, the user will request to the application for whatever actions he/she
want to perform the application further requests to the internal storage and only goes to the database
if the user have to load and save the game.

10
CHAPTER 4
IMPLEMENTATION

To develop any application you have to use some tools and technologies, we’ll discuss
different tools and technologies used to develop the BIIT Digital Library & Lesson Plans.

4.1 Tools &Technology

Operating System Android

Environment Android Studio

Language Java

Database Used SQL LITE

 Android Studio
Android is an operating system developed by Google, based on a modified version of the Linux kernel
designed for touchscreen mobile devices such as smartphones and tablets. Android Studio is the
official integrated development environment for Google's Android operating system, built on Jet
Brains' Intelli IDEA software and designed specifically for Android development.

 SQL Lite

SQLite is a software library that implements a self-contained, serverless, zero-configuration,


transactional SQL database engine. SQLite is the most widely deployed SQL database engine in the
world. The source code for SQLite is in the public domain. This tutorial will give you a quick start with
SQLite and make you comfortable with SQLite programming.

11
4.2 Pseudo Code

Pseudo code that determines read metadata


Initialise n to fifty

Initialise sum to zero

Initialise f1 and f2 to zero

repeat n times

add f1 and f2, store this value in sum

assign f1’s current value to f2

assign sum’s current value to f1

int arr;

arr = new int[10];

for(int i = 0; i < arr.size(); i++)

{ arr[i] = random ();

print arr[i];

12
Code of Main Screen

Figure 2.6: Representation of Main Screen

13
Output

Figure 2.7: Output of Main Screen

 For more details refer to ANNEXURE A.

Movement Of Cards

Pseudo code that determines read metadata

Pass In: nothing

Direct the operating system to clear the monitor

Pass Out: nothing

Pass In: integer representing tenths of a second

14
Using the operating system delay the program

Pass Out: nothing

Pass In: nothing

Doing some lines of code

Call: clear monitor

Doing some lines of code

Pass Out: value zero to the operating system

Pass In: integer representing tenths of a second

Using the operating system delay the program

Pass Out: nothing

Pass In: nothing

Doing some lines of code

Call: clear monitor

Doing some lines of code

Pass Out: value zero to the operating system

Set total to zero

Get list of numbers

Loop through each number

Add each number to total

End loop

If number more than zero

Print “editing video”

Else Print “searching video”

End if

iLow = Lbound(Data Array)

iHigh= Ubound(Data Array

Do while iLow<=iHigh
15
If Target = DataArray(Middle) then

bFound = true

exit do

else target < DataArray (iMiddle) then

I High = (iMiddle - 1)

else

iLow = (iMiddle + 1)

end if

add one to failures

add one to student counter

print the number of passes

print the number of failures

if eight or more students passed

print "raise tuition"

Code of Movement of Cards

16
17
Figure 2.8: Representation of Movement of cards

 For more details refer to ANNEXURE B.

18
Output

Figure 2.9: Output of Movement of Cards

19
4.2 Screen Shots

(Splash Screen)

Figure 3.1: Splash Screen

In (Figure 4.9) the Splash screen of application is shown, it is used in this application to make it
more interactive and so that the user can feel more excited after seeing the interactive splash screen
at the start.

20
(Main Screen)

Figure 3.2: Main Screen

In (Figure 4.10) the Main screen of the game is showed, different cards and structure of the game is
being presented at the main screen. User can see and evaluate the game by this and the main screen is
user friendly and attractive.

21
(Movement of Cards)

Figure 3.3: Movement of Cards

In (Figure 4.12) the movement of cards is being shown after making some possible moves, you can
see that there is an undo option and support option. User can undo its move up to its first move and
can see the hints for the possible moves in support option.

22
(General Statistics)

Figure 3.4: General Statistics

In (Figure 4.13) the Statistic of user is shown in which the General tab is being displayed. User can
see its progress in the game so far and can see all the stats of the present match.

23
(High Scores Statistics)

Figure 3.5: High Scores Statistics

In (Figure 4.13) the Statistic of user is shown in which the High scores tab is being displayed. User
can see the high Scores of all the games played and the user can try to achieve the new high score.

24
(Menu Screen)

Figure 3.6: Menu Screen

In (Figure 4.17) all the possible options of the menu are given. User can start a new game, save its
game, loads it previous game, close the game, ask for a re deal. Menus are made according to the
user requirements.

25
(Save Game Screen)

Figure 3.7: Save game

In (Figure 4.18) the save game dialog box can be seen. User can save its game according to its own
title and can retrieve the same game later on in a load game option.

26
(Loaded Games )

Figure 3.8: Load games Screen

In the (Figure 4.20) the loads of the user can be seen, user have loaded the games with these names
and the user can now retrieve its game by selecting any of its previously saved games.

27
(Support Option)

Figure 3.9: Support Dialog Box

In (Figure 4.20) The Support dialog box of the game has been shown. User can see the possible hints
on the possible moves and if the user is new to the game then there is a Game Rule option which can
be helpful for the user to Learn more about the game.

28
(Settings Screen)

Figure 3.10: Settings Screen

Figure 4.23 shows many options in the setting menu.


User can set its Main screen according to the different options in the setting menu

29
CHAPTER 5

CONCLUSION

5.1 Future Direction


Every application has its own merits and demerits. The project has covered almost all the
requirements. Further requirements and improvements can easily be done. Further enhancements can
be made to the application, so that the application remain attractive and works in useful manner then
the present one.

5.2 Limitations
 Application is dependent to Android smart phones/devices only.

5.3 Conclusion
The Solitaire Game is made for general users and it very appreciated among every kind of user, it can
be access from everywhere and from every android device. The main Purpose of this gaming
application is to develop a game that will entertain user to some extent. This game is made
considering many objectives. User can play, achieve high scores, Undo its moves, saves and loads
games. Guides user with how to play option. To Provides user the possible hints. Allows user to
change the game setting according to its own choice. These are all the features of the Solitaire Game.
It is concluded that the application works well and meets with all the requirements of application.
The Game is tested well and errors are debugged. The application is simultaneously accessed from
more than one system and simultaneous Accessed from more than one place is tested.

The application works fine and further enhancements can be made to the application, so that the
application remains attractive and useful to existing application.

30
REFERENCES

[1] King Klan , "Assigning images to the Cards", (27th Sept, 2017) [ Online link:
https://stackoverflow.com/questions/46444468/how-to-assign-unique-images-to-each-card-
in-my-deck-of-cards-in-android-studio ] (accessed 11th April, 2018).

[2] Android Developers, “ Create a Card Based Layout “ , ( November 8, 2017) [ Online Link
:https://developer.android.com/guide/topics/ui/layout/cardview] (accessed 14th April, 2018).

[3] Stack Exchange ,“ Creating Cards” , ( December 7, 2017) [ Online Link


:https://codereview.stackexchange.com/questions/70599/simple-deck-of-cards] (accessed 14th
May, 2018).

[4] User 3665376, "Working on the Cars Design", (20th Sep, 2014), [Online link:
https://stackoverflow.com/questions/25810586/android-layout-how-to-implement-a-ui-
similar-to-deck-of-cards],(accessed 14th May, 2018).

[5] Thomas, "Shuffling of Cards", (April 1st, 2012),[ online


link:https://gamedev.stackexchange.com/questions/26551/how-do-i-shuffle-cards-for-a-card-
game] (accessed 18th May,2018).

` [6] TihomarRadeff, "Working on Deck Of cards ", (Jan 25th, 2017), [online link:
https://www.youtube.com/watch?v=1qHVvu4BUtk], (accessed 24h May,2018).

[7] Google, "downloaded images from Google", (accessed 29 Feb, 2018).

31
ANNEXEURE

ANNEXURE A

Main Screen
import android.graphics.PointF;

import java.util.ArrayList;
import java.util.List;

import static de.tobiasbielefeld.solitaire.SharedData.*;

public class Card {

public static intwidth, height;


public static Bitmap background;
private static Bitmap[] drawables= new Bitmap[52];
public CustomImageViewview;
private intcolor;
private intvalue;
private Stack stack;
private intid;
private booleanisUp;
private PointFoldLocation= new PointF();
public Card(intid) {
this.id = id;
color = currentGame.cardDrawablesOrder[(id % 52) / 13];
value = (id % 13) + 1;
}

public static void updateCardDrawableChoice() {


booleanfourColors = prefs.getSavedFourColorMode();

for (inti = 0; i <13; i++) {


drawables[i] = bitmaps.getCardFront(i, fourColors ? 1 : 0);
drawables[13 + i] = bitmaps.getCardFront(i, 2);
drawables[26 + i] = bitmaps.getCardFront(i, 3);
drawables[39 + i] = bitmaps.getCardFront(i, fourColors ? 5 : 4);
}

if (cards == null) {
return;
}

for (Card card : cards) {


32
if (card.isUp()) {
card.setCardFront();
}
}
}

public static void updateCardBackgroundChoice() {


intpositionX = prefs.getSavedCardBackground();
intpositionY = prefs.getSavedCardBackgroundColor();
background = bitmaps.getCardBack(positionX, positionY);

if (cards == null) {
return;
}

for (Card card : cards) {


if (!card.isUp()) {
card.setCardBack();
}
}
}

public static void save() {


List<Integer> list = new ArrayList<>(cards.length);

for (Card card : cards)


list.add(card.isUp? 1 : 0);

prefs.saveCards(list);
}

public static void load() {


List<Integer> list = prefs.getSavedCards();

for (inti = 0; i <cards.length; i++) {


if (list.get(i) == 1)
cards[i].flipUp();
else
cards[i].flipDown();
}
}

public void setCardFront() {


view.setImageBitmap(drawables[(color - 1) * 13 + value - 1]);
}

public void setCardBack() {

33
view.setImageBitmap(background);
}

public void setColor() {


color = currentGame.cardDrawablesOrder[(id % 52) / 13];
}

public void setLocation(float pX, float pY) {


if (view.getX() != pX || view.getY() != pY)
animate.moveCard(this, pX, pY);
}

public void setLocationWithoutMovement(float pX, float pY) {


view.bringToFront();
view.setX(pX);
view.setY(pY);
}

public void saveOldLocation() {


oldLocation.x= view.getX();
oldLocation.y= view.getY();
}

public void returnToOldLocation() {


view.setX(oldLocation.x);
view.setY(oldLocation.y);
}

public void flipUp() {


isUp= true;
setCardFront();
}

public void flipDown() {


isUp= false;
setCardBack();
}

public void flip() {


if (isUp())
flipDown();
else
flipUp();
}

34
public void flipWithAnim() {
if (isUp()) {
isUp= false;

scores.undo(this, getStack());
animate.flipCard(this, false);
} else {
isUp= true;

scores.move(this, getStack());
recordList.addFlip(this);
animate.flipCard(this, true);
}
}
public booleantest(Stack destination) {
if (prefs.isDeveloperOptionMoveCardsEverywhereEnabled()){
return true;
}

return !((!isUp() || (destination.getSize() != 0 &&


!destination.getTopCard().isUp())) && !autoComplete.isRunning())
&&currentGame.cardTest(destination, this);
}
public intgetColor() {
return color;
}
public booleanisTopCard() {
return getStack().getTopCard() == this;
}

public booleanisFirstCard() {
return getStack().getCard(0) == this;
}
public intgetIndexOnStack() {
return getStack().getIndexOfCard(this);
}
public booleanisUp() {
return isUp;
}
public intgetId() {
return id;
}
public intgetValue() {
return value;
}
public Stack getStack() {
return stack;
}
public void setStack(Stack stack) {
this.stack= stack;
}
35
public float getX() {
return view.getX();
}

public void setX(float X) {


view.setX(X);
}
public float getY() {
return view.getY();
}
public void setY(float Y) {
view.setY(Y);
}

public intgetStackId() {
return stack.getId();
}

public void removeFromCurrentStack(){


if (stack!=null) {
stack.removeCard(this);
stack = null;
}
}public Card getCardOnTop(){
if (getIndexOnStack() <stack.getSize() -1){
return stack.getCard(getIndexOnStack()+1);
} else {
return this;
}
}

public Card getCardBelow(){


return getIndexOnStack() == 0 ? this :
stack.getCard(getIndexOnStack()-1);
}
}

36
Output

Figure 3.11 Final Output Main Screen

37
ANNEXURE B

Movement Of cards
package de.tobiasbielefeld.solitaire.games;

import android.content.Context;
import android.widget.RelativeLayout;

import java.util.ArrayList;

import de.tobiasbielefeld.solitaire.classes.Card;
import de.tobiasbielefeld.solitaire.classes.CardAndStack;
import de.tobiasbielefeld.solitaire.classes.Stack;

import static de.tobiasbielefeld.solitaire.SharedData.*;


import static de.tobiasbielefeld.solitaire.games.Game.testMode.*;
import static de.tobiasbielefeld.solitaire.games.Game.testMode2.*;
import static de.tobiasbielefeld.solitaire.games.Game.testMode3.*;
import static
de.tobiasbielefeld.solitaire.helper.Preferences.DEFAULT_KLONDIKE_NUMB
ER_OF_RECYCLES;
import static
de.tobiasbielefeld.solitaire.helper.Preferences.PREF_KEY_KLONDIKE_NUM
BER_OF_RECYCLES;

public class Klondike extends Game {

protected intwhichGame;

public Klondike() {
setNumberOfDecks(1);
setNumberOfStacks(15);

setTableauStackIDs(0,1,2,3,4,5,6);
setFoundationStackIDs(7,8,9,10);
setDiscardStackIDs(11,12,13);
setMainStackIDs(14);

whichGame= 1;

setMixingCardsTestMode(testMode.ALTERNATING_COLOR);
setNumberOfRecycles(PREF_KEY_KLONDIKE_NUMBER_OF_RECYCLES,
DEFAULT_KLONDIKE_NUMBER_OF_RECYCLES);

toggleRecycles(prefs.getSavedKlondikeLimitedRecycles());
}

38
public void setStacks(RelativeLayoutlayoutGame, booleanisLandscape,
Context context) {

setUpCardWidth(layoutGame, isLandscape, 8, 10);

intspacing = setUpHorizontalSpacing(layoutGame, 7, 8);


intstartPos = layoutGame.getWidth() / 2 - Card.width/ 2 - 3 *
Card.width- 3 * spacing;

for (inti = 0; i <4; i++) {


stacks[7 + i].setX(startPos + spacing * i + Card.width* i);
stacks[7 + i].view.setY((isLandscape ? Card.width/ 4 : Card.width/ 2)
+ 1);
}

startPos = layoutGame.getWidth() - 2 * spacing - 3 * Card.width;


for (inti = 0; i <3; i++) {
stacks[11 + i].setX(startPos + Card.width/ 2 * i);
stacks[11 + i].view.setY((isLandscape ? Card.width/ 4 : Card.width/
2) + 1);
}
stacks[14].setX(stacks[13].getX() + Card.width+ spacing);
stacks[14].setY(stacks[13].getY());

startPos = layoutGame.getWidth() / 2 - Card.width/ 2 - 3 *


Card.width- 3 * spacing;
for (inti = 0; i <7; i++) {
stacks[i].setX(startPos + spacing * i + Card.width* i);
stacks[i].setY(stacks[7].getY() + Card.height+
(isLandscape ? Card.width/ 4 : Card.width/ 2));
}

for (Stack stack : stacks) {


if (stack.getId() >6 &&stack.getId() <= 10) {
stack.view.setImageBitmap(Stack.background1);
} else if (stack.getId() >10 &&stack.getId() <= 13) {
stack.view.setImageBitmap(Stack.backgroundTransparent);
}
else if (stack.getId() == 14) {
stack.view.setImageBitmap(Stack.backgroundTalon);
}
}
}

public booleanwinTest() {

39
for (inti = 7; i <= 10; i++) {
if (stacks[i].getSize() != 13) {
return false;
}
}

return true;
}

public void dealCards() {

prefs.saveKlondikeVegasDrawModeOld(whichGame);

if (prefs.getSavedKlondikeVegasDrawModeOld(whichGame).equals("1")) {
moveToStack(getMainStack().getTopCard(), stacks[13],
OPTION_NO_RECORD);
stacks[13].getCard(0).flipUp();
} else {
for (inti = 0; i <3; i++) {
moveToStack(getMainStack().getTopCard(), stacks[11 + i],
OPTION_NO_RECORD);
stacks[11 + i].getCard(0).flipUp();
}
}

for (inti = 0; i <= 6; i++) {


for (intj = 0; j < i + 1; j++) {
moveToStack(getMainStack().getTopCard(), stacks[i],
OPTION_NO_RECORD);
}
stacks[i].getCard(i).flipUp();
}
}

public intonMainStackTouch() {
booleandeal3 =
prefs.getSavedKlondikeVegasDrawModeOld(whichGame).equals("3");

if (getMainStack().getSize() >0) {
if (deal3) {
intsize = min(3, getMainStack().getSize());
ArrayList<Card>cardsReversed = new ArrayList<>();
ArrayList<Stack>originReversed = new ArrayList<>();
ArrayList<Card> cards = new ArrayList<>();
ArrayList<Stack> origin = new ArrayList<>();

while (!stacks[12].isEmpty()) {

40
cards.add(stacks[12].getTopCard());
origin.add(stacks[12]);
moveToStack(stacks[12].getTopCard(), stacks[11], OPTION_NO_RECORD);
}
while (!stacks[13].isEmpty()) {
cards.add(stacks[13].getTopCard());
origin.add(stacks[13]);
moveToStack(stacks[13].getTopCard(), stacks[11], OPTION_NO_RECORD);
}

for (inti = 0; i <cards.size(); i++) {


cardsReversed.add(cards.get(cards.size() - 1 - i));
originReversed.add(origin.get(cards.size() - 1 - i));
}
for (inti = 0; i <cards.size(); i++) {
cards.set(i, cardsReversed.get(i));
origin.set(i, originReversed.get(i));
}

for (inti = 0; i < size; i++) {


cards.add(getMainStack().getTopCard());
origin.add(getMainStack());
moveToStack(getMainStack().getTopCard(), stacks[11],
OPTION_NO_RECORD);
stacks[11].getTopCard().flipUp();
}

size = min(3, stacks[11].getSize());


if (size >1) {
moveToStack(stacks[11].getCardFromTop(1), stacks[12],
OPTION_NO_RECORD);
if (!cards.contains(stacks[12].getTopCard())) {
cards.add(stacks[12].getTopCard());
origin.add(stacks[11]);
}
}
if (size >0) {
moveToStack(stacks[11].getTopCard(), stacks[13], OPTION_NO_RECORD);
if (!cards.contains(stacks[13].getTopCard())) {
cards.add(stacks[13].getTopCard());
origin.add(stacks[11]);
}
}

if (!stacks[12].isEmpty()) {
stacks[12].getTopCard().view.bringToFront();
}
if (!stacks[13].isEmpty()) {
stacks[13].getTopCard().view.bringToFront();

41
}

cardsReversed.clear();
originReversed.clear();
for (inti = 0; i <cards.size(); i++) {
cardsReversed.add(cards.get(cards.size() - 1 - i));
originReversed.add(origin.get(cards.size() - 1 - i));
}

recordList.add(cardsReversed, originReversed);
} else {

moveToStack(getMainStack().getTopCard(), stacks[13]);
}

return 1;
}

else if ((stacks[11].getSize() != 0 || stacks[12].getSize() != 0 ||


stacks[13].getSize() != 0)) {
ArrayList<Card> cards = new ArrayList<>();

for (inti = 0; i <stacks[11].getSize(); i++) {


cards.add(stacks[11].getCard(i));
}

for (inti = 0; i <stacks[12].getSize(); i++) {


cards.add(stacks[12].getCard(i));
}

for (inti = 0; i <stacks[13].getSize(); i++) {


cards.add(stacks[13].getCard(i));
}

ArrayList<Card>cardsReversed = new ArrayList<>();


for (inti = 0; i <cards.size(); i++) {
cardsReversed.add(cards.get(cards.size() - 1 - i));
}

moveToStack(cardsReversed, getMainStack(), OPTION_REVERSED_RECORD);

return 2;
}

return 0;
}

public booleanautoCompleteStartTest() {

42
for (inti = 0; i <7; i++) {
if (stacks[i].getSize() >0 && !stacks[i].getCard(0).isUp()) {
return false;
}
}

if (prefs.getSavedKlondikeVegasDrawModeOld(whichGame).equals("3")||
hasLimitedRecycles()) {
if (getMainStack().getSize()>0 || stacks[11].getSize()>0 ||
stacks[12].getSize()>0 || stacks[13].getSize()>1){
return false;
}
}

return true;
}

public booleancardTest(Stack stack, Card card) {


if (stack.getId() <7) {
if (stack.isEmpty()) {
return card.getValue() == 13;
} else {
return canCardBePlaced(stack, card, ALTERNATING_COLOR, DESCENDING);
}
} else if (stack.getId() <11 &&movingCards.hasSingleCard()) {
if (stack.isEmpty()) {
return card.getValue() == 1;
} else {
return canCardBePlaced(stack, card, SAME_FAMILY, ASCENDING);
}
} else {
return false;
}
}

public booleanaddCardToMovementGameTest(Card card) {

return !(((card.getStackId() == 11 || card.getStackId() == 12) &&


!stacks[13].isEmpty())
|| (card.getStackId() == 11 &&
!stacks[12].isEmpty()));
}

public CardAndStackhintTest() {
Card card;

for (inti = 0; i <= 6; i++) {

Stack origin = stacks[i];

if (origin.isEmpty()) {

43
continue;
}

card = origin.getFirstUpCard();

if (!hint.hasVisited(card) && !(card.isFirstCard() &&card.getValue()


== 13)
&&card.getValue() != 1) {
for (intj = 0; j <= 6; j++) {
if (j == i) {
continue;
}

if (card.test(stacks[j])) {
return new CardAndStack(card, stacks[j]);
}
}
}

card = origin.getTopCard();

if (!hint.hasVisited(card)) {
for (intj = 7; j <= 10; j++) {
if (card.test(stacks[j])) {
return new CardAndStack(card, stacks[j]);
}
}
}

for (inti = 0; i <3; i++) {


if ((i <2 && !stacks[13].isEmpty()) || (i == 0 &&
!stacks[12].isEmpty())) {
continue;
}

if (stacks[11 + i].getSize() >0 && !hint.hasVisited(stacks[11 +


i].getTopCard())) {
for (intj = 10; j >= 0; j--) {
if (stacks[11 + i].getTopCard().test(stacks[j])) {
return new CardAndStack(stacks[11 + i].getTopCard(), stacks[j]);
}
}
}
}

return null;
}
44
public Stack doubleTapTest(Card card) {

if (card.isTopCard()) {
for (intj = 7; j <11; j++) {
if (card.test(stacks[j])) {
return stacks[j];
}
}
}

for (intj = 0; j <7; j++) {

if (card.getStackId() <7 &&sameCardOnOtherStack(card, stacks[j],


SAME_VALUE_AND_COLOR))
continue;

if (card.getValue() == 13 &&card.isFirstCard() &&card.getStackId() <=


6)
continue;

if (card.test(stacks[j])) {
return stacks[j];
}
}

for (intj = 0; j <7; j++) {


if (stacks[j].isEmpty() &&card.test(stacks[j]))
return stacks[j];
}

return null;
}

public CardAndStackautoCompletePhaseTwo() {

for (inti = 7; i <= 10; i++) {


Stack destination = stacks[i];

for (intj = 0; j <= 6; j++) {


Stack origin = stacks[j];

if (origin.getSize() >0 &&origin.getTopCard().test(destination)) {


return new CardAndStack(origin.getTopCard(), destination);
}
}

for (intj = 11; j <15; j++) {


Stack origin = stacks[j];
45
for (intk = 0; k <origin.getSize(); k++) {
if (origin.getCard(k).test(destination)) {
origin.getCard(k).flipUp();
return new CardAndStack(origin.getCard(k), destination);
}
}
}
}

return null;
}

public intaddPointsToScore(ArrayList<Card> cards, int[] originIDs,


int[] destinationIDs, booleanisUndoMovement) {
intoriginID = originIDs[0];
intdestinationID = destinationIDs[0];

for (inti=0;i<originIDs.length;i++){
if (originIDs[i] >=11 &&originIDs[i]<=13 &&destinationIDs[i] <=10){
return 45;
}
}

if (originID<7 &&destinationID>= 7 &&destinationID<= 10) {


return 60;
}
if (destinationID<7 &&originID>= 7 &&originID<= 10) {
return -75;
}
if (originID == destinationID) {
return 25;
}
if (originID>= 11 &&originID<14 &&destinationID == 14) {
return -200;
}

return 0;
}

public void testAfterMove() {

if (gameLogic.hasWon()){
return;
}

booleandeal1 =
prefs.getSavedKlondikeVegasDrawModeOld(whichGame).equals("1");
checkEmptyDiscardStack(getMainStack(),stacks[11], stacks[12],
stacks[13], deal1);
}
46
public static void checkEmptyDiscardStack(Stack mainStack, Stack
discard1, Stack discard2, Stack discard3, booleandeal1){

if (deal1 && discard3.isEmpty() && !mainStack.isEmpty()){


recordList.addToLastEntry(mainStack.getTopCard(), mainStack);
moveToStack(mainStack.getTopCard(),discard3, OPTION_NO_RECORD);
} else if (!deal1 && discard1.isEmpty() && discard2.isEmpty()
&& discard3.isEmpty() && !mainStack.isEmpty()){

intsize = min(3, mainStack.getSize());

ArrayList<Card> cards = new ArrayList<>();


ArrayList<Stack> origin = new ArrayList<>();

for (inti = 0; i < size; i++) {


cards.add(mainStack.getTopCard());
origin.add(mainStack);
moveToStack(mainStack.getTopCard(), discard1, OPTION_NO_RECORD);
discard1.getTopCard().flipUp();
}

size = min(3, discard1.getSize());


if (size >1) {
moveToStack(discard1.getCardFromTop(1), discard2, OPTION_NO_RECORD);

if(!cards.contains(discard2.getTopCard())) {
cards.add(discard2.getTopCard());
origin.add(discard1);
}
}

if(size >0) {
moveToStack(discard1.getTopCard(), discard3, OPTION_NO_RECORD);
if (!cards.contains(discard3.getTopCard())) {
cards.add(discard3.getTopCard());
origin.add(discard1);
}
}

ArrayList<Card>cardsReversed = new ArrayList<>();


ArrayList<Stack>originReversed = new ArrayList<>();
for (inti = 0; i <cards.size(); i++) {
cardsReversed.add(cards.get(cards.size() - 1 - i));
originReversed.add(origin.get(cards.size() - 1 - i));
}
47
if (!discard2.isEmpty()) {
discard2.getTopCard().view.bringToFront();
}

if (!discard3.isEmpty()) {
discard3.getTopCard().view.bringToFront();
}

recordList.addToLastEntry(cardsReversed, originReversed);
}

if (!deal1 && (discard2.getSize() == 0 || discard3.getSize() == 0)) {


ArrayList<Card> cards = new ArrayList<>();
ArrayList<Stack> origin = new ArrayList<>();

while (!discard2.isEmpty()) {
cards.add(discard2.getTopCard());
origin.add(discard2);
moveToStack(discard2.getTopCard(), discard1, OPTION_NO_RECORD);
}

if (discard1.getSize() >1) {
moveToStack(discard1.getCardFromTop(1), discard2, OPTION_NO_RECORD);
if (!cards.contains(discard2.getTopCard())) {
cards.add(discard2.getTopCard());
origin.add(discard1);
}
}

if (!discard1.isEmpty()) {
moveToStack(discard1.getTopCard(), discard3, OPTION_NO_RECORD);
if (!cards.contains(discard3.getTopCard())) {
cards.add(discard3.getTopCard());
origin.add(discard1);
}
}

ArrayList<Card>cardsReversed = new ArrayList<>();


ArrayList<Stack>originReversed = new ArrayList<>();
for (inti = 0; i <cards.size(); i++) {
cardsReversed.add(cards.get(cards.size() - 1 - i));
originReversed.add(origin.get(cards.size() - 1 - i));
}

48
if(!discard2.isEmpty()) {
discard2.getTopCard().view.bringToFront();
}

if (!discard3.isEmpty()) {s
discard3.getTopCard().view.bringToFront();
}

recordList.addToLastEntry(cardsReversed, originReversed);
}
}
}

Figure 3.12: Final Output of Movement of cards

49

You might also like