Skip to content

Instantly share code, notes, and snippets.

@bgourlie
Last active August 29, 2015 14:00
Show Gist options
  • Select an option

  • Save bgourlie/11349299 to your computer and use it in GitHub Desktop.

Select an option

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.
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