//*****************************************
// Filename: game.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
//*****************************************
// Library Includes
#include "ai.h"
#include "game.h"
#include "splash.h"
// -- Graphics --
// Backgrounds
#include "gfx/ham_tut.map.c" // gfx2gba -fsrc -m -pham_tut.pal -t8 ham_tut.bmp
#include "gfx/ham_tut.pal.c"
#include "gfx/ham_tut.raw.c"
#include "gfx/hearts.map.c" // gfx2gba -fsrc -m -phearts.pal -t8 hearts.bmp
#include "gfx/hearts.pal.c"
#include "gfx/hearts.raw.c"
#include "gfx/board.map.c" // gfx2gba -fsrc -m -pboard.pal -t8 board.bmp
#include "gfx/board.pal.c"
#include "gfx/board.raw.c"
#include "gfx/main_menu.pal.c" // Generated from all of the main_menu bitmaps
#include "gfx/main_menu_op.raw.c" // gfx2gba -D -fsrc -pmain_menu.pal -t1 -a34 *.bmp
#include "gfx/main_menu_qg.raw.c" // gfx2gba -D -fsrc -pmain_menu.pal -t1 -a34 *.bmp
#include "gfx/main_menu_rg.raw.c" // gfx2gba -D -fsrc -pmain_menu.pal -t1 -a34 *.bmp
#include "gfx/options.pal.c" // Generated from all of the options bitmaps
#include "gfx/options_sl.raw.c" // gfx2gba -a34 -D -fsrc -poptions.pal -t1 *.bmp
#include "gfx/options_so.raw.c" // gfx2gba -a34 -D -fsrc -poptions.pal -t1 *.bmp
#include "gfx/options_mu.raw.c" // gfx2gba -a34 -D -fsrc -poptions.pal -t1 *.bmp
#include "gfx/score.pal.c" // gfx2gba -a34 -fsrc -m -pscore.pal -t8 score.bmp
#include "gfx/score.map.c" // gfx2gba -a34 -fsrc -m -pscore.pal -t8 score.bmp
#include "gfx/score.raw.c" // gfx2gba -a34 -fsrc -m -pscore.pal -t8 score.bmp
#include "gfx/game_over.pal.c" // Generated from all of the game_over bitmaps
#include "gfx/game_over_p1.map.c" // gfx2gba -fsrc -m -t8 *.bmp
#include "gfx/game_over_p1.raw.c"
#include "gfx/game_over_p2.map.c" // gfx2gba -fsrc -m -t8 *.bmp
#include "gfx/game_over_p2.raw.c"
#include "gfx/game_over_p3.map.c" // gfx2gba -fsrc -m -t8 *.bmp
#include "gfx/game_over_p3.raw.c"
#include "gfx/game_over_p4.map.c" // gfx2gba -fsrc -m -t8 *.bmp
#include "gfx/game_over_p4.raw.c"
#include "gfx/game_over_tie.map.c" // gfx2gba -fsrc -m -t8 *.bmp
#include "gfx/game_over_tie.raw.c"
// Sprites
#include "gfx/in_game_objects.pal.c" // Generated (separately) from the following sprites
#include "gfx/card_back.raw.c" // gfx2gba -D -fsrc -pin_game_objects.pal -t8 *.bmp
#include "gfx/card_deck.raw.c" // gfx2gba -D -fsrc -pin_game_objects.pal -t8 *.bmp
#include "gfx/card_deck_64.raw.c" // gfx2gba -D -fsrc -pin_game_objects.pal -t8 *.bmp
#include "gfx/card_deck_grey.raw.c" // gfx2gba -D -fsrc -pin_game_objects.pal -t8 *.bmp
#include "gfx/card_deck_orange.raw.c" // gfx2gba -D -fsrc -pin_game_objects.pal -t8 *.bmp
#include "gfx/go.raw.c" // gfx2gba -D -fsrc -pin_game_objects.pal -t8 *.bmp
#include "gfx/pass_across.raw.c" // gfx2gba -D -fsrc -pin_game_objects.pal -t8 *.bmp
#include "gfx/pass_left.raw.c" // gfx2gba -D -fsrc -pin_game_objects.pal -t8 *.bmp
#include "gfx/pass_right.raw.c" // gfx2gba -D -fsrc -pin_game_objects.pal -t8 *.bmp
#include "gfx/options_sprites.pal.c" // Generated (separately) from the following sprites
#include "gfx/op_1.raw.c" // gfx2gba -D -fsrc -t8 op_1.bmp
#include "gfx/op_2.raw.c" // gfx2gba -D -fsrc -t8 op_2.bmp
#include "gfx/op_3.raw.c" // gfx2gba -D -fsrc -t8 op_3.bmp
#include "gfx/on.raw.c" // gfx2gba -D -fsrc -t8 on.bmp
#include "gfx/off.raw.c" // gfx2gba -D -fsrc -t8 off.bmp
#include "gfx/numbers_new.pal.c" // gfx2gba -D -fsrc -pnumbers_new.pal -t8 numbers_new.bmp
#include "gfx/numbers_new.raw.c" // gfx2gba -D -fsrc -pnumbers_new.pal -t8 numbers_new.bmp
//*****************************
// Function: HEARTS::HEARTS()
// Purpose: Default Constructor
//*****************************
HEARTS::HEARTS()
{
// Set the game state to START
game_state = START; // *** Should be START ***
// Seed the random function only once
seed = true;
} // End of HEARTS::HEARTS()
//*****************************
// Function: HEARTS::init()
// Purpose: Initialize the game
//*****************************
void HEARTS::init()
{
// Initialize HAMlib
ham_Init();
// Setup the background mode
ham_SetBgMode(1);
// Set the number of players to 1
players = 1;
// Set the skill level to 2
skill = 2;
// Turn the sound off at first
sound = 0;
// Turn the music off at first
music = 0;
// Setup the 64 pixel card pointer
big_card = false;
return;
} // End of HEARTS::init()
//*****************************************
// Function: HEARTS::start_screen_init()
// Purpose: Initialize the start screen
//*****************************************
void HEARTS::start_screen_init()
{
// Set the tileset for the 'HAM Tutorial' screen
ham_bg[0].ti = ham_InitTileSet((void *)ham_tut_Tiles,
SIZEOF_16BIT(ham_tut_Tiles),1,1);
ham_bg[0].mi = ham_InitMapSet((void *)ham_tut_Map,1024,0,0);
// Display the background
ham_InitBg(0,1,0,0);
// Used for the fading backgrounds
CSplash *ham_tut_Splash = new CSplash;
// Fade in the 'HAM Tutorial' screen
ham_tut_Splash->Init();
//ham_tut_Splash->SetTexture((u8*)ham_tut_Bitmap);
ham_tut_Splash->SetPalette((u16*)ham_tut_Palette);
ham_tut_Splash->SetFadeSpeed(3);
ham_tut_Splash->FadeIn();
ham_tut_Splash->WaitFrames(100*64);
ham_tut_Splash->FadeOut();
ham_tut_Splash->WaitFrames(100*16);
// Deinitialize the background
ham_DeInitBg(0);
// Set the tileset for the 'Hearts' screen
ham_bg[0].ti = ham_InitTileSet((void *)hearts_Tiles,
SIZEOF_16BIT(hearts_Tiles),1,1);
ham_bg[0].mi = ham_InitMapSet((void *)hearts_Map,1024,0,0);
// Display the background
ham_InitBg(0,1,0,0);
// Used for the fading backgrounds
CSplash *hearts_Splash = new CSplash;
// Fade in 'Hearts' screen
hearts_Splash->Init();
//hearts_Splash->SetTexture((u8*)hearts_Bitmap);
hearts_Splash->SetPalette((u16*)hearts_Palette);
hearts_Splash->SetFadeSpeed(3);
hearts_Splash->FadeIn();
hearts_Splash->WaitFrames(100*64);
hearts_Splash->FadeOut();
hearts_Splash->WaitFrames(100*16);
// Change the game state
game_state = MAIN; // *** should be main ***
return;
} // End of HEARTS::start_screen_init()
//********************************************
// Function: HEARTS::start_screen_query_keys()
// Purpose: Gets input during start_screen()
//********************************************
void HEARTS::start_screen_query_keys()
{
return;
} // End of HEARTS::start_screen_query_keys()
//*******************************************
// Function: HEARTS::start_screen_deinit()
// Purpose: Deinitialize the start screen
//*******************************************
void HEARTS::start_screen_deinit()
{
// Deinitialize the background
ham_DeInitBg(0);
return;
} // End of HEARTS::start_screen_deinit()
//****************************************
// Function: HEARTS::main_screen_init()
// Purpose: Initialize the main screen
//****************************************
void HEARTS::main_screen_init()
{
// Setup the background mode
ham_SetBgMode(4);
// Setup variables to keep track of screens
curr_screen = 0;
last_screen = 0;
// Of course, no one wins right away
winner = 4;
// Set the round to zero
round = 0; // *** increment at the end of a game ***
// Set everyone's score to 0
for (u8 i = 0; i < 4; ++i) Total_Score[i] = 0;
// Start the VBL counter at 0
vbl_count = 0;
// Initialize the background palette
ham_LoadBGPal((void *)main_menu_Palette,256);
// Display the image
TOOL_DMA1_SET(&main_menu_qg_Bitmap,
MEM_BG_PTR,SIZEOF_32BIT(main_menu_qg_Bitmap),
DMA_TRANSFER_32BIT,
DMA_STARTAT_NOW);
return;
} // End of HEARTS::main_screen_init()
//**********************************************
// Function: HEARTS::main_screen_query_keys()
// Purpose: Gets input during main_screen()
//**********************************************
void HEARTS::main_screen_query_keys()
{
// Increment the VBL counter every VBL
++vbl_count;
// START or A button
if (vbl_count > 10 && (F_CTRLINPUT_START_PRESSED || F_CTRLINPUT_A_PRESSED)) {
// See if we seeded the random function or not
if (!seed) {
// Keep calling random to keep things random
flash_count = rand()%1000;
} else {
// No need to seed anymore
seed = false;
// Seed the random function
srand(vbl_count);
}
// Make sure to do this after seeding the random function
vbl_count = 0;
// Change the game state
if (curr_screen == 0) { // Quick Game
game_state = PLAY;
// Reset everything
ham_Init();
} else if (curr_screen == 1) { // Regular Game
} else if (curr_screen == 2) { // Options screen
game_state = OPTIONS;
}
}
// UP
if (vbl_count > 10 && F_CTRLINPUT_UP_PRESSED) {
vbl_count = 0;
last_screen = curr_screen;
if (curr_screen == 0) {
curr_screen = 2;
} else {
--curr_screen;
}
}
// DOWN
if (vbl_count > 10 && F_CTRLINPUT_DOWN_PRESSED) {
vbl_count = 0;
last_screen = curr_screen;
if (curr_screen == 2) {
curr_screen = 0;
} else {
++curr_screen;
}
}
return;
} // End of HEARTS::main_screen_query_keys()
//************************************************
// Function: HEARTS::main_screen_redraw()
// Purpose: Redraw the screen during main_screen()
//************************************************
void HEARTS::main_screen_redraw()
{
// See if changes were made
if (last_screen != curr_screen) {
if (curr_screen == 0) {
// Display the image
TOOL_DMA1_SET(&main_menu_qg_Bitmap,
MEM_BG_PTR,SIZEOF_32BIT(main_menu_qg_Bitmap),
DMA_TRANSFER_32BIT,
DMA_STARTAT_NOW);
} else if (curr_screen == 1) {
// Display the image
TOOL_DMA1_SET(&main_menu_rg_Bitmap,
MEM_BG_PTR,SIZEOF_32BIT(main_menu_rg_Bitmap),
DMA_TRANSFER_32BIT,
DMA_STARTAT_NOW);
} else if (curr_screen == 2) {
// Display the image
TOOL_DMA1_SET(&main_menu_op_Bitmap,
MEM_BG_PTR,SIZEOF_32BIT(main_menu_op_Bitmap),
DMA_TRANSFER_32BIT,
DMA_STARTAT_NOW);
}
last_screen = curr_screen; // Set them equal - this means there was no input change
}
return;
} // End of HEARTS::main_screen_redraw()
//******************************************
// Function: HEARTS::main_screen_deinit()
// Purpose: Deinitialize the main screen
//******************************************
void HEARTS::main_screen_deinit()
{
return;
} // End of HEARTS::main_screen_deinit()
//************************************
// Function: HEARTS::in_game_init()
// Purpose: Initialize game playing
//************************************
void HEARTS::in_game_init()
{
// Setup the background mode
ham_SetBgMode(1);
// Start the VBL counter at 0
vbl_count = 0;
flash_count = 0;
// Used to cycle through the deck
deck_spot = 0;
// Start the pointer on the first card
my_pnt_card = 0;
// In round 3, no cards need to be selected to pass
if (round != 3) {
pass_three = 0;
} else {
pass_three = 5;
}
// If it's not the fourth ruond, the first stage
// of a trick is passing three cards
if (round != 3) {
choose_three = true;
} else {
choose_three = false;
}
// Setup the first trick
first_trick = true;
// This is false until a Heart is played
hearts_broken = false;
// There are no cards played yet
trick_cards = 0;
// Start off on the first trick
tricks = 1;
// Setup the four trick cards locations
T[0].x_pos = 100; // Player 1
T[0].y_pos = 82;
T[1].x_pos = 65; // Player 2
T[1].y_pos = 62;
T[2].x_pos = 100; // Player 3
T[2].y_pos = 42;
T[3].x_pos = 136; // Player 4
T[3].y_pos = 62;
// Setup the locations for the 'pass xxx'/'go' sprites
pass_xxx[0].x_pos = 87;
pass_xxx[0].y_pos = 47;
// Create the 'pass_xxx'/'go' sprite right away
create_pass_xxx = true;
delete_go = false;
flash_pass_xxx = 0; // Flashing off
flash_go = 0; // Flashing off
// Set all the cards to blank
for (u8 i = 0; i < 4; ++i) {
Trick[i].number = 0;
Trick[i].suit = 0;
}
// Set everyone's hand score to 0
for (u8 i = 0; i < 4; ++i) {
Hand_Score[i] = 0;
}
// Make sure Passed_Cards[] is empty
for (u8 i = 0; i < 12; ++i) {
Passed_Cards[i] = 13;
}
// Setup the deck of cards
// Go through and initialize the deck to empty
for (u8 i = 0; i < 52; ++i) {
Deck[i].number = 0;
Deck[i].suit = 0;
}
// Setup a temporary deck
Card Temp_Deck[52];
// Fill in the temporary deck first
u8 n = 2; // Number (2 - 14)
u8 s = 0; // Suit (0 - 3)
for (u8 i = 0; i < 52; ++i) {
Temp_Deck[i].number = n;
Temp_Deck[i].suit = s;
++n;
if (n == 15) {
n = 2; // Cards must be 2 - 14
++s; // After the Ace, increment the suit
}
//if (s == 4) s = 0; // The suit must be 0 - 3
}
// Randomly move the cards into the actual deck
u8 spot;
for (u8 i = 0; i < 52; ++i) {
// Get a random spot in the deck
spot = rand()%52;
// Make sure the spot is open
while (Deck[spot].number != 0) {
++spot; // Otherwise move to the next spot
if (spot == 52) spot = 0;
}
// Copy the card to the open spot
Deck[spot].number = Temp_Deck[i].number;
Deck[spot].suit = Temp_Deck[i].suit;
}
// Setup the hand for each player
for (u8 i = 0; i < 13; ++i) {
Player1[i].number = Deck[i].number; // The card number (2-14)
Player1[i].suit = Deck[i].suit; // The card suit (0-3)
Player2[i].number = Deck[(i+13)].number;
Player2[i].suit = Deck[(i+13)].suit;
Player3[i].number = Deck[(i+26)].number;
Player3[i].suit = Deck[(i+26)].suit;
Player4[i].number = Deck[(i+39)].number;
Player4[i].suit = Deck[(i+39)].suit;
}
// Sort the hands
hand_sort(1);
hand_sort(2);
hand_sort(3);
hand_sort(4);
// Get computer players ready to pass cards
if (players == 1 && round != 3) {
ai_setup_passed_cards(this, skill);
}
// Initialize the background and sprites palettes
ham_LoadBGPal((void *)board_Palette,256);
ham_LoadObjPal((void *)in_game_objects_Palette,256);
// Setup the tileset for our image
ham_bg[0].ti = ham_InitTileSet((void *)board_Tiles,
SIZEOF_16BIT(board_Tiles),1,1);
// Setup the map for our image
ham_bg[0].mi = ham_InitMapEmptySet(3,0);
bg_one = ham_InitMapFragment((void *)board_Map,30,20,0,0,30,20,0);
ham_InsertMapFragment(bg_one,0,0,0);
// Display the background
ham_InitBg(0,1,3,0);
// Larger version of the card used as a pointer
Card_64[0].x_pos = 40; // 209
Card_64[0].y_pos = 140; // 134
graphic_spot = convert_card_64(Player1[0].number, Player1[0].suit);
Card_64[0].slot = ham_CreateObj((void *)&card_deck_64_Bitmap[graphic_spot],0,3,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,Card_64[0].x_pos,Card_64[0].y_pos);
// Hide it if necessary
if (!big_card) {
ham_SetObjVisible(Card_64[0].slot, 0);
}
// Setup the graphics for all four players' cards
for (u8 i = 0; i < 13; ++i) {
P1[i].x_pos = 40 + (i)*10;
P1[i].y_pos = 121;
graphic_spot = convert_card(Player1[i].number, Player1[i].suit);
P1[i].slot = ham_CreateObj((void *)&card_deck_Bitmap[graphic_spot],0,2,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,P1[i].x_pos,P1[i].y_pos);
// Swap the sprite priorities
if (i > 0) {
ham_SetObjBefore(P1[i].slot, P1[i-1].slot);
}
P2[i].x_pos = 5;
P2[i].y_pos = 2 + (i)*10;
P3[i].x_pos = 40 + (i)*10;
P3[i].y_pos = 2;
P4[i].x_pos = 200;
P4[i].y_pos = 2 + (i)*10;
if (i == 0) {
P2[0].slot = ham_CreateObj((void *)&card_back_Bitmap[0],0,2,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,P2[0].x_pos,P2[0].y_pos);
P3[0].slot = ham_CreateObj((void *)&card_back_Bitmap[0],0,2,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,P3[0].x_pos,P3[0].y_pos);
P4[0].slot = ham_CreateObj((void *)&card_back_Bitmap[0],0,2,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,P4[0].x_pos,P4[0].y_pos);
} else {
P2[i].slot = ham_CloneObj(P2[0].slot,P2[i].x_pos,P2[i].y_pos);
P3[i].slot = ham_CloneObj(P2[0].slot,P3[i].x_pos,P3[i].y_pos);
P4[i].slot = ham_CloneObj(P2[0].slot,P4[i].x_pos,P4[i].y_pos);
// Swap the sprite priorities
ham_SetObjBefore(P4[i].slot, P4[i-1].slot);
}
}
// Swap the image of the first card (to make it grey)
graphic_spot = convert_card(Player1[0].number, Player1[0].suit);
ham_UpdateObjGfx(P1[0].slot,(void *)&card_deck_grey_Bitmap[graphic_spot]);
// In the fourth round no cards are passed so we need to
// figure out who goes first ahead of time
if (round == 3) {
setup_leader();
turn = leader;
}
return;
} // End of HEARTS::in_game_init()
//******************************************
// Function: HEARTS::in_game_query_keys()
// Purpose: Gets input during in_game()
//******************************************
void HEARTS::in_game_query_keys()
{
// Increment the VBL counter every VBL
++vbl_count;
// Increment the counter to flash sprites
if (flash_pass_xxx != 0 || flash_go != 0) ++flash_count;
// Create the 'pass_xxx' sprite
// Pass left
if ((round == 0) && (pass_three < 3) && (create_pass_xxx)) {
create_pass_xxx = false;
flash_pass_xxx = 1; // Start flashing
pass_xxx[0].slot = ham_CreateObj((void *)&pass_left_Bitmap[0],0,3,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,pass_xxx[0].x_pos,pass_xxx[0].y_pos);
} else if ((round == 0) && (pass_three == 3)) {
//ham_SetObjVisible(pass_xxx[0].slot, 1);
ham_DeleteObj(pass_xxx[0].slot); // Delete the 'pass_xxx' sprite
flash_pass_xxx = 0; // Stop flashing
// Pass right
} else if ((round == 1) && (pass_three < 3) && (create_pass_xxx)) {
create_pass_xxx = false;
flash_pass_xxx = 1; // Start flashing
pass_xxx[0].slot = ham_CreateObj((void *)&pass_right_Bitmap[0],0,3,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,pass_xxx[0].x_pos,pass_xxx[0].y_pos);
} else if ((round == 1) && (pass_three == 3)) {
//ham_SetObjVisible(pass_xxx[0].slot, 1);
ham_DeleteObj(pass_xxx[0].slot); // Delete the 'pass_xxx' sprite
flash_pass_xxx = 0; // Stop flashing
// Pass Across
} else if ((round == 2) && (pass_three < 3) && (create_pass_xxx)) {
create_pass_xxx = false;
flash_pass_xxx = 1; // Start flashing
pass_xxx[0].slot = ham_CreateObj((void *)&pass_across_Bitmap[0],0,3,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,pass_xxx[0].x_pos,pass_xxx[0].y_pos);
} else if ((round == 2) && (pass_three == 3)) {
// ham_SetObjVisible(pass_xxx[0].slot, 1);
ham_DeleteObj(pass_xxx[0].slot); // Delete the 'pass_xxx' sprite
flash_pass_xxx = 0; // Stop flashing
}
// Flash the 'pass_xxx' srite on or off
if ((flash_count%20 == 0) && (flash_pass_xxx != 0)) { // Every 20 frames
if (flash_pass_xxx == 1) { // Flash on
flash_pass_xxx = 2; // Flash off next time
ham_SetObjVisible(pass_xxx[0].slot, 1);
} else if (flash_pass_xxx == 2) { // Flash off
flash_pass_xxx = 1; // Flash on next time
ham_SetObjVisible(pass_xxx[0].slot, 0);
}
}
// If it's the fourth round and Player 1 has the 2 of Clubs, create the 'Go!' sprite
if (round == 3 && first_trick && trick_cards == 0 && leader == 1 && !delete_go) {
flash_go = 1;
delete_go = true;
pass_xxx[0].slot = ham_CreateObj((void *)&go_Bitmap[0],0,3,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,pass_xxx[0].x_pos,pass_xxx[0].y_pos);
}
// Flash the 'Go!' srite on or off
if ((flash_count%20 == 0) && (flash_go != 0)) { // Every 20 frames
if (flash_go == 1) { // Flash on
flash_go = 2; // Flash off next time
ham_SetObjVisible(pass_xxx[0].slot, 1);
} else if (flash_go == 2) { // Flash off
flash_go = 1; // Flash on next time
ham_SetObjVisible(pass_xxx[0].slot, 0);
}
}
// SELECT
if (vbl_count > 5 && F_CTRLINPUT_SELECT_PRESSED) {
vbl_count = 0;
game_state = START; // Restart the entire HEARTS game
return;
}
// One player version of input check
if (choose_three || pass_three == 4 || turn == 1) {
// START
if (vbl_count > 10 && F_CTRLINPUT_START_PRESSED) {
vbl_count = 0;
if (first_trick && pass_three == 3) {
// Pass the cards
pass_cards();
// Save the card that came into the spots that you passed out
Card temp_passed[3];
temp_passed[0].number = Player1[Passed_Cards[0]].number;
temp_passed[0].suit = Player1[Passed_Cards[0]].suit;
temp_passed[1].number = Player1[Passed_Cards[1]].number;
temp_passed[1].suit = Player1[Passed_Cards[1]].suit;
temp_passed[2].number = Player1[Passed_Cards[2]].number;
temp_passed[2].suit = Player1[Passed_Cards[2]].suit;
// Sort the hand
hand_sort(1);
// Update the graphic for the card in the corner
graphic_spot = convert_card_64(Player1[0].number, Player1[0].suit);
ham_UpdateObjGfx(Card_64[0].slot,(void *)&card_deck_64_Bitmap[graphic_spot]);
Card_64[0].x_pos = P1[0].x_pos;
ham_SetObjX(Card_64[0].slot, Card_64[0].x_pos);
// Find the cards in their new spots
for (u8 i = 0; i < 13; ++i) {
// Move all of the cards down at first
P1[i].y_pos = 121;
ham_SetObjY(P1[i].slot,P1[i].y_pos);
// Update the graphics for every card
graphic_spot = convert_card(Player1[i].number, Player1[i].suit);
ham_UpdateObjGfx(P1[i].slot,(void *)&card_deck_Bitmap[graphic_spot]);
if (Player1[i].number == temp_passed[0].number && Player1[i].suit == temp_passed[0].suit) {
// Move the card up if it matches
P1[i].y_pos = 110;
ham_SetObjY(P1[i].slot,P1[i].y_pos);
} else if (Player1[i].number == temp_passed[1].number && Player1[i].suit == temp_passed[1].suit) {
// Move the card up if it matches
P1[i].y_pos = 110;
ham_SetObjY(P1[i].slot,P1[i].y_pos);
} else if (Player1[i].number == temp_passed[2].number && Player1[i].suit == temp_passed[2].suit) {
// Move the card up if it matches
P1[i].y_pos = 110;
ham_SetObjY(P1[i].slot,P1[i].y_pos);
}
}
// Done choosing three cards
choose_three = false;
// Using pass_three as a temp variable
++pass_three;
} else if (first_trick && pass_three == 4) {
// Update the graphics for all of the cards
for (u8 i = 0; i < 13; ++i) {
// Make sure all of the cards are moved down
P1[i].y_pos = 121;
ham_SetObjY(P1[i].slot,P1[i].y_pos);
}
// Move my_pnt_card back to the first spot
my_pnt_card = 0;
// Swap the image of the first card (to make it grey)
graphic_spot = convert_card(Player1[0].number, Player1[0].suit);
ham_UpdateObjGfx(P1[0].slot,(void *)&card_deck_grey_Bitmap[graphic_spot]);
// Decide who leads first
setup_leader();
// Create the 'go' sprite
if (first_trick && leader == 1) {
flash_go = 1;
delete_go = true;
pass_xxx[0].slot = ham_CreateObj((void *)&go_Bitmap[0],0,3,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,pass_xxx[0].x_pos,pass_xxx[0].y_pos);
}
// To start the trick, turn = leader
turn = leader;
// Increment pass_three so it will no longer be processed
++pass_three;
}
}
// RIGHT only
if(vbl_count > 5 && F_CTRLINPUT_RIGHT_PRESSED && pass_three != 4) {
vbl_count = 0;
if (Player1[my_pnt_card].number != 0) {
// Change the current card to white
graphic_spot = convert_card(Player1[my_pnt_card].number, Player1[my_pnt_card].suit);
ham_UpdateObjGfx(P1[my_pnt_card].slot,(void *)&card_deck_Bitmap[graphic_spot]);
// Then move the card one to the right
if (my_pnt_card != 12) {
++my_pnt_card;
} else {
my_pnt_card = 0;
}
}
// Move the pointer to a valid spot
while (Player1[my_pnt_card].number == 0) {
if (my_pnt_card != 12) {
++my_pnt_card;
} else {
my_pnt_card = 0;
}
}
// Change the new card to grey
graphic_spot = convert_card(Player1[my_pnt_card].number, Player1[my_pnt_card].suit);
ham_UpdateObjGfx(P1[my_pnt_card].slot,(void *)&card_deck_grey_Bitmap[graphic_spot]);
// Update the graphic for the card in the corner
Card_64[0].x_pos = P1[my_pnt_card].x_pos;
ham_SetObjX(Card_64[0].slot, P1[my_pnt_card].x_pos);
graphic_spot = convert_card_64(Player1[my_pnt_card].number, Player1[my_pnt_card].suit);
ham_UpdateObjGfx(Card_64[0].slot,(void *)&card_deck_64_Bitmap[graphic_spot]);
}
// LEFT only
if(vbl_count > 5 && F_CTRLINPUT_LEFT_PRESSED && pass_three != 4) {
vbl_count = 0;
if (Player1[my_pnt_card].number != 0) {
// Change the current card to white
graphic_spot = convert_card(Player1[my_pnt_card].number, Player1[my_pnt_card].suit);
ham_UpdateObjGfx(P1[my_pnt_card].slot,(void *)&card_deck_Bitmap[graphic_spot]);
// Then move the card one to the left
if (my_pnt_card != 0) {
--my_pnt_card;
} else {
my_pnt_card = 12;
}
}
// Move the pointer to a valid spot
while (Player1[my_pnt_card].number == 0) {
if (my_pnt_card != 0) {
--my_pnt_card;
} else {
my_pnt_card = 12;
}
}
// Change the new card to grey
graphic_spot = convert_card(Player1[my_pnt_card].number, Player1[my_pnt_card].suit);
ham_UpdateObjGfx(P1[my_pnt_card].slot,(void *)&card_deck_grey_Bitmap[graphic_spot]);
// Update the graphic for the card in the corner
Card_64[0].x_pos = P1[my_pnt_card].x_pos;
ham_SetObjX(Card_64[0].slot, P1[my_pnt_card].x_pos);
graphic_spot = convert_card_64(Player1[my_pnt_card].number, Player1[my_pnt_card].suit);
ham_UpdateObjGfx(Card_64[0].slot,(void *)&card_deck_64_Bitmap[graphic_spot]);
}
// A Button
if (vbl_count > 10 && F_CTRLINPUT_A_PRESSED) {
vbl_count = 0;
// Check whether it's the first phase of a trick - passing three cards
if (choose_three) {
// Move the card up & get it ready to pass
if ((P1[my_pnt_card].y_pos == 121) && (pass_three < 3)) {
P1[my_pnt_card].y_pos = 110; // Move up
Passed_Cards[pass_three] = my_pnt_card;
++pass_three; // Increment the 'cards chosen' counter
// Move the card down, don't pass that card
} else if (P1[my_pnt_card].y_pos == 110) {
P1[my_pnt_card].y_pos = 121; // Move down
--pass_three; // Decrement the 'cards chosen' counter
for (u8 i = 0; i < 3; ++i) {
if (Passed_Cards[i] == my_pnt_card) {
u8 j = i;
while (j != 2) {
Passed_Cards[j] = Passed_Cards[j+1];
++j;
}
Passed_Cards[2] = 13;
}
}
}
ham_SetObjY(P1[my_pnt_card].slot,P1[my_pnt_card].y_pos);
} else { // Otherwise, try to play the card
if (turn == 1 && trick_cards != 4) {
// Move that card into the trick
if (!first_trick || trick_cards != 0 ||
(first_trick && Player1[my_pnt_card].number == 2 // 2 of Clubs
&& Player1[my_pnt_card].suit == 1)) {
// Add the card to Trick[] if it is a valid card
if ((Player1[my_pnt_card].number != 0) && valid_move(1, my_pnt_card)) {
// Delete the 'go' sprite
if (delete_go) {
flash_go = 0; // Don't flash 'go' sprite anymore
delete_go = false; // Don't try to delete 'go' sprite anymore
ham_DeleteObj(pass_xxx[0].slot); // Delete the 'go' sprite
}
// Move the card into the trick
add_card_to_trick(my_pnt_card);
// If it is a Heart, make sure we know Hearts have been broken
if ((!hearts_broken) && (Trick[0].suit == 2)) hearts_broken = true;
// Move the card up
graphic_spot = convert_card(Trick[0].number, Trick[0].suit);
if (Trick[0].suit == 2 || (Trick[0].number == 12 && Trick[0].suit == 0)) {
T[0].slot = ham_CreateObj((void *)&card_deck_orange_Bitmap[graphic_spot],0,2,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,T[0].x_pos,T[0].y_pos);
} else {
T[0].slot = ham_CreateObj((void *)&card_deck_Bitmap[graphic_spot],0,2,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,T[0].x_pos,T[0].y_pos);
}
// Hide the old card location
ham_DeleteObj(P1[my_pnt_card].slot);
// Remove the old card's info
remove_card(1, my_pnt_card);
// If Player 1 lead, setup suit_lead
if (leader == 1) {
suit_lead = Trick[0].suit;
}
// Increment turn
if (turn == 4) {
turn = 1;
} else {
++turn;
}
// Increment trick_cards
++trick_cards;
// Move the card to a new spot
if (tricks != 13) {
if (my_pnt_card == 12) {
my_pnt_card = 0;
} else {
++my_pnt_card;
}
// If it's empty, keep it moving
while (Player1[my_pnt_card].number == 0) {
if (my_pnt_card == 12) {
my_pnt_card = 0;
} else {
++my_pnt_card;
}
}
// Change the new card to grey
graphic_spot = convert_card(Player1[my_pnt_card].number, Player1[my_pnt_card].suit);
ham_UpdateObjGfx(P1[my_pnt_card].slot,(void *)&card_deck_grey_Bitmap[graphic_spot]);
// Update the graphic for the card in the corner
Card_64[0].x_pos = P1[my_pnt_card].x_pos;
ham_SetObjX(Card_64[0].slot, P1[my_pnt_card].x_pos);
graphic_spot = convert_card_64(Player1[my_pnt_card].number, Player1[my_pnt_card].suit);
ham_UpdateObjGfx(Card_64[0].slot,(void *)&card_deck_64_Bitmap[graphic_spot]);
}
}
}
}
}
} // End of A Button
// B Button
if (vbl_count > 10 && F_CTRLINPUT_B_PRESSED) {
vbl_count = 0;
if (!big_card) {
// Update the graphic for the card in the corner
Card_64[0].x_pos = P1[my_pnt_card].x_pos;
ham_SetObjX(Card_64[0].slot, P1[my_pnt_card].x_pos);
graphic_spot = convert_card_64(Player1[my_pnt_card].number, Player1[my_pnt_card].suit);
ham_UpdateObjGfx(Card_64[0].slot,(void *)&card_deck_64_Bitmap[graphic_spot]);
ham_SetObjVisible(Card_64[0].slot, 1);
big_card = true;
} else if (big_card) {
ham_SetObjVisible(Card_64[0].slot, 0);
big_card = false;
}
}
} else if (turn != 1 && trick_cards != 4) {
// Have the computer pick a card to play
ai_card = ai_choose_card(this, skill);
// Move that card into the trick
add_card_to_trick(ai_card);
// Hide the old card location // *** not sure about this ***
if (turn == 2) {
ham_DeleteObj(P2[ai_card].slot);
}
if (turn == 3) {
ham_DeleteObj(P3[ai_card].slot);
}
if (turn == 4) {
ham_DeleteObj(P4[ai_card].slot);
}
// Update sprites
ham_CopyObjToOAM();
// If it is a Heart, make sure we know Hearts have been broken
if ((!hearts_broken) && (Trick[turn-1].suit == 2)) hearts_broken = true;
// Move the card up
graphic_spot = convert_card(Trick[turn-1].number, Trick[turn-1].suit);
if (Trick[turn-1].suit == 2 || (Trick[turn-1].number == 12 && Trick[turn-1].suit == 0)) {
T[turn-1].slot = ham_CreateObj((void *)&card_deck_orange_Bitmap[graphic_spot],0,2,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,T[turn-1].x_pos,T[turn-1].y_pos);
} else {
T[turn-1].slot = ham_CreateObj((void *)&card_deck_Bitmap[graphic_spot],0,2,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,T[turn-1].x_pos,T[turn-1].y_pos);
}
// Remove that card from players hand
remove_card(turn, ai_card);
// Setup suit_lead to match the first card lead
if (leader == turn) {
suit_lead = Trick[turn-1].suit;
}
// Increment turn
if (turn == 4 && trick_cards != 3) {
turn = 1;
} else {
++turn;
}
// Increment trick_cards
++trick_cards;
// Move Player1's pointer to a card that is of the same suit as suit lead
if (trick_cards == 1 && Player1[my_pnt_card].suit != suit_lead) {
u8 suit_slot = 0;
// Loop through Player1's cards
while (suit_slot != 13) {
// Player1 has the suit, stop looking
if ((Player1[suit_slot].number != 0) && (Player1[suit_slot].suit == suit_lead)) {
break;
}
// Otherwise move to the next card
++suit_slot;
}
// If suit_slot is not 13, then they have the suit
if (suit_slot != 13) {
// Change the current card to white
graphic_spot = convert_card(Player1[my_pnt_card].number, Player1[my_pnt_card].suit);
ham_UpdateObjGfx(P1[my_pnt_card].slot,(void *)&card_deck_Bitmap[graphic_spot]);
// Move the pointer
my_pnt_card = suit_slot;
// Change the new card to grey
graphic_spot = convert_card(Player1[my_pnt_card].number, Player1[my_pnt_card].suit);
ham_UpdateObjGfx(P1[my_pnt_card].slot,(void *)&card_deck_grey_Bitmap[graphic_spot]);
// Update the graphic for the card in the corner
Card_64[0].x_pos = P1[my_pnt_card].x_pos;
ham_SetObjX(Card_64[0].slot, P1[my_pnt_card].x_pos);
graphic_spot = convert_card_64(Player1[my_pnt_card].number, Player1[my_pnt_card].suit);
ham_UpdateObjGfx(Card_64[0].slot,(void *)&card_deck_64_Bitmap[graphic_spot]);
}
}
} else if (vbl_count > 35 && trick_cards == 4) {
vbl_count = 0;
// Update variables
turn = trick_winner();
leader = turn;
// Score the trick (based on who the new leader is)
score_trick();
// Hide the old trick
for (u8 i = 0; i < 4; ++i) {
ham_DeleteObj(T[i].slot);
// Clear out the old trick
Trick[i].number = 0;
Trick[i].suit = 0;
}
// No longer the first trick
if (first_trick) first_trick = false;
// Reset trick cards
trick_cards = 0;
// Update the number of tricks
++tricks;
// Check if the round is over
if (tricks == 14) {
// Increment the round
if (round == 3) {
round = 0;
} else {
++round;
}
// Change the gamestate
game_state = SCORE;
return;
}
}// End of if (players == 1 && turn == 1)
return;
} // End of HEARTS::in_game_query_keys()
//********************************************
// Function: HEARTS::in_game_redraw()
// Purpose: Redraw the screen during in_game()
//********************************************
void HEARTS::in_game_redraw()
{
return;
} // End of HEARTS::in_game_redraw()
//**************************************
// Function: HEARTS::in_game_deinit()
// Purpose: Deinitialize game playing
//**************************************
void HEARTS::in_game_deinit()
{
// Deinitialize the background
ham_DeInitBg(0);
// *** brute force delete ***
for (u8 i = 0; i < 128; ++i) {
ham_DeleteObj(i);
}
// This must be called to actually delete the sprites
ham_CopyObjToOAM();
return;
} // End of HEARTS::in_game_deinit()
//*************************************
// Function: HEARTS::score_init()
// Purpose: Initialize the score screen
//*************************************
void HEARTS::score_init()
{
// Start the VBL counter at 0
vbl_count = 0;
// Start with the first start screen image
curr_screen = 1;
// Show the Hand Scores screen
// Initialize the background palette
ham_LoadBGPal((void *)score_Palette,256);
ham_LoadObjPal((void *)numbers_new_Palette,256);
/*
// Set the tileset for the 'Hearts' screen
ham_bg[0].ti = ham_InitTileSet((void *)score_Tiles,
SIZEOF_16BIT(score_Tiles),1,1);
ham_bg[0].mi = ham_InitMapSet((void *)score_Map,256,0,0);
// Display the background
ham_InitBg(0,1,0,0);
*/
// Setup the tileset for our image
ham_bg[0].ti = ham_InitTileSet((void *)score_Tiles,
SIZEOF_16BIT(score_Tiles),1,1);
// Setup the map for our image
ham_bg[0].mi = ham_InitMapEmptySet(3,0);
bg_one = ham_InitMapFragment((void *)score_Map,30,20,0,0,30,20,0);
ham_InsertMapFragment(bg_one,0,0,0);
// Display the background
ham_InitBg(0,1,0,0);
// Setup the Hand Score pointers
HSh[0].x_pos = 129; HSh[0].y_pos = 48;
HSt[0].x_pos = 139; HSt[0].y_pos = 48;
HSo[0].x_pos = 149; HSo[0].y_pos = 48;
HSh[1].x_pos = 129; HSh[1].y_pos = 76;
HSt[1].x_pos = 139; HSt[1].y_pos = 76;
HSo[1].x_pos = 149; HSo[1].y_pos = 76;
HSh[2].x_pos = 129; HSh[2].y_pos = 104;
HSt[2].x_pos = 139; HSt[2].y_pos = 104;
HSo[2].x_pos = 149; HSo[2].y_pos = 104;
HSh[3].x_pos = 129; HSh[3].y_pos = 132;
HSt[3].x_pos = 139; HSt[3].y_pos = 132;
HSo[3].x_pos = 149; HSo[3].y_pos = 132;
// Setup the Total Score pointers
TSh[0].x_pos = 184; TSh[0].y_pos = 48;
TSt[0].x_pos = 194; TSt[0].y_pos = 48;
TSo[0].x_pos = 204; TSo[0].y_pos = 48;
TSh[1].x_pos = 184; TSh[1].y_pos = 76;
TSt[1].x_pos = 194; TSt[1].y_pos = 76;
TSo[1].x_pos = 204; TSo[1].y_pos = 76;
TSh[2].x_pos = 184; TSh[2].y_pos = 104;
TSt[2].x_pos = 194; TSt[2].y_pos = 104;
TSo[2].x_pos = 204; TSo[2].y_pos = 104;
TSh[3].x_pos = 184; TSh[3].y_pos = 132;
TSt[3].x_pos = 194; TSt[3].y_pos = 132;
TSo[3].x_pos = 204; TSo[3].y_pos = 132;
// See if anyone 'shot the moon'
if (Hand_Score[0] == 26) {
Hand_Score[0] = 0;
Hand_Score[1] = 26;
Hand_Score[2] = 26;
Hand_Score[3] = 26;
} else if (Hand_Score[1] == 26) {
Hand_Score[0] = 26;
Hand_Score[1] = 0;
Hand_Score[2] = 26;
Hand_Score[3] = 26;
} else if (Hand_Score[2] == 26) {
Hand_Score[0] = 26;
Hand_Score[1] = 26;
Hand_Score[2] = 0;
Hand_Score[3] = 26;
} else if (Hand_Score[3] == 26) {
Hand_Score[0] = 26;
Hand_Score[1] = 26;
Hand_Score[2] = 26;
Hand_Score[3] = 0;
}
// Add the hand scores to the total scores
for (u8 i = 0; i < 4; ++i) {
Total_Score[i] += Hand_Score[i];
}
// Setup the Hand Score values
graphic_spot = convert_number(Hand_Score[0]/10);
HSt[0].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,HSt[0].x_pos,HSt[0].y_pos);
graphic_spot = convert_number(Hand_Score[0]%10);
HSo[0].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,HSo[0].x_pos,HSo[0].y_pos);
graphic_spot = convert_number(Hand_Score[1]/10);
HSt[1].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,HSt[1].x_pos,HSt[1].y_pos);
graphic_spot = convert_number(Hand_Score[1]%10);
HSo[1].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,HSo[1].x_pos,HSo[1].y_pos);
graphic_spot = convert_number(Hand_Score[2]/10);
HSt[2].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,HSt[2].x_pos,HSt[2].y_pos);
graphic_spot = convert_number(Hand_Score[2]%10);
HSo[2].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,HSo[2].x_pos,HSo[2].y_pos);
graphic_spot = convert_number(Hand_Score[3]/10);
HSt[3].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,HSt[3].x_pos,HSt[3].y_pos);
graphic_spot = convert_number(Hand_Score[3]%10);
HSo[3].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,HSo[3].x_pos,HSo[3].y_pos);
// Setup the graphics for each score
// Check whether they have gone over 100
u8 hundreds = 0;
if (Total_Score[0]/100 > 0) {
// Setup the 'hundreds'
hundreds = Total_Score[0]/100;
graphic_spot = convert_number(hundreds);
TSh[0].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,TSh[0].x_pos,TSh[0].y_pos);
// Setup the 'tens'
graphic_spot = convert_number((Total_Score[0]/10)-hundreds*10);
TSt[0].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,TSt[0].x_pos,TSt[0].y_pos);
} else {
// Setup the 'tens'
graphic_spot = convert_number(Total_Score[0]/10);
TSt[0].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,TSt[0].x_pos,TSt[0].y_pos);
}
if (Total_Score[1]/100 > 0) {
// Setup the 'hundreds'
hundreds = Total_Score[1]/100;
graphic_spot = convert_number(hundreds);
TSh[1].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,TSh[1].x_pos,TSh[1].y_pos);
// Setup the 'tens'
graphic_spot = convert_number((Total_Score[1]/10)-hundreds*10);
TSt[1].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,TSt[1].x_pos,TSt[1].y_pos);
} else {
// Setup the 'tens'
graphic_spot = convert_number(Total_Score[1]/10);
TSt[1].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,TSt[1].x_pos,TSt[1].y_pos);
}
if (Total_Score[2]/100 > 0) {
// Setup the 'hundreds'
hundreds = Total_Score[2]/100;
graphic_spot = convert_number(hundreds);
TSh[2].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,TSh[2].x_pos,TSh[2].y_pos);
// Setup the 'tens'
graphic_spot = convert_number((Total_Score[2]/10)-hundreds*10);
TSt[2].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,TSt[2].x_pos,TSt[2].y_pos);
} else {
// Setup the 'tens'
graphic_spot = convert_number(Total_Score[2]/10);
TSt[2].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,TSt[2].x_pos,TSt[2].y_pos);
}
if (Total_Score[3]/100 > 0) {
// Setup the 'hundreds'
hundreds = Total_Score[3]/100;
graphic_spot = convert_number(hundreds);
TSh[3].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,TSh[3].x_pos,TSh[3].y_pos);
// Setup the 'tens'
graphic_spot = convert_number((Total_Score[3]/10)-hundreds*10);
TSt[3].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,TSt[3].x_pos,TSt[3].y_pos);
} else {
// Setup the 'tens'
graphic_spot = convert_number(Total_Score[3]/10);
TSt[3].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,TSt[3].x_pos,TSt[3].y_pos);
}
// Figure out the 'ones'
graphic_spot = convert_number(Total_Score[0]%10);
TSo[0].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,TSo[0].x_pos,TSo[0].y_pos);
graphic_spot = convert_number(Total_Score[1]%10);
TSo[1].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,TSo[1].x_pos,TSo[1].y_pos);
graphic_spot = convert_number(Total_Score[2]%10);
TSo[2].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,TSo[2].x_pos,TSo[2].y_pos);
graphic_spot = convert_number(Total_Score[3]%10);
TSo[3].slot = ham_CreateObj((void *)&numbers_new_Bitmap[graphic_spot],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,TSo[3].x_pos,TSo[3].y_pos);
return;
} // End of score_init()
//****************************************
// Function: HEARTS::score_query_keys()
// Purpose: Gets input during score screen
//****************************************
void HEARTS::score_query_keys()
{
// Increment the VBL counter every VBL
++vbl_count;
// A, B or START button
if (vbl_count > 10 && (F_CTRLINPUT_A_PRESSED || F_CTRLINPUT_B_PRESSED || F_CTRLINPUT_START_PRESSED)) {
// Get back into the game
if (is_winner()) {
game_state = FINISH;
} else {
game_state = PLAY;
}
}
return;
} // End of score_query_keys
//****************************************
// Function: HEARTS::score_redraw()
// Purpose: Redraw the screen during score
//****************************************
void HEARTS::score_redraw()
{
return;
} // End of score_redraw()
//***************************************
// Function: HEARTS::score_deinit()
// Purpose: Deinitialize the score screen
//***************************************
void HEARTS::score_deinit()
{
// Deinitialize the background
ham_DeInitBg(0);
// *** brute force delete ***
for (u8 i = 0; i < 128; ++i) {
ham_DeleteObj(i);
}
// This must be called to actually delete the sprites
ham_CopyObjToOAM();
return;
} // End of score_deinit()
//***********************************
// Function: HEARTS::finish_init()
// Purpose: Displays the screen
// after tie, win or quit
//***********************************
void HEARTS::finish_init()
{
// Start the VBL counter at 0
vbl_count = 0;
// Initialize the background palette
ham_LoadBGPal((void *)game_over_Palette,256);
// Choose which background to load based on the winner
if (winner == 0) { // Player1
// Setup the tileset for our image
ham_bg[0].ti = ham_InitTileSet((void *)game_over_p1_Tiles,
SIZEOF_16BIT(game_over_p1_Tiles),1,1);
// Setup the map for our image
ham_bg[0].mi = ham_InitMapEmptySet(3,0);
bg_one = ham_InitMapFragment((void *)game_over_p1_Map,30,20,0,0,30,20,0);
ham_InsertMapFragment(bg_one,0,0,0);
} else if (winner == 1) { // Player2
// Setup the tileset for our image
ham_bg[0].ti = ham_InitTileSet((void *)game_over_p2_Tiles,
SIZEOF_16BIT(game_over_p2_Tiles),1,1);
// Setup the map for our image
ham_bg[0].mi = ham_InitMapEmptySet(3,0);
bg_one = ham_InitMapFragment((void *)game_over_p2_Map,30,20,0,0,30,20,0);
ham_InsertMapFragment(bg_one,0,0,0);
} else if (winner == 2) { // Player3
// Setup the tileset for our image
ham_bg[0].ti = ham_InitTileSet((void *)game_over_p3_Tiles,
SIZEOF_16BIT(game_over_p3_Tiles),1,1);
// Setup the map for our image
ham_bg[0].mi = ham_InitMapEmptySet(3,0);
bg_one = ham_InitMapFragment((void *)game_over_p3_Map,30,20,0,0,30,20,0);
ham_InsertMapFragment(bg_one,0,0,0);
} else if (winner == 3) { // Player4
// Setup the tileset for our image
ham_bg[0].ti = ham_InitTileSet((void *)game_over_p4_Tiles,
SIZEOF_16BIT(game_over_p4_Tiles),1,1);
// Setup the map for our image
ham_bg[0].mi = ham_InitMapEmptySet(3,0);
bg_one = ham_InitMapFragment((void *)game_over_p4_Map,30,20,0,0,30,20,0);
ham_InsertMapFragment(bg_one,0,0,0);
} else if (winner == 4) { // Tie Game
// Setup the tileset for our image
ham_bg[0].ti = ham_InitTileSet((void *)game_over_tie_Tiles,
SIZEOF_16BIT(game_over_tie_Tiles),1,1);
// Setup the map for our image
ham_bg[0].mi = ham_InitMapEmptySet(3,0);
bg_one = ham_InitMapFragment((void *)game_over_tie_Map,30,20,0,0,30,20,0);
ham_InsertMapFragment(bg_one,0,0,0);
}
// Display the background
ham_InitBg(0,1,0,0);
return;
} // End of HEARTS::finish_init()
//*********************************************
// Function: HEARTS::finish_query_keys()
// Purpose: Gets input during the finish screen
//*********************************************
void HEARTS::finish_query_keys()
{
// Increment the VBL counter every VBL
++vbl_count;
// Wait for the user to press a key
if (vbl_count > 10 && anykey()) {
game_state = MAIN;
}
return;
} // End of finish_query_keys()
//*************************************
// Function: HEARTS::finish_deinit()
// Purpose: Deinitialize finish()
//*************************************
void HEARTS::finish_deinit()
{
// Deinitialize the background and sprites
ham_DeInitBg(0);
// *** brute force delete ***
for (u8 i = 0; i < 128; ++i) {
ham_DeleteObj(i);
}
// This must be called to actually delete the sprites
ham_CopyObjToOAM();
return;
} // End of HEARTS::finish_deinit()
//*************************************
// Function: HEARTS::options_init()
// Purpose: Displays the options screen
//*************************************
void HEARTS::options_init()
{
// Start the VBL counter at 0
vbl_count = 0;
// Setup variables to keep track of screens
curr_screen = 0;
last_screen = 0;
// Initialize the palettes
ham_LoadBGPal((void *)options_Palette,256);
ham_LoadObjPal((void *)options_sprites_Palette,256);
// Display the image
TOOL_DMA1_SET(&options_sl_Bitmap,
MEM_BG_PTR,SIZEOF_32BIT(options_sl_Bitmap),
DMA_TRANSFER_32BIT,
DMA_STARTAT_NOW);
// Setup the options sprites
opts[0].x_pos = 173;
opts[0].y_pos = 41;
opts[1].x_pos = 160;
opts[1].y_pos = 76;
opts[2].x_pos = 160;
opts[2].y_pos = 119;
// Create the three options sprites
opts[0].slot = ham_CreateObj((void *)&op_2_Bitmap[0],0,1,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,opts[0].x_pos,opts[0].y_pos);
opts[1].slot = ham_CreateObj((void *)&off_Bitmap[0],0,2,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,opts[1].x_pos,opts[1].y_pos);
opts[2].slot = ham_CreateObj((void *)&off_Bitmap[0],0,2,
OBJ_MODE_NORMAL,1,0,0,0,0,0,0,opts[2].x_pos,opts[2].y_pos);
return;
} // End of options_init()
//**********************************************
// Function: HEARTS::options_query_keys()
// Purpose: Gets input during the options screen
//**********************************************
void HEARTS::options_query_keys()
{
// Increment the VBL counter every VBL
++vbl_count;
// START or A button
if (vbl_count > 10 && (F_CTRLINPUT_START_PRESSED || F_CTRLINPUT_A_PRESSED)) {
// Go back to the main screen
game_state = MAIN;
}
// UP
if (vbl_count > 10 && F_CTRLINPUT_UP_PRESSED) {
vbl_count = 0;
last_screen = curr_screen;
if (curr_screen == 0) {
curr_screen = 2;
} else {
--curr_screen;
}
}
// DOWN
if (vbl_count > 10 && F_CTRLINPUT_DOWN_PRESSED) {
vbl_count = 0;
last_screen = curr_screen;
if (curr_screen == 2) {
curr_screen = 0;
} else {
++curr_screen;
}
}
// RIGHT
if (vbl_count > 10 && F_CTRLINPUT_RIGHT_PRESSED) {
vbl_count = 0;
// Skill Level
if (curr_screen == 0) {
if (skill == 1) {
skill = 2;
} else if (skill == 2) {
skill = 3;
} else if (skill == 3) {
skill = 1;
}
// Sound
} else if (curr_screen == 1) {
// Off
if (sound == 0) {
sound = 1; // On
// On
} else if (sound == 1) {
sound = 0; // Off
}
// Music
} else if (curr_screen == 2) {
// Off
if (music == 0) {
music = 1; // On
// On
} else if (music == 1) {
music = 0; // Off
}
}
}
// LEFT
if (vbl_count > 10 && F_CTRLINPUT_LEFT_PRESSED) {
vbl_count = 0;
// Skill Level
if (curr_screen == 0) {
if (skill == 3) {
skill = 2;
} else if (skill == 2) {
skill = 1;
} else if (skill == 1) {
skill = 3;
}
// Sound
} else if (curr_screen == 1) {
// Off
if (sound == 0) {
sound = 1; // On
// On
} else if (sound == 1) {
sound = 0; // Off
}
// Music
} else if (curr_screen == 2) {
// Off
if (music == 0) {
music = 1; // On
// On
} else if (music == 1) {
music = 0; // Off
}
}
}
return;
} // End of options_query_keys()
//********************************************
// Function: HEARTS::options_redraw()
// Purpose: Redraw the screen during options()
//********************************************
void HEARTS::options_redraw()
{
// See if changes were made
if (last_screen != curr_screen) {
if (curr_screen == 0) {
// Display the image
TOOL_DMA1_SET(&options_sl_Bitmap,
MEM_BG_PTR,SIZEOF_32BIT(options_sl_Bitmap),
DMA_TRANSFER_32BIT,
DMA_STARTAT_NOW);
} else if (curr_screen == 1) {
// Display the image
TOOL_DMA1_SET(&options_so_Bitmap,
MEM_BG_PTR,SIZEOF_32BIT(options_so_Bitmap),
DMA_TRANSFER_32BIT,
DMA_STARTAT_NOW);
} else if (curr_screen == 2) {
// Display the image
TOOL_DMA1_SET(&options_mu_Bitmap,
MEM_BG_PTR,SIZEOF_32BIT(options_mu_Bitmap),
DMA_TRANSFER_32BIT,
DMA_STARTAT_NOW);
}
last_screen = curr_screen; // Set them equal - this means there was no input change
}
// Update the sprites
// Skill Level
if (skill == 1) {
ham_UpdateObjGfx(opts[0].slot,(void *)&op_1_Bitmap[0]);
} else if (skill == 2) {
ham_UpdateObjGfx(opts[0].slot,(void *)&op_2_Bitmap[0]);
} else if (skill == 3) {
ham_UpdateObjGfx(opts[0].slot,(void *)&op_3_Bitmap[0]);
}
// Sound
if (sound == 0) {
ham_UpdateObjGfx(opts[1].slot,(void *)&off_Bitmap[0]);
} else if (sound == 1) {
ham_UpdateObjGfx(opts[1].slot,(void *)&on_Bitmap[0]);
}
// Music
if (music == 0) {
ham_UpdateObjGfx(opts[2].slot,(void *)&off_Bitmap[0]);
} else if (music == 1) {
ham_UpdateObjGfx(opts[2].slot,(void *)&on_Bitmap[0]);
}
return;
} // End of options_redraw()
//*************************************
// Function: HEARTS::options_deinit()
// Purpose: Deinitialize options()
//*************************************
void HEARTS::options_deinit()
{
// Delete the sprites
ham_DeleteObj(opts[0].slot);
ham_DeleteObj(opts[1].slot);
ham_DeleteObj(opts[2].slot);
return;
} // End of options_deinit()
//*********************************************
// Function: HEARTS::is_winner()
// Purpose: Checks to see if there was a winner
//*********************************************
bool HEARTS::is_winner()
{
// Varables
bool win = false;
bool tie = false;
// Make sure that no one is the winner yet
winner = 4;
// Cycle through the total scores
for (u8 i = 0; i < 4; ++i) {
// See if anyone has over 100
if (Total_Score[i] >= 100) {
// If no one scored over a hundred yet
if (!win) {
// Make sure we know that someone has won
win = true;
// If the stored score is empty
if (winner == 4) {
winner = i; // Store this one for now
}
}
// Otherwise, check if the score is less than 100
} else {
// If the stored score is empty
if (winner == 4) {
winner = i; // Store this one
// Otherwise, compare this score with the stored one
} else {
// Current score is less than stored score
if (Total_Score[i] < Total_Score[winner]) {
winner = i;
tie = false;
// Current store equals stored score, TIE!
} else if (Total_Score[i] == Total_Score[winner]) {
tie = true;
}
}
}
}
// Check if there is a tie
if (tie) winner = 4;
return win;
} // End of HEARTS::is_winner()
//****************************
// Function: HEARTS::gs()
// Purpose: Returns game_state
//****************************
HEARTS::states HEARTS::gs()
{
return game_state;
} // End of HEARTS::gs()
//**************************
// Function: HEARTS::gt()
// Purpose: Returns turn
//**************************
u8 HEARTS::gt()
{
return turn;
} // End of HEARTS::gt()
//***************************
// Function: HEARTS::gsl()
// Purpose: Returns suit_lead
//***************************
u8 HEARTS::gsl()
{
return suit_lead;
} // End of HEARTS::gsl()
//************************
// Function: HEARTS::gl()
// Purpose: Returns leader
//************************
u8 HEARTS::gl()
{
return leader;
} // End of HEARTS::gl()
//************************
// Function: HEARTS::gtc()
// Purpose: Returns leader
//************************
u8 HEARTS::gtc()
{
return trick_cards;
} // End of HEARTS::gtc()
//************************
// Function: HEARTS::gtr()
// Purpose: Returns tricks
//************************
u8 HEARTS::gtr()
{
return tricks;
} // End of HEARTS::gtr()
//********************************************
// Function: HEARTS::trick_number()
// Purpose: Returns card number in Trick[slot]
//********************************************
u8 HEARTS::trick_number(u8 slot)
{
return Trick[slot].number;
} // End of trick_number()
//******************************************
// Function: HEARTS::trick_suit()
// Purpose: Returns card suit in Trick[slot]
//******************************************
u8 HEARTS::trick_suit(u8 slot)
{
return Trick[slot].suit;
} // End of trick_suit()
//********************************************
// Function: HEARTS::player_number()
// Purpose: Returns card suit of PlayerX[slot]
//********************************************
u8 HEARTS::player_number(u8 player, u8 slot)
{
if (player == 1) {
return Player1[slot].number;
} else if (player == 2) {
return Player2[slot].number;
} else if (player == 3) {
return Player3[slot].number;
} else if (player == 4) {
return Player4[slot].number;
}
return 0; // *** should never happen ***
} // End of player_number()
//********************************************
// Function: HEARTS::player_suit()
// Purpose: Returns card suit of PlayerX[slot]
//********************************************
u8 HEARTS::player_suit(u8 player, u8 slot)
{
if (player == 1) {
return Player1[slot].suit;
} else if (player == 2) {
return Player2[slot].suit;
} else if (player == 3) {
return Player3[slot].suit;
} else if (player == 4) {
return Player4[slot].suit;
}
return 0; // *** should never happen ***
} // End of player_suit()
//*********************************************
// Function: HEARTS::convert_card()
// Purpose: Returns the passed card info's spot
// in the card_deck graphics array
//*********************************************
u32 HEARTS::convert_card(u8 number, u8 suit)
{
return (((number - 2) * 4096) + (suit * 1024));
} // End of HEARTS::convert_card()
//*********************************************
// Function: HEARTS::convert_card_64()
// Purpose: Returns the passed card info's spot
// in the card_deck_64 graphics array
//*********************************************
u32 HEARTS::convert_card_64(u8 number, u8 suit)
{
return (((number - 2) * 16384) + (suit * 4096));
} // End of HEARTS::convert_card_64()
//******************************************
// Function: HEARTS::convert_number()
// Purpose: Returns the passed number's spot
// in the number graphics array
//******************************************
u32 HEARTS::convert_number(u8 number)
{
return (number * 256);
} // End of HEARTS::convert_number()
//*************************************
// Function: HEARTS::hand_sort()
// Purpose: Sorts a hand: C,D,S,H : 2-A
//*************************************
void HEARTS::hand_sort(u8 player)
{
if (player == 1) {
for (u8 i = 0; i < 12; ++i) {
for (u8 j = 0; j < 12; ++j) {
u8 one = sort_card_value(Player1[j].number,Player1[j].suit);
u8 two = sort_card_value(Player1[j+1].number,Player1[j+1].suit);
if (two < one) {
u8 temp_numb = Player1[j].number;
u8 temp_suit = Player1[j].suit;
Player1[j].number = Player1[j+1].number;
Player1[j].suit = Player1[j+1].suit;
Player1[j+1].number = temp_numb;
Player1[j+1].suit = temp_suit;
}
}
}
} else if (player == 2) {
for (u8 i = 0; i < 12; ++i) {
for (u8 j = 0; j < 12; ++j) {
u8 one = sort_card_value(Player2[j].number,Player2[j].suit);
u8 two = sort_card_value(Player2[j+1].number,Player2[j+1].suit);
if (two < one) {
u8 temp_numb = Player2[j].number;
u8 temp_suit = Player2[j].suit;
Player2[j].number = Player2[j+1].number;
Player2[j].suit = Player2[j+1].suit;
Player2[j+1].number = temp_numb;
Player2[j+1].suit = temp_suit;
}
}
}
} else if (player == 3) {
for (u8 i = 0; i < 12; ++i) {
for (u8 j = 0; j < 12; ++j) {
u8 one = sort_card_value(Player3[j].number,Player3[j].suit);
u8 two = sort_card_value(Player3[j+1].number,Player3[j+1].suit);
if (two < one) {
u8 temp_numb = Player3[j].number;
u8 temp_suit = Player3[j].suit;
Player3[j].number = Player3[j+1].number;
Player3[j].suit = Player3[j+1].suit;
Player3[j+1].number = temp_numb;
Player3[j+1].suit = temp_suit;
}
}
}
} else if (player == 4) {
for (u8 i = 0; i < 12; ++i) {
for (u8 j = 0; j < 12; ++j) {
u8 one = sort_card_value(Player4[j].number,Player4[j].suit);
u8 two = sort_card_value(Player4[j+1].number,Player4[j+1].suit);
if (two < one) {
u8 temp_numb = Player4[j].number;
u8 temp_suit = Player4[j].suit;
Player4[j].number = Player4[j+1].number;
Player4[j].suit = Player4[j+1].suit;
Player4[j+1].number = temp_numb;
Player4[j+1].suit = temp_suit;
}
}
}
}
return;
} // End of HEARTS::hand_sort
//*******************************************************
// Function: HEARTS::sort_card_value()
// Purpose: Used during sort to figure out a card's value
//*******************************************************
u8 HEARTS::sort_card_value(u8 number, u8 suit)
{
if (suit == 0) {
suit = 2;
} else if (suit == 1) {
suit = 0;
} else if (suit == 2) {
suit = 3;
} else if (suit == 3) {
suit = 1;
}
return ((suit * 13) + (number - 2));
} // End of HEARTS::sort_card_value()
//*******************************************
// Function: setup_leader()
// Purpose: Figure out who has the 2 of Clubs
//*******************************************
void HEARTS::setup_leader()
{
// Cycle through each hand looking for the 2 of Clubs
for (u8 i = 0; i < 13; ++i) {
if (Player1[i].number == 2 && Player1[i].suit == 1) {
leader = 1;
return;
}
if (Player2[i].number == 2 && Player2[i].suit == 1) {
leader = 2;
return;
}
if (Player3[i].number == 2 && Player3[i].suit == 1) {
leader = 3;
return;
}
if (Player4[i].number == 2 && Player4[i].suit == 1) {
leader = 4;
return;
}
}
return;
} // End of setup_leader()
//**************************************
// Function: trick_winner()
// Purpose: Figure out who won the trick
//**************************************
u8 HEARTS::trick_winner()
{
u8 check[4];
check[0] = 0;
check[1] = 0;
check[2] = 0;
check[3] = 0;
// Determine which trick cards will be compared
for (u8 i = 0; i < 4; ++i) {
if (Trick[i].suit == suit_lead) {
check[i] = Trick[i].number;
}
}
if ((check[0] > check[1]) && (check[0] > check[2]) && (check[0] > check[3])) {
return 1;
} else if ((check[1] > check[0]) && (check[1] > check[2]) && (check[1] > check[3])) {
return 2;
} else if ((check[2] > check[0]) && (check[2] > check[1]) && (check[2] > check[3])) {
return 3;
} else if ((check[3] > check[0]) && (check[3] > check[1]) && (check[3] > check[2])) {
return 4;
} else {
return 1;
}
} // End of trick_winner()
//********************************************
// Function: score_trick()
// Purpose: Figure out the score of each trick
//********************************************
void HEARTS::score_trick()
{
// Setup a pointer
u8 *Trick_Winner = NULL;
if (leader == 1) {
Trick_Winner = &Hand_Score[0];
} else if (leader == 2) {
Trick_Winner = &Hand_Score[1];
} else if (leader == 3) {
Trick_Winner = &Hand_Score[2];
} else if (leader == 4) {
Trick_Winner = &Hand_Score[3];
}
// Add one point for a Heart
if (Trick[0].suit == 2) *Trick_Winner += 1;
if (Trick[1].suit == 2) *Trick_Winner += 1;
if (Trick[2].suit == 2) *Trick_Winner += 1;
if (Trick[3].suit == 2) *Trick_Winner += 1;
// Add 13 points for a Queen of Spades
if (Trick[0].number == 12 && Trick[0].suit == 0) *Trick_Winner += 13;
if (Trick[1].number == 12 && Trick[1].suit == 0) *Trick_Winner += 13;
if (Trick[2].number == 12 && Trick[2].suit == 0) *Trick_Winner += 13;
if (Trick[3].number == 12 && Trick[3].suit == 0) *Trick_Winner += 13;
return;
}
//***************************************
// Function: valid_move()
// Purpose: Check whether the card passed
// is valid to play
//***************************************
bool HEARTS::valid_move(u8 player, u8 slot)
{
// Variables
Card *Player = NULL;
// Make the pointer point to the correct Card array
if (player == 1) {
Player = Player1;
} else if (player == 2) {
Player = Player2;
} else if (player == 3) {
Player = Player3;
} else if (player == 4) {
Player = Player4;
}
// *** there is already a check that the first card is the 2 of Clubs ***
// Cannot play Queen of Spades on first trick
if (first_trick && (Player[slot].number == 12 && Player[slot].suit == 0)) return false;
// Cannot play a Heart on the first trick, unless the player has only Hearts
if (first_trick && (Player[slot].suit == 2)) {
for (u8 i = 0; i < 13; ++i) {
if ((Player[i].number != 0) && (Player[i].suit != 2)) return false;
}
return true;
}
// Cannot lead a Heart until Hearts are broken, unless the player has only Hearts
if ((leader == player) && (!hearts_broken) && (Player[slot].suit == 2)) {
// Cycle through the hand to make sure the player has only Hearts
for (u8 i = 0; i < 13; ++i) {
if ((Player[i].number != 0) && (Player[i].suit != 2)) return false;
}
return true;
}
// Make sure the player plays the suit lead if they have it
if ((leader != player) && (Player[slot].suit != suit_lead)) {
// Cycle through the hand to make sure they don't have the suit
for (u8 i = 0; i < 13; ++i) {
if ((Player[i].number != 0) && (Player[i].suit == suit_lead)) return false;
}
return true;
}
return true;
} // End of valid_move()
void HEARTS::pass_cards()
{
// Variables
Card temp_cards[3];
// Pass the cards
if (round == 0) {
// Backup Player 1's cards
temp_cards[0].number = Player1[Passed_Cards[0]].number;
temp_cards[0].suit = Player1[Passed_Cards[0]].suit;
temp_cards[1].number = Player1[Passed_Cards[1]].number;
temp_cards[1].suit = Player1[Passed_Cards[1]].suit;
temp_cards[2].number = Player1[Passed_Cards[2]].number;
temp_cards[2].suit = Player1[Passed_Cards[2]].suit;
// Swap from Player 4 to Player 1
Player1[Passed_Cards[0]].number = Player4[Passed_Cards[9]].number;
Player1[Passed_Cards[0]].suit = Player4[Passed_Cards[9]].suit;
Player1[Passed_Cards[1]].number = Player4[Passed_Cards[10]].number;
Player1[Passed_Cards[1]].suit = Player4[Passed_Cards[10]].suit;
Player1[Passed_Cards[2]].number = Player4[Passed_Cards[11]].number;
Player1[Passed_Cards[2]].suit = Player4[Passed_Cards[11]].suit;
// Swap from Player 3 to Player 4
Player4[Passed_Cards[9]].number = Player3[Passed_Cards[6]].number;
Player4[Passed_Cards[9]].suit = Player3[Passed_Cards[6]].suit;
Player4[Passed_Cards[10]].number = Player3[Passed_Cards[7]].number;
Player4[Passed_Cards[10]].suit = Player3[Passed_Cards[7]].suit;
Player4[Passed_Cards[11]].number = Player3[Passed_Cards[8]].number;
Player4[Passed_Cards[11]].suit = Player3[Passed_Cards[8]].suit;
// Swap from Player 2 to Player 3
Player3[Passed_Cards[6]].number = Player2[Passed_Cards[3]].number;
Player3[Passed_Cards[6]].suit = Player2[Passed_Cards[3]].suit;
Player3[Passed_Cards[7]].number = Player2[Passed_Cards[4]].number;
Player3[Passed_Cards[7]].suit = Player2[Passed_Cards[4]].suit;
Player3[Passed_Cards[8]].number = Player2[Passed_Cards[5]].number;
Player3[Passed_Cards[8]].suit = Player2[Passed_Cards[5]].suit;
// Swap from Player 1 to Player 2
Player2[Passed_Cards[3]].number = temp_cards[0].number;
Player2[Passed_Cards[3]].suit = temp_cards[0].suit;
Player2[Passed_Cards[4]].number = temp_cards[1].number;
Player2[Passed_Cards[4]].suit = temp_cards[1].suit;
Player2[Passed_Cards[5]].number = temp_cards[2].number;
Player2[Passed_Cards[5]].suit = temp_cards[2].suit;
} else if (round == 1) {
// Backup Player 1's cards
temp_cards[0].number = Player1[Passed_Cards[0]].number;
temp_cards[0].suit = Player1[Passed_Cards[0]].suit;
temp_cards[1].number = Player1[Passed_Cards[1]].number;
temp_cards[1].suit = Player1[Passed_Cards[1]].suit;
temp_cards[2].number = Player1[Passed_Cards[2]].number;
temp_cards[2].suit = Player1[Passed_Cards[2]].suit;
// Swap from Player 2 to Player 1
Player1[Passed_Cards[0]].number = Player2[Passed_Cards[3]].number;
Player1[Passed_Cards[0]].suit = Player2[Passed_Cards[3]].suit;
Player1[Passed_Cards[1]].number = Player2[Passed_Cards[4]].number;
Player1[Passed_Cards[1]].suit = Player2[Passed_Cards[4]].suit;
Player1[Passed_Cards[2]].number = Player2[Passed_Cards[5]].number;
Player1[Passed_Cards[2]].suit = Player2[Passed_Cards[5]].suit;
// Swap from Player 3 to Player 2
Player2[Passed_Cards[3]].number = Player3[Passed_Cards[6]].number;
Player2[Passed_Cards[3]].suit = Player3[Passed_Cards[6]].suit;
Player2[Passed_Cards[4]].number = Player3[Passed_Cards[7]].number;
Player2[Passed_Cards[4]].suit = Player3[Passed_Cards[7]].suit;
Player2[Passed_Cards[5]].number = Player3[Passed_Cards[8]].number;
Player2[Passed_Cards[5]].suit = Player3[Passed_Cards[8]].suit;
// Swap from Player 4 to Player 3
Player3[Passed_Cards[6]].number = Player4[Passed_Cards[9]].number;
Player3[Passed_Cards[6]].suit = Player4[Passed_Cards[9]].suit;
Player3[Passed_Cards[7]].number = Player4[Passed_Cards[10]].number;
Player3[Passed_Cards[7]].suit = Player4[Passed_Cards[10]].suit;
Player3[Passed_Cards[8]].number = Player4[Passed_Cards[11]].number;
Player3[Passed_Cards[8]].suit = Player4[Passed_Cards[11]].suit;
// Swap from Player 1 to Player 4
Player4[Passed_Cards[9]].number = temp_cards[0].number;
Player4[Passed_Cards[9]].suit = temp_cards[0].suit;
Player4[Passed_Cards[10]].number = temp_cards[1].number;
Player4[Passed_Cards[10]].suit = temp_cards[1].suit;
Player4[Passed_Cards[11]].number = temp_cards[2].number;
Player4[Passed_Cards[11]].suit = temp_cards[2].suit;
} else if (round == 2) {
// Backup Player 1's cards
temp_cards[0].number = Player1[Passed_Cards[0]].number;
temp_cards[0].suit = Player1[Passed_Cards[0]].suit;
temp_cards[1].number = Player1[Passed_Cards[1]].number;
temp_cards[1].suit = Player1[Passed_Cards[1]].suit;
temp_cards[2].number = Player1[Passed_Cards[2]].number;
temp_cards[2].suit = Player1[Passed_Cards[2]].suit;
// Swap from Player 3 to Player 1
Player1[Passed_Cards[0]].number = Player3[Passed_Cards[6]].number;
Player1[Passed_Cards[0]].suit = Player3[Passed_Cards[6]].suit;
Player1[Passed_Cards[1]].number = Player3[Passed_Cards[7]].number;
Player1[Passed_Cards[1]].suit = Player3[Passed_Cards[7]].suit;
Player1[Passed_Cards[2]].number = Player3[Passed_Cards[8]].number;
Player1[Passed_Cards[2]].suit = Player3[Passed_Cards[8]].suit;
// Swap from Player 1 to Player 3
Player3[Passed_Cards[6]].number = temp_cards[0].number;
Player3[Passed_Cards[6]].suit = temp_cards[0].suit;
Player3[Passed_Cards[7]].number = temp_cards[1].number;
Player3[Passed_Cards[7]].suit = temp_cards[1].suit;
Player3[Passed_Cards[8]].number = temp_cards[2].number;
Player3[Passed_Cards[8]].suit = temp_cards[2].suit;
// Backup Player 2's cards
temp_cards[0].number = Player2[Passed_Cards[3]].number;
temp_cards[0].suit = Player2[Passed_Cards[3]].suit;
temp_cards[1].number = Player2[Passed_Cards[4]].number;
temp_cards[1].suit = Player2[Passed_Cards[4]].suit;
temp_cards[2].number = Player2[Passed_Cards[5]].number;
temp_cards[2].suit = Player2[Passed_Cards[5]].suit;
// Swap from Player 4 to Player 2
Player2[Passed_Cards[3]].number = Player4[Passed_Cards[9]].number;
Player2[Passed_Cards[3]].suit = Player4[Passed_Cards[9]].suit;
Player2[Passed_Cards[4]].number = Player4[Passed_Cards[10]].number;
Player2[Passed_Cards[4]].suit = Player4[Passed_Cards[10]].suit;
Player2[Passed_Cards[5]].number = Player4[Passed_Cards[11]].number;
Player2[Passed_Cards[5]].suit = Player4[Passed_Cards[11]].suit;
// Swap from Player 2 to Player 4
Player4[Passed_Cards[9]].number = temp_cards[0].number;
Player4[Passed_Cards[9]].suit = temp_cards[0].suit;
Player4[Passed_Cards[10]].number = temp_cards[1].number;
Player4[Passed_Cards[10]].suit = temp_cards[1].suit;
Player4[Passed_Cards[11]].number = temp_cards[2].number;
Player4[Passed_Cards[11]].suit = temp_cards[2].suit;
}
return;
} // End of pass_cards()
//*****************************************
// Function: add_to_passed_cards()
// Purpose: Add PlayerX[slot]'s card[value]
// to Passed_Cards[]
//*****************************************
void HEARTS::add_to_passed_cards(u8 slot, u8 value)
{
// Make sure the slot is valid
Passed_Cards[slot] = value;
return;
} // End of add_to_passed_cards()
void HEARTS::add_card(u8 player, u8 slot, u8 number, u8 suit)
{
switch (player)
{
case 1:
Player1[slot].number = number;
Player1[slot].suit = suit;
break;
case 2:
Player2[slot].number = number;
Player2[slot].suit = suit;
break;
case 3:
Player3[slot].number = number;
Player3[slot].suit = suit;
break;
case 4:
Player4[slot].number = number;
Player4[slot].suit = suit;
break;
}
return;
} // End of add_card()
//**********************************************
// Function: add_card_to_trick()
// Purpose: Add card to Trick[slot] from PlayerX
//**********************************************
void HEARTS::add_card_to_trick(u8 slot)
{
// Figure out who's turn it is
if (turn == 1) {
Trick[0].number = Player1[slot].number;
Trick[0].suit = Player1[slot].suit;
} else if (turn == 2) {
Trick[1].number = Player2[slot].number;
Trick[1].suit = Player2[slot].suit;
} else if (turn == 3) {
Trick[2].number = Player3[slot].number;
Trick[2].suit = Player3[slot].suit;
} else if (turn == 4) {
Trick[3].number = Player4[slot].number;
Trick[3].suit = Player4[slot].suit;
}
return;
} // End of add_card_to_trick()
//*******************************************
// Function: remove_card()
// Purpose: Zero out a card in PlayerX's hand
//*******************************************
void HEARTS::remove_card(u8 player, u8 slot)
{
if (player == 1) {
Player1[slot].number = 0;
Player1[slot].suit = 4;
} else if (player == 2) {
Player2[slot].number = 0;
Player2[slot].suit = 4;
} else if (player == 3) {
Player3[slot].number = 0;
Player3[slot].suit = 4;
} else if (player == 4) {
Player4[slot].number = 0;
Player4[slot].suit = 4;
}
return;
} // End of remove_card()
//****************************************************
// Function: get_card()
// Purpose: Returns the card at Player[]
//****************************************************
Card HEARTS::get_card(u8 player, u8 slot)
{
// Variables
Card temp;
temp.number = 0;
temp.suit = 0;
Card *Player = NULL;
// Make the pointer point to the correct Card array
if (player == 1) {
Player = Player1;
} else if (player == 2) {
Player = Player2;
} else if (player == 3) {
Player = Player3;
} else if (player == 4) {
Player = Player4;
}
temp.number = Player[slot].number;
temp.suit = Player[slot].suit;
return temp;
} // End of get_card()
bool HEARTS::is_first_trick()
{
return first_trick;
} // End of is_first_trick()
//************************************
// Function: anykey()
// Purpose: True if any key is pressed
//************************************
bool anykey()
{
return (F_CTRLINPUT_DOWN_PRESSED || F_CTRLINPUT_LEFT_PRESSED || F_CTRLINPUT_A_PRESSED ||
F_CTRLINPUT_UP_PRESSED || F_CTRLINPUT_RIGHT_PRESSED || F_CTRLINPUT_B_PRESSED ||
F_CTRLINPUT_START_PRESSED || F_CTRLINPUT_SELECT_PRESSED);
} // End of anykey()