Last active
August 29, 2015 14:00
-
-
Save bgourlie/11349299 to your computer and use it in GitHub Desktop.
A couple years back I got a weird urge to write some entirely procedural code, so I made this text-based sheepshead game.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import java.util.Random; | |
| import java.util.Scanner; | |
| public class Main { | |
| private static final String[] card_labels = | |
| {"Q CLUBS ","Q SPADES ","Q HEARTS ","Q DIAMONDS ","J CLUBS ", | |
| "J SPADES ","J HEARTS ","J DIAMONDS ","A DIAMONDS ","10 DIAMONDS","K DIAMONDS ","9 DIAMONDS ", | |
| "8 DIAMONDS ","7 DIAMONDS ","A CLUBS ","10 CLUBS ","K CLUBS ","9 CLUBS ","8 CLUBS ", | |
| "7 CLUBS ","A SPADES ","10 SPADES ","K SPADES ","9 SPADES ","8 SPADES ","7 SPADES ", | |
| "A HEARTS ","10 HEARTS ","K HEARTS ","9 HEARTS ","8 HEARTS ","7 HEARTS " }; | |
| private static final int[] point_values = {3,3,3,3,2,2,2,2,11,10,4,0,0,0,11,10,4,0,0,0,11,10,4,0,0,0,11,10,4,0,0,0}; | |
| private static final String[] hand_labels = {"Player 1", "Player 2", "Player 3", "Player 4", "Player 5", "Blind "}; | |
| private static final String[] suit_labels = {"No Suit", "Trump", "Clubs", "Spades", "Hearts"}; | |
| private static final int TRUMP_LOW_BOUND = 0, TRUMP_HIGH_BOUND = 13; | |
| private static final int CLUBS_LOW_BOUND = 14, CLUBS_HIGH_BOUND = 19; | |
| private static final int SPADES_LOW_BOUND = 20, SPADES_HIGH_BOUND = 25; | |
| private static final int HEARTS_LOW_BOUND = 26, HEARTS_HIGH_BOUND = 31; | |
| private static final int CARDS_IN_DECK = 32, CARDS_IN_HAND = 6, CARDS_IN_BLIND = 2, NUM_PLAYERS = 5; | |
| private static final int CARDS_DEALT_AT_TIME = 3, MAX_DEAL_TICKS = 10, SCHNEIDER = 31, POINTS_NEEDED_TO_WIN = 61; | |
| private static final int PLAYER1 = 0, PLAYER2 = 1, PLAYER3 = 2, PLAYER4 = 3, PLAYER5 = 4, BLIND = 5; | |
| private static final int NO_PLAYER_PICKED = -1, NO_PARTNER = -1, JACK_OF_DIAMONDS = 7, EMPTY = -1, MAX_POINTS_POSSIBLE = 120; | |
| private static final int NO_SUIT = 0, TRUMP = 1, CLUBS = 2, SPADES = 3, HEARTS = 4, BASE_PICKER_POINTS = 2, BASE_PARTNER_POINTS = 1; | |
| private static final Random r = new Random(); | |
| public static void main(String args[]) { | |
| final Scanner s = new Scanner(System.in); | |
| //init game vars | |
| int dealer = r.nextInt(5); //select the first dealer at random | |
| int[] deck, scores = new int[NUM_PLAYERS]; | |
| int[][] hands = new int[6][]; | |
| hands[PLAYER1] = new int[CARDS_IN_HAND]; | |
| hands[PLAYER2] = new int[CARDS_IN_HAND]; | |
| hands[PLAYER3] = new int[CARDS_IN_HAND]; | |
| hands[PLAYER4] = new int[CARDS_IN_HAND]; | |
| hands[PLAYER5] = new int[CARDS_IN_HAND]; | |
| hands[BLIND] = new int[CARDS_IN_BLIND]; | |
| //main game loop | |
| while (true) { | |
| int cur_player = dealer < NUM_PLAYERS - 1 ? dealer + 1 : 0; | |
| int picker = NO_PLAYER_PICKED; | |
| deck = shuffle_deck(); | |
| //deal cards | |
| int player_being_dealt = dealer != (NUM_PLAYERS - 1) ? (dealer + 1) : 0; | |
| int cards_dealt = 0; | |
| for (int deal_tick = 0; deal_tick < MAX_DEAL_TICKS; deal_tick++) { | |
| if (deal_tick == 5) { | |
| hands[BLIND][0] = deck[cards_dealt++]; | |
| hands[BLIND][1] = deck[cards_dealt++]; | |
| } | |
| for (int y = 0; y < CARDS_DEALT_AT_TIME; y++) { | |
| hands[player_being_dealt][((deal_tick < 5) ? 0 : 3) + y] = deck[cards_dealt++]; | |
| } | |
| if (++player_being_dealt == NUM_PLAYERS) {player_being_dealt = 0;} | |
| } | |
| //determine picker | |
| int checking_player = cur_player; | |
| for (int i = 0; i < NUM_PLAYERS; i++) { | |
| String answer; | |
| do { | |
| print_hand(hands, checking_player); | |
| System.out.print(hand_labels[checking_player] + ", do you want to pick? Y/N: "); | |
| answer = s.next().toLowerCase(); | |
| } while (!answer.equals("n") && !answer.equals("y")); | |
| if (answer.equals("y")) { | |
| picker = checking_player; | |
| break; | |
| } | |
| checking_player = checking_player < (NUM_PLAYERS - 1) ? (checking_player + 1) : 0; | |
| } | |
| boolean is_leaster = false; | |
| int partner = NO_PARTNER; | |
| if (picker == NO_PLAYER_PICKED) { | |
| is_leaster = true; | |
| System.out.println("IT'S A LEASTER MEESTER!!!"); | |
| } else { | |
| //picker can now swap cards with blind... | |
| System.out.println("The picker " + hand_labels[picker] + " can optionally swap cards out of the blind into their hand"); | |
| int blind_card_pos, hand_card_pos; | |
| while (true) { | |
| print_hand(hands, BLIND); | |
| print_hand(hands, picker); | |
| System.out.print("Type corresponding Blind Card number to swap, or 9 to skip swapping: "); | |
| blind_card_pos = s.nextInt(); | |
| if (blind_card_pos == 9) { | |
| break; | |
| } | |
| System.out.print("Type corresponding Hand Card number to swap: "); | |
| do { | |
| hand_card_pos = s.nextInt(); | |
| } while (!(hand_card_pos >= 0 && hand_card_pos < CARDS_IN_HAND)); | |
| int blind_card = hands[BLIND][blind_card_pos]; //todo outofbounds exception, make sure blind_card_pos either 0 or 1 and hard card pos between 0 and 5 | |
| int hand_card = hands[picker][hand_card_pos]; | |
| hands[BLIND][blind_card_pos] = hand_card; | |
| hands[picker][hand_card_pos] = blind_card; | |
| } | |
| //determine_partner | |
| for (int player = 0; player < NUM_PLAYERS; player++) { | |
| if(player == picker){continue;} | |
| for (int card = 0; card < CARDS_IN_HAND; card++) { | |
| if (hands[player][card] == JACK_OF_DIAMONDS) { | |
| partner = player; | |
| } | |
| if(partner == player){break;} | |
| } | |
| } | |
| } | |
| int[] trick_points = new int[NUM_PLAYERS]; | |
| for (int hand_tick = 0; hand_tick < CARDS_IN_HAND; hand_tick++) { | |
| int[] cur_trick = new int[NUM_PLAYERS]; | |
| for (int i = 0; i < NUM_PLAYERS; i++) {cur_trick[i] = EMPTY;} | |
| int cur_trick_suit = NO_SUIT; | |
| for (int player_tick = 0; player_tick < NUM_PLAYERS; player_tick++) { | |
| print_trick(cur_trick, cur_trick_suit); //display the current state of the trick | |
| print_hand(hands, cur_player); //display the current players hand | |
| //player plays a card... | |
| int card_to_play; | |
| while (true) { | |
| System.out.print(hand_labels[cur_player] + ", choose a card to play: "); | |
| card_to_play = s.nextInt(); | |
| if (!(card_to_play >= 0 && card_to_play < CARDS_IN_HAND)) { //invalid card position | |
| System.out.println(card_to_play + " is not a valid card position"); | |
| continue; | |
| } | |
| if (hands[cur_player][card_to_play] == EMPTY) { //no card at position) | |
| System.out.println("There is no card at position " + card_to_play); | |
| continue; | |
| } | |
| if (cur_trick_suit != NO_SUIT //suit has been determined | |
| && player_has_suit(hands, cur_player, cur_trick_suit) //the player has the trick suit | |
| && get_card_suit(hands[cur_player][card_to_play]) != cur_trick_suit) { //and they didnt follow suit | |
| System.out.println("You must follow suit. The trick suit is " + suit_labels[cur_trick_suit]); | |
| continue; | |
| } | |
| break; | |
| } | |
| cur_trick[cur_player] = hands[cur_player][card_to_play]; //lay the card down | |
| hands[cur_player][card_to_play] = EMPTY; //remove card from players hand | |
| if (player_tick == 0) {cur_trick_suit = get_card_suit(cur_trick[cur_player]);}//if this was the card played of the hand, set the current tricks suit | |
| cur_player = cur_player < NUM_PLAYERS - 1 ? cur_player + 1 : 0; //players take turns in a clock-wise order | |
| } | |
| cur_player = determine_trick_winner(cur_trick, cur_trick_suit); | |
| //add up points for the trick | |
| for (int i = 0; i < NUM_PLAYERS; i++) {trick_points[cur_player] += point_values[cur_trick[i]];} | |
| System.out.println(hand_labels[cur_player] + " wins the trick!"); | |
| } | |
| if (!is_leaster) { | |
| int picker_and_partner_total = (partner == NO_PARTNER ? trick_points[picker] : (trick_points[picker] + trick_points[partner])) + point_values[hands[BLIND][0]] + point_values[hands[BLIND][1]]; | |
| int opposition_total = MAX_POINTS_POSSIBLE - picker_and_partner_total; | |
| System.out.print(partner != NO_PARTNER ? "The picker and partner " : "The picker "); | |
| System.out.println("totalled " + picker_and_partner_total + " points."); | |
| System.out.println("The opposition totalled " + opposition_total + " points."); | |
| int multiplier = 1; | |
| boolean picker_got_schnitz = picker_and_partner_total >= POINTS_NEEDED_TO_WIN; | |
| if (partner == NO_PARTNER) {multiplier++;} //todo verify extra modifier for going alone | |
| if (picker_and_partner_total < SCHNEIDER || opposition_total < SCHNEIDER){multiplier++;} | |
| if (picker_and_partner_total == MAX_POINTS_POSSIBLE) {multiplier++;} | |
| int picker_points = picker_got_schnitz ? BASE_PICKER_POINTS * multiplier : BASE_PICKER_POINTS * -multiplier; | |
| int partner_points = picker_got_schnitz ? BASE_PARTNER_POINTS * multiplier : BASE_PARTNER_POINTS * -multiplier; | |
| scores[picker] += picker_points; | |
| if (partner != NO_PARTNER) { | |
| System.out.println("Picker gets " + picker_points + " points."); | |
| System.out.println("Partner gets " + partner_points + " points."); | |
| scores[partner] += partner_points; | |
| } else { | |
| System.out.println("Picker gets " + (picker_points + partner_points) + " points."); | |
| scores[picker] += picker_points; | |
| } | |
| int num_opposition_players = partner == NO_PARTNER ? 4 : 3; | |
| //todo this is a logic check, verify and remove | |
| if ((picker_points + partner_points) % num_opposition_players != 0) { | |
| System.out.println("HALT@@!! Net points does not equal 0!!"); | |
| s.next(); | |
| } | |
| //todo end check | |
| //accumulate points | |
| int opposition_points = (picker_points + partner_points) / num_opposition_players; | |
| opposition_points = picker_got_schnitz ? -opposition_points : opposition_points; | |
| System.out.println("Each opposition player gets " + opposition_points + " points."); | |
| for (int player = 0; player < NUM_PLAYERS; player++) { | |
| if (player == picker || (partner != NO_PARTNER && player == partner)) {continue;} | |
| scores[player] += opposition_points; | |
| } | |
| //print game totals | |
| } else { //is leaster | |
| } | |
| System.out.println("Scorecard"); | |
| for(int i = 0; i < NUM_PLAYERS; i++){System.out.println(hand_labels[i] + ": " + scores[i]);} | |
| } | |
| } | |
| private static int get_card_suit(int card) { | |
| if (card >= TRUMP_LOW_BOUND && card <= TRUMP_HIGH_BOUND) {return TRUMP;} | |
| if (card >= CLUBS_LOW_BOUND && card <= CLUBS_HIGH_BOUND) {return CLUBS;} | |
| if (card >= SPADES_LOW_BOUND && card <= SPADES_HIGH_BOUND) {return SPADES;} | |
| if (card >= HEARTS_LOW_BOUND && card <= HEARTS_HIGH_BOUND) {return HEARTS;} | |
| return -2; | |
| } | |
| private static boolean player_has_suit(int[][] hands, int player, int suit) { | |
| for (int i = 0; i < CARDS_IN_HAND; i++) { | |
| if (get_card_suit(hands[player][i]) == suit) {return true;} | |
| } | |
| return false; | |
| } | |
| private static void print_trick(int[] trick, int cur_trick_suit) { | |
| System.out.println("Trick (" + suit_labels[cur_trick_suit] + ")"); | |
| for (int i = 0; i < NUM_PLAYERS; i++) { | |
| System.out.print(hand_labels[i] + ": "); | |
| if (trick[i] == EMPTY) {System.out.print(" Hasn't played yet"); | |
| } else { | |
| System.out.print(card_labels[trick[i]]); | |
| } | |
| System.out.println(); | |
| } | |
| } | |
| private static int determine_trick_winner(int[] trick, int trick_suit) { | |
| int winning_player = -1, last_card_checked = 127; | |
| for (int i = 0; i < NUM_PLAYERS; i++) { | |
| int cur_card_suit = get_card_suit(trick[i]); | |
| if ((cur_card_suit == TRUMP || cur_card_suit == trick_suit) && trick[i] < last_card_checked) { | |
| last_card_checked = trick[i]; | |
| winning_player = i; | |
| } | |
| } | |
| return winning_player; | |
| } | |
| private static int[] shuffle_deck() { | |
| int cards_processed = 0; | |
| int[] deck = new int[CARDS_IN_DECK]; | |
| for (int i = 0; i < CARDS_IN_DECK; i++) { | |
| boolean card_was_found; | |
| int next_card; | |
| do { | |
| next_card = r.nextInt(CARDS_IN_DECK); | |
| card_was_found = false; | |
| for (int x = 0; x < cards_processed; x++) { | |
| if (deck[x] == next_card) { | |
| card_was_found = true; | |
| break; | |
| } | |
| } | |
| } while (card_was_found); | |
| deck[i] = next_card; | |
| cards_processed++; | |
| } | |
| return deck; | |
| } | |
| private static void print_hand(int hands[][], int hand) { | |
| System.out.print(hand_labels[hand] + " hand: "); | |
| for (int i = 0; i < hands[hand].length; i++) { | |
| if (hands[hand][i] != EMPTY) {System.out.print("(" + i + ") " + card_labels[hands[hand][i]] + " ");} | |
| } | |
| System.out.println(); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment