import java.io.*; import java.lang.*; import java.awt.*; import Deck; import Card; import Hand; import Player; import BuildStack; /* This class controls the overall function of the game, not the player interface to the game. That is handled by SkipBoWrapper. Major components are: an array of two players ( so it can be expanded) an array of four build stacks ( initially empty) a source deck of Cards ( this deck is dealt from ) a played deck ( when a build stack is filled it is placed in this deck. if the source deck is depleted then this one is used. ) */ public class SkipBo { final static int HANDSIZE = 5; final static int PLAYERCOUNT = 2; final static int NUM_BUILDS = 4; private Deck source = new Deck(); private Deck played = new Deck(); private BuildStack build[] = new BuildStack[NUM_BUILDS]; private Player player[] = new Player[PLAYERCOUNT]; private int current = 0; boolean game_over = false; public SkipBo (int storesize, String name1, String name2, int gamestate[]) /* provides initial game setup: creates players and build stacks, creates and shuffles the deck, and deals the cards */ { int i; for (i = 0; i < NUM_BUILDS; i++) { // init build stacks to empty build[i] = new BuildStack (); } player[0] = new Player(name1); if (name2.length() == 0){ //if no name, player is the computer player[1] = new CompPlayer(); } else player[1] = new Player(name2); source.Fill (PLAYERCOUNT + 2); //Initialize shuffled game deck source.Shuffle (); player[0].fillStore (storesize, HANDSIZE, source); player[1].fillStore (storesize, HANDSIZE, source); player[current].showPlayer (gamestate, build); } public boolean playCommand (int index, int gamestate[]) /* this function is called when the player attempts to play from the store stack. */ { Card temp; if (!game_over) { //play the card player[current].playStore (build[index]); if (player[current].storeEmpty()) { game_over = true; gameOver (player[current].name, 1); } } index = 0; //remove full build stacks while (index < NUM_BUILDS) { //if top card is a king if (!build[index].empty()) { temp = (Card) build[index].peek(); if (temp.showUseValue() == 13) fillPlayed(build[index], played); } index++; } //always update the gamestate player[current].showPlayer (gamestate, build); return game_over; } public boolean playCommand (char command, int index1, int index2, int gamestate[]) /* The case statement identifies the source and destination of the play. Index1 point to the card to play in either the hand or the array of discard stacks. Index2 indicates which build to put it on. */ { Card temp; if (!game_over) { switch (command){ case 'H': case 'h': { player[current].playHand (build[index2], index1); if (player[current].emptyHand()) if (!player[current].fillHand (source, HANDSIZE)) { getPlayed (played, source); player[current].fillHand (source, HANDSIZE); } break; } case 'D': case 'd': { player[current].playDiscard (build[index2], index1); break; } /* After a successful play in case f (finish or discard) the current player is set to the next player. If the next player is the computer, then it runs its plays in a loop until it finishes its turn with a discard. This case works for either two human players or one human and a computer player. */ case 'F': case 'f': { int value2; boolean success; success = player[current].playFinish (index1, index2); if (success) { current = (current + 1) % PLAYERCOUNT; if (!player[current].fillHand(source, HANDSIZE)) getPlayed (played, source); if (player[current] instanceof CompPlayer) { while (player[current].choosePlay(build, gamestate, source)) { if (player[current].storeEmpty()) game_over = true; } current = (current + 1) % PLAYERCOUNT; if (!player[current].fillHand(source, HANDSIZE)) getPlayed (played, source); } } break; } default: { //default is do nothing break; } } index1 = 0; while (index1 < NUM_BUILDS) { //remove full build stacks if (!build[index1].empty()) { temp = (Card) build[index1].peek(); if (temp.showUseValue() == 13) fillPlayed(build[index1], played); } index1++; } player[current].showPlayer (gamestate, build); //update game state } return game_over; } public String getName () { return player[current].name; } public void gameOver (String str, int condition) /* Changes the current player name to announce a winner or tie. Basically its a way to fake declaring a winner. */ { if (condition == 1) //Store condition player[current].name = player[current].name + " wins!"; if (condition == 2) //No cards condition player[current].name = "Out of Cards. It's a Draw."; game_over = true; } public void fillPlayed (BuildStack b, Deck played) /* When a king is placed on a build stack then it is full. This function pops the cards from a build stack a adds them to the played deck. If necessary they may shuffled and reused. */ { int i; Card c; Object object; for (i=0; i < 13; i++) { object = b.pop (); c = (Card) object; c.setUseValue (c.showFaceValue ()); played.addCard (c); } } public void getPlayed (Deck played, Deck source) /* If the source deck is emptied during the course of the game, then the played deck is recycled. This function moves the cards from the played deck to the source and shuffles. If both decks are empty then the game is a draw. */ { Card temp; System.out.println ("GOT PLAYED!!!!!!!!!!!!!!!!!!!!!!!!"); while (!played.isEmpty ()) { temp = played.Deal (); source.addCard (temp); } if (source.isEmpty ()) gameOver ("", 2); else source.Shuffle(); } public void dispose () /* removes the computer player window when the html page is changed. */ { if (player[1] instanceof CompPlayer) player[1].dispose(); } }