//*****************************************
// Filename: ai.cpp
// Author: Aaron Rogers
// Updated: 11/04/02
// Purpose: Hearts game AI
//*****************************************
// This file is part of HAM Tutorial Hearts
// Copyright 2002 Aaron Rogers
// See README.txt for more information
//*****************************************


#include "ai.h"
#include "stdlib.h"


//***************************************
// Function: ai_setup_passed_cards()
// Purpose: Determine three cards to pass
//***************************************
void ai_setup_passed_cards(HEARTS *game, u8 skill)
{  
  // Variables
  u8 P2_one = 13, P2_two = 13, P2_thr = 13;
  u8 P3_one = 13, P3_two = 13, P3_thr = 13;
  u8 P4_one = 13, P4_two = 13, P4_thr = 13;

  // The cards will be decided based on the AI's skill
  if (skill == 1) {
   bool is_done = false; // To get out of the while loop

   // Get three different numbers from 0 to 12
   while (!is_done) {
   P2_one = rand()%13;
   P2_two = rand()%13;
   P2_thr = rand()%13;

   if ((P2_one != P2_two) && (P2_two != P2_thr) && (P2_one != P2_thr)) {
   P3_one = P2_one;
   P3_two = P2_two;
   P3_thr = P2_thr;
   P4_one = P2_one;
   P4_two = P2_two;
   P4_thr = P2_thr;
   is_done = true;
   }
   }
  } else if (skill == 2 || skill == 3) {
   // Variables
   bool one_3 = false;
   bool two_3 = false;
   bool thr_3 = false;
   Card one_card;
   Card two_card;
   Card thr_card;
   u8 value[9]; // P2: 0-2, P3: 3-5, P4: 6-8

   // Set the values to 13
   for (u8 i = 0; i < 9; ++i) value[i] = 13;

   // Start searching Player2's hands
   for (u8 i = 0; i < 13; ++i) {
   // Copy a card from player's hand to a temp card
   one_card = game->get_card(2, i);

   // See if it should be stored (and later passed)
   if (card_value(game, 2, one_card) > 0) { // It's a (somewhat) valuable card
   if (value[0] == 13) { // If the spot is empty...
   value[0] = i; // ... store it ...
   continue; // ... and start the for loop over again
   } else if (value[1] == 13) {
   value[1] = i;
   continue;
   } else if (value[2] == 13) {
   value[2] = i;
   continue;
   }

   // See if the current card is move valuable than a previously stored card
   if (card_value(game, 2, one_card) > card_value(game, 2, game->get_card(2, value[0]))) {
   value[0] = i;
   continue;
   } else if (card_value(game, 2, one_card) > card_value(game, 2, game->get_card(2, value[1]))) {
   value[1] = i;
   continue;
   } else if (card_value(game, 2, one_card) > card_value(game, 2, game->get_card(2, value[2]))) {
   value[2] = i;
   continue;
   }
   }
   } // End of for(...)

   // Start searching Player3's hands
   for (u8 i = 0; i < 13; ++i) {
   // Copy a card from player's hand to a temp card
   two_card = game->get_card(3, i);

   // See if it should be stored (and later passed)
   if (card_value(game, 3, two_card) > 0) { // It's a (somewhat) valuable card
   if (value[3] == 13) { // If the spot is empty...
   value[3] = i; // ... store it ...
   continue; // ... and start the for loop over again
   } else if (value[4] == 13) {
   value[4] = i;
   continue;
   } else if (value[5] == 13) {
   value[5] = i;
   continue;
   }

   // See if the current card is move valuable than a previously stored card
   if (card_value(game, 3, two_card) > card_value(game, 3, game->get_card(3, value[3]))) {
   value[3] = i;
   continue;
   } else if (card_value(game, 3, two_card) > card_value(game, 3, game->get_card(3, value[4]))) {
   value[4] = i;
   continue;
   } else if (card_value(game, 3, two_card) > card_value(game, 3, game->get_card(3, value[5]))) {
   value[5] = i;
   continue;
   }
   }
   } // End of for(...)

   // Start searching Player4's hands
   for (u8 i = 0; i < 13; ++i) {
   // Copy a card from player's hand to a temp card
   thr_card = game->get_card(4, i);

   // See if it should be stored (and later passed)
   if (card_value(game, 4, thr_card) > 0) { // It's a (somewhat) valuable card
   if (value[6] == 13) { // If the spot is empty...
   value[6] = i; // ... store it ...
   continue; // ... and start the for loop over again
   } else if (value[7] == 13) {
   value[7] = i;
   continue;
   } else if (value[8] == 13) {
   value[8] = i;
   continue;
   }

   // See if the current card is move valuable than a previously stored card
   if (card_value(game, 4, thr_card) > card_value(game, 4, game->get_card(4, value[6]))) {
   value[6] = i;
   continue;
   } else if (card_value(game, 4, thr_card) > card_value(game, 4, game->get_card(4, value[7]))) {
   value[7] = i;
   continue;
   } else if (card_value(game, 4, thr_card) > card_value(game, 4, game->get_card(4, value[8]))) {
   value[8] = i;
   continue;
   }
   }
   } // End of for(...)

   // Copy over the good values
   if (value[0] != 13) P2_one = value[0];
   if (value[1] != 13) P2_two = value[1];
   if (value[2] != 13) P2_thr = value[2];
   if (value[3] != 13) P3_one = value[3];
   if (value[4] != 13) P3_two = value[4];
   if (value[5] != 13) P3_thr = value[5];
   if (value[6] != 13) P4_one = value[6];
   if (value[7] != 13) P4_two = value[7];
   if (value[8] != 13) P4_thr = value[8];

   // See if all of the values are filled in
   if (value[0] != 13 && value[1] != 13 && value[2] != 13) one_3 = true;
   if (value[3] != 13 && value[4] != 13 && value[5] != 13) two_3 = true;
   if (value[6] != 13 && value[7] != 13 && value[8] != 13) thr_3 = true;

   // If any of the values aren't good, we'll have to get more
   if (!one_3 || !two_3 || !thr_3) {

   // Setup some temp variables
   bool p2_1 = false, p2_2 = false, p2_3 = false;
   bool p3_1 = false, p3_2 = false, p3_3 = false;
   bool p4_1 = false, p4_2 = false, p4_3 = false;

   // If any of them have a good value, we won't change that later
   if (value[0] != 13) p2_1 = true;
   if (value[1] != 13) p2_2 = true;
   if (value[2] != 13) p2_3 = true;
   if (value[3] != 13) p3_1 = true;
   if (value[4] != 13) p3_2 = true;
   if (value[5] != 13) p3_3 = true;
   if (value[6] != 13) p4_1 = true;
   if (value[7] != 13) p4_2 = true;
   if (value[8] != 13) p4_3 = true;

   // Just in case each player hasn't selected 3 cards, randomly pick the rest
   while (!one_3) {
   // Get three different numbers from 0 to 12
   if (!p2_1) P2_one = rand()%13;
   if (!p2_2) P2_two = rand()%13;
   if (!p2_3) P2_thr = rand()%13;

   if ((P2_one != P2_two) && (P2_two != P2_thr) && (P2_one != P2_thr)) {
   one_3 = true;
   }
   }
   while (!two_3) {
   // Get three different numbers from 0 to 12
   if (!p3_1) P3_one = rand()%13;
   if (!p3_2) P3_two = rand()%13;
   if (!p3_3) P3_thr = rand()%13;

   if ((P3_one != P3_two) && (P3_two != P3_thr) && (P3_one != P3_thr)) {
   two_3 = true;
   }
   }
   while (!thr_3) {
   // Get three different numbers from 0 to 12
   if (!p4_1) P4_one = rand()%13;
   if (!p4_2) P4_two = rand()%13;
   if (!p4_3) P4_thr = rand()%13;

   if ((P4_one != P4_two) && (P4_two != P4_thr) && (P4_one != P4_thr)) {
   thr_3 = true;
   }
   }
   }

  } // End of if (skill == x) ...

  game->add_to_passed_cards(3, P2_one);
  game->add_to_passed_cards(4, P2_two);
  game->add_to_passed_cards(5, P2_thr);
  game->add_to_passed_cards(6, P3_one);
  game->add_to_passed_cards(7, P3_two);
  game->add_to_passed_cards(8, P3_thr);
  game->add_to_passed_cards(9, P4_one);
  game->add_to_passed_cards(10, P4_two);
  game->add_to_passed_cards(11, P4_thr);

  return;
}


//*************************************************
// Function: ai_choose_card()
// Purpose: Determine which card the AI should play
//*************************************************
u8 ai_choose_card(HEARTS *game, u8 skill)
{
  // Variables
  u8 Chosen_Card = 13;
  u8 curr_turn = game->gt(); // Current turn
  u8 curr_lead = game->gl(); // Who lead

  // Check if the computer has the 2 of Clubs
  Chosen_Card = Two_of_Clubs(game, curr_turn);
  if (Chosen_Card != 13) return Chosen_Card;

  // Figure out the suit that was played
  u8 suit_lead = game->gsl();

  if (skill == 1) {

   // Look through hand for card of that suit
   for (u8 i = 0; i < 13; ++i) {
   if ((game->player_number(curr_turn, i) != 0) &&
   (game->player_suit(curr_turn, i) == suit_lead)) {
   return i;
   }
   }

   // Pick a random card
   Chosen_Card = 0;
   while (game->player_number(curr_turn, Chosen_Card) == 0) {
   ++Chosen_Card;
   }
  } else if (skill == 2 || skill == 3) {
   // AI must throw the first card (but not 2 of Clubs)
   if (curr_turn == curr_lead) {
   // Throw the lowest card
   Chosen_Card = lowest_card(game, curr_turn);
   if (Chosen_Card != 13) return Chosen_Card;

   // Pick a random card
   for (Chosen_Card = 0; Chosen_Card < 13; ++Chosen_Card) {
   if (game->player_number(curr_turn, Chosen_Card) != 0 && game->valid_move(curr_turn, Chosen_Card))
   return Chosen_Card;
   }

   // AI does not have to throw the first card
   } else {
   // Check whether AI has to follow suit
   if (has_suit(game, curr_turn, suit_lead)) {
// If Spades was led...
   if (suit_lead == 0) {
   // ... if the player can get rid of the Queen, play it
   Chosen_Card = play_Qsp(game, curr_turn);
   if (Chosen_Card != 13) return Chosen_Card;

   // ... if the player can get rid of the A or K, play it
   Chosen_Card = play_AKsp(game, curr_turn);
   if (Chosen_Card != 13) return Chosen_Card;
   }
  
   // If Hearts or Spades was lead, play the lowest
   if (suit_lead == 2 || suit_lead == 0) {
   Chosen_Card = lowest_of_suit(game, curr_turn, suit_lead);
   if (Chosen_Card != 13) return Chosen_Card;
   }

   // Figure out what the current highest of the suit lead is
   u8 highest = get_high(game, suit_lead);
   u8 gch = get_closest_high(game, curr_turn, suit_lead, highest);
   u8 gcl = get_closest_low(game, curr_turn, suit_lead, highest);

   // If only lower, play highest of low
   if (gcl != 13 && gch == 13) return gcl;
   // If only higher, play lowest of high...
   // ... unless player is the last to play
   if (gch != 13 && gcl == 13) {
   if (game->gtc() == 3) {
   Chosen_Card = highest_of_suit(game, curr_turn, suit_lead);
   if (Chosen_Card != 13) return Chosen_Card;
   } else {
   return gch;
   }
   }

   // Throw lowest card of the suit lead
   Chosen_Card = lowest_of_suit(game, curr_turn, suit_lead);
   if (Chosen_Card != 13) return Chosen_Card;

   // Void in the suit lead
   } else {
   // If AI has the Queen of Spades, play it, except on the first trick
   if (game->gtr() != 1) Chosen_Card = Queen_of_Spades(game, curr_turn);
   if (Chosen_Card != 13) return Chosen_Card;

   // If AI has the Ace of Spades, play it
   Chosen_Card = has_card(game, curr_turn, 14, 0);
   if (Chosen_Card != 13) return Chosen_Card;

   // If AI has the King of Spades, play it
   Chosen_Card = has_card(game, curr_turn, 13, 0);
   if (Chosen_Card != 13) return Chosen_Card;

   // If AI can void itself in a suit, do so
   Chosen_Card = void_suit(game, curr_turn);
   if (Chosen_Card != 13) return Chosen_Card;

   // If AI has a Heart greater than the 10, play it
   if (has_suit(game, curr_turn, 2)) {
   Chosen_Card = highest_of_suit(game, curr_turn, 2);
   if ((Chosen_Card != 13) && (game->player_number(curr_turn, Chosen_Card) > 10) &&
   (game->valid_move(curr_turn, Chosen_Card))) {
   return Chosen_Card;
   }
   }

   // Throw the highest card
   Chosen_Card = highest_card(game, curr_turn);
   if (Chosen_Card != 13) return Chosen_Card;
   } // End of if (has_suit(...))
   }
  }

  return Chosen_Card;
} // End of ai_choose_card()


//******************************************
// Function: card_value()
// Purpose: Returns the card's passing value
//******************************************
u8 card_value(HEARTS *game, u8 player, Card cv_card)
{
  // Variables
  u8 number = cv_card.number;
  u8 suit = cv_card.suit;

  // If the player has more than 3 cards below
  // the 8 of Spades, keep the A,K,Q of Spades
  if (num_sp_below_eight(game, player) > 2) {
   if (number == 12 && suit == 0) return 0;
   if (number == 14 && suit == 0) return 0;
   if (number == 13 && suit == 0) return 0;
  } else {
   if (number == 12 && suit == 0) return 10;
   if (number == 14 && suit == 0) return 9;
   if (number == 13 && suit == 0) return 9;
  }

  // Go through the rest of the deck
  if (number == 14 && suit == 2) return 8;
  if (number == 13 && suit == 2) return 8;
  if (number == 12 && suit == 2) return 8;
  if (number == 11 && suit == 2) return 7;
  if (number == 14 && suit == 3) return 7;
  if (number == 14 && suit == 1) return 7;
  if (number == 13 && suit == 3) return 6;
  if (number == 13 && suit == 1) return 6;
  if (number == 12 && suit == 3) return 5;
  if (number == 12 && suit == 1) return 5;
  if (number == 11 && suit == 3) return 4;
  if (number == 11 && suit == 1) return 4;
  if (number == 11 && suit == 0) return 4;

  if (number == 10) return 3;
  if (number == 9) return 3;
  if (number == 8) return 3;
  if (number == 7) return 2;
  if (number == 6) return 2;
  if (number == 5) return 2;
  if (number == 4) return 1;
  if (number == 3) return 1;
  if (number == 2) return 1;

  return 0;
} // End of card_value()


//************************************
// Function: Two_of_Clubs()
// Purpose: Check whether has
// the 2 of Clubs
//************************************
u8 Two_of_Clubs(HEARTS *game, u8 player)
{
  for (u8 i = 0; i < 13; ++i) {
   if (game->player_number(player, i) == 2 && // It's a 2 ...
   game->player_suit(player,i) == 1) { // ... of Clubs
   return i;
   }
  }

  // The calling function should make sure to
  // check that the return value is != 13
  return 13;
} // End of Two_of_Clubs()


//************************************
// Function: Queen_of_Spades()
// Purpose: Check whether has
// the Queen of Spades
//************************************
u8 Queen_of_Spades(HEARTS *game, u8 player)
{
  for (u8 i = 0; i < 13; ++i) {
   if (game->player_number(player, i) == 12 && // It's a Queen ...
   game->player_suit(player,i) == 0) { // ... of Spades
   return i;
   }
  }

  // The calling function should make sure to
  // check that the return value is != 13
  return 13;
} // End of Queen_of_Spades()


//******************************************
// Function: has_card()
// Purpose: Returns the slot if has
// a card matching ,
// or returns 13 if not
//******************************************
u8 has_card(HEARTS *game, u8 player, u8 number, u8 suit)
{
  // Variables
  u8 h_c = 13;

  // Loop through 's hand
  for (u8 i = 0; i < 13; ++i) {
   if (game->player_number(player, i) == number && game->player_suit(player, i) == suit) {
   return i;
   }
  }

  return h_c;
} // End of has_card()


//**************************************
// Function: has_suit()
// Purpose: Check whether has a
// card with suit
//**************************************
bool has_suit(HEARTS *game, u8 player, u8 suit)
{
  for (u8 i = 0; i < 13; ++i) {
   if ((game->player_number(player, i) != 0) && game->player_suit(player, i) == suit)
   return true;
  }

  return false;
} // End of has_suit()


//*****************************************
// Function: get_high()
// Purpose: Returns the slot of the current
// highest card of
//*****************************************
u8 get_high(HEARTS *game, u8 suit)
{
  // Variables
  u8 curr_high = 4;

  // Cycle through the tricks
  for (u8 i = 0; i < 4; ++i) {
   if (game->trick_suit(i) == suit) {
   if (curr_high == 4) {
   curr_high = i;
   } else if (game->trick_number(i) > game->trick_number(curr_high)) {
   curr_high = i;
   }
   }
  }

  // Make sure to check that the return value is != 4
  return curr_high;
}


//**********************************************
// Function: get_closest_high()
// Purpose: Returns the slot of the next highest
// card, if any, in 's hand
// that is higher than . Returns
// 13 if only has lower cards
//**********************************************
u8 get_closest_high(HEARTS *game, u8 player, u8 suit, u8 high)
{
  // No need to do any checks if is an Ace
  if (high == 14) return 13;

  // Variables
  u8 closest_high = 13;

  // Loop through 's hand
  for (u8 i = 0; i < 13; ++i) {
   // If the suit matches and the number is higher
   if ((game->player_suit(player, i) == suit) && (game->player_number(player, i) > high)) {
   // If this is the first card that's higher, store it
   if (closest_high == 13) {
   closest_high = i;
   // Otherwise, check if this is lower than the current stored card
   } else if ((game->player_number(player, i)) < (game->player_number(player, closest_high))) {
   closest_high = i;
   }
   }
  }

  return closest_high;
} // End of closest_high()


//**********************************************
// Function: get_closest_low()
// Purpose: Returns the slot of the next lowest
// card, if any, in 's hand
// that is lower than . Returns
// 13 if only has higher cards
//**********************************************
u8 get_closest_low(HEARTS *game, u8 player, u8 suit, u8 low)
{
  // No need to do any checks if is a 2
  if (low == 2) return 13;

  // Variables
  u8 closest_low = 13;

  // Loop through 's hand
  for (u8 i = 0; i < 13; ++i) {
   // If the suit matches and the number is lower
   if ((game->player_suit(player, i) == suit) && (game->player_number(player, i) < low)) {
   // If this is the first card that's lower, store it
   if (closest_low == 13) {
   closest_low = i;
   // Otherwise, check if this is higher than the current stored card
   } else if ((game->player_number(player, i)) > (game->player_number(player, closest_low))) {
   closest_low = i;
   }
   }
  }

  return closest_low;
} // End of closest_low()


//*********************************************
// Function: lowest_of_suit()
// Purpose: Returns the slot of the lowest card
// of in 's hand or 13
// if they don't have it
//*********************************************
u8 lowest_of_suit(HEARTS *game, u8 player, u8 suit)
{
  // Variables
  u8 the_lowest = 13;

  // If they don't have the suit, forget it
  //if (!has_suit(game, player, suit)) return 13;

  // Loop through 's cards of for the lowest one
  for (u8 i = 0; i < 13; ++i) {
   if (game->player_suit(player, i) == suit) {
   if (the_lowest == 13) {
   the_lowest = i;
   } else if (game->player_number(player, the_lowest) > game->player_number(player, i)) {
   the_lowest = i;
   }
   }
  }

  return the_lowest;
} // End of lowest_of_suit()


//**********************************************
// Function: highest_of_suit()
// Purpose: Returns the slot of the highest card
// of in 's hand or 13
// if they don't have it
//**********************************************
u8 highest_of_suit(HEARTS *game, u8 player, u8 suit)
{
  // Variables
  u8 the_highest = 13;

  // If they don't have the suit, forget it
  if (!has_suit(game, player, suit)) return 13;

  // Loop through 's cards of for the lowest one
  for (u8 i = 0; i < 13; ++i) {
   if (game->player_suit(player, i) == suit) {
   if (the_highest == 13) {
   the_highest = i;
   } else if (game->player_number(player, the_highest) < game->player_number(player, i)) {
   the_highest = i;
   }
   }
  }

  return the_highest;
} // End of highest_of_suit()


//****************************************
// Function: lowest_card()
// Purpose: Returns the slot of the lowest
// card in 's hand
//****************************************
u8 lowest_card(HEARTS *game, u8 player)
{
  // Variables
  u8 low_card = 13;

  // Start searching
  for (u8 i = 0; i < 13; ++i) {
   if (game->player_number(player, i) != 0) {
   // Make sure if it's a Heart that Hearts are broken
   if ((game->player_suit(player, i) != 2) ||
   (game->player_suit(player, i) == 2 && (game->valid_move(player, i)))) {
   // This is the first low card
   if (low_card == 13) {
   low_card = i;
   // Current card is lower than the previous low card
   } else if (game->player_number(player, i) < game->player_number(player, low_card)) {
   low_card = i;
   }
   }
   }
  }

  return low_card;
} // End of lowest_card()


//*****************************************
// Function: highest_card()
// Purpose: Returns the slot of the highest
// card in 's hand
//*****************************************
u8 highest_card(HEARTS *game, u8 player)
{
  // Variables
  u8 high_card = 13;

  // Start searching
  for (u8 i = 0; i < 13; ++i) {
   if (game->player_number(player, i) != 0) {
   if (high_card == 13) {
   high_card = i;
   } else if (game->player_number(player, i) > game->player_number(player, high_card)) {
   // Make sure if it's a Heart that Hearts are broken
   if ((game->player_suit(player, i) != 2) ||
   ((game->player_suit(player, i) == 2) && (game->valid_move(player, i)))) {
   high_card = i;
   }
   }
   }
  }

  return high_card;
} // End of highest_card()


//************************************
// Function: void_suit()
// Purpose: Would playing one card get
// rid of a suit for
//************************************
u8 void_suit(HEARTS *game, u8 player)
{
  // Variables
  u8 vs = 13; // The spot that will be returned
  u8 num_suits[4]; // Stores the number of that suit
  u8 loc_suits[4]; // Stores the location of that suit
  u8 curr_suit = 4; // The current suit of a card in 's hand

  // Set all of the current number of suits to 0
  for (u8 i = 0; i < 4; ++i) num_suits[i] = 0;

  // Now count them up
  for (u8 i = 0; i < 13; ++i) {
   if (game->player_number(player, i) != 0) {
curr_suit = game->player_suit(player, i);
   if (curr_suit == 0) {
   ++num_suits[0];
   loc_suits[0] = i;
   } else if (curr_suit == 1) {
   ++num_suits[1];
   loc_suits[1] = i;
   } else if (curr_suit == 2) {
   ++num_suits[2];
   loc_suits[2] = i;
   } else if (curr_suit == 3) {
   ++num_suits[3];
   loc_suits[3] = i;
   }
   }
  }

  // Figure out if any were only one
  for (u8 i = 0; i < 13; ++i) {
   if (num_suits[i] == 1) {
   // Make sure if it's a Heart that Hearts are broken
   if ((i != 2) || ((i == 2) && (game->valid_move(player, loc_suits[i])))) {
   return loc_suits[i]; // And return that location
   }
   }
  }

  return vs;
} // End of void_suit()


//**************************************
// Function: number_of_suit()
// Purpose: Returns the number of
// in 's hand
//**************************************
u8 number_of_suit(HEARTS *game, u8 player, u8 suit)
{
  // Variables
  u8 num_suit = 0;

  // Loop through 's cards
  for (u8 i = 0; i < 13; ++i) {
   if (game->player_number(player, i) != 0 && game->player_suit(player, i) == suit) ++num_suit;
  }

  return num_suit;
} // End of number_of_suit()


//****************************************
// Function: num_sp_below_eight()
// Purpose: Returns the number of Spades
// in 's hand below the 8
//****************************************
u8 num_sp_below_eight(HEARTS *game, u8 player)
{
  // Variables
  u8 num_suit = 0;

  // Loop through 's cards
  for (u8 i = 0; i < 13; ++i) {
   if (game->player_number(player, i) < 8 && game->player_suit(player, i) == 0) ++num_suit;
  }

  return num_suit;
} // End of num_sp_below_eight()


//***********************************************
// Function: play_AKsp()
// Purpose: Determine if should play
// the Ace or King of Spades. Returns
// the slot of either if so or 13 if not
//***********************************************
u8 play_AKsp(HEARTS *game, u8 player)
{
  // Variables
  u8 Asp_slot = 13;
  u8 Ksp_slot = 13;
u8 trick_cards = game->gtc();
  u8 curr_numb = 0;
  bool has_AKsp = false;

  // The player must have the Ace or King of Spades
  for (u8 i = 0; i < 13; ++i) {
   if (game->player_suit(player, i) == 0) { // It's a Spade
   curr_numb = game->player_number(player, i);
   // If it's a King, store the King's spot
   if (curr_numb == 13) {
   has_AKsp = true; // Has one of them
   Ksp_slot = i; // Store the spot
   // If it's an Ace, store the Ace's spot
   } else if (curr_numb == 14) {
   has_AKsp = true; // Has one of them
   Asp_slot = i; // Store the spot
   }
   }
  }

  // Doesn't have either, cya
  if (!has_AKsp) return 13;

  // Check if someone played the Ace of Spades, if so, play the King
  for (u8 i = 0; i < 4; ++i) {
   if (game->trick_number(i) == 14 && game->trick_suit(i) == 0) {
   if (Ksp_slot != 13) {
   return Ksp_slot;
   }
   }
  }

  // Check if someone played the Queen of Spades
  for (u8 i = 0; i < 4; ++i) {
   if (game->trick_number(i) == 12 && game->trick_suit(i) == 0) return 13;
  }

  // Check if the player has a lower Spade
  if (lowest_of_suit(game, player, 0) != Ksp_slot) return 13;

  // If three trick cards have been played, then discard either the Ace or King
  if (trick_cards == 3) {
   if (Asp_slot != 13) return Asp_slot;
   if (Ksp_slot != 13) return Ksp_slot;
  }

  // If the player has the Queen of Spades, get rid of an Ace or King first
  if (Queen_of_Spades(game, player) != 13) {
   if (Asp_slot != 13) return Asp_slot;
   if (Ksp_slot != 13) return Ksp_slot;
  }

  return 13;
}


//*******************************************
// Function: play_Qsp()
// Purpose: Determine if should play
// the Queen of Spades. Returns the
// slot if so or 13 if not.
//*******************************************
u8 play_Qsp(HEARTS *game, u8 player)
{
  // Variables
  bool Qsp = false;
  u8 Qsp_slot = Queen_of_Spades(game, player);

  // If they don't have it, they can't play it
  if (Qsp_slot == 13) return 13;

  // Otherwise, note if the Ace or King of Spades has been played
  for (u8 i = 0; i < 4; ++i) {
   if (game->trick_suit(i) == 0) { // Search the trick card for Spades
   if (game->trick_number(i) == 13 || game->trick_number(i) == 14) { // And the Ace or King
   Qsp = true; // A or K has been played, we can play the Queen
   }
   }
  }

  // If the Ace or King of Spades was played
  if (Qsp) {
   return Qsp_slot; // Then return the Queen's spot
  } else {
   return 13; // Otherwise, don't play the Queen
  }
} // End of play_Qsp()