You are on page 1of 15

/****************************************************************************

Header file for Game SM


based on the Gen2 Events and Services Framework
Author: Kacyn Fujii Date: 11/2/14
Final Editing: Dongao Yang 11/25/2014
****************************************************************************/
#ifndef Game_H
#define Game_H
// Event
#include
#include
#include

Definitions
"ES_Configure.h" /* gets us event definitions */
"ES_Types.h"
/* gets bool type for returns */
"ES_Framework.h"

#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
//used for gpio
#include "ES_Port.h"
#include "termio.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "inc/hw_sysctl.h"
#include "driverlib/gpio.h"
#define ALL_BITS (0xff<<2)
// Event
#include
#include
#include

Definitions
"ES_Configure.h" /* gets us event definitions */
"ES_Types.h"
/* gets bool type for returns */
"ES_Framework.h"

// typedefs for the states


typedef enum {TerrorState, WaitForTiltInput, WaitForScore, ScoreMade,
WaitForSnitchPress, HappyState} GameState_t ;
// Public Function Prototypes
bool InitGameFSM ( uint8_t Priority );
bool PostGameFSM( ES_Event ThisEvent );
ES_Event RunGameFSM( ES_Event ThisEvent );
#endif
/****************************************************************************
Module
Game.c
Description
The major state machine of the game.
Author: Kacyn Fujii Date: 11/2/14

Final Edit: Dongao Yang 11/25/14


****************************************************************************/
/*----------------------------- Include Files -----------------------------*/
/* include header files for this state machine as well as any machines at the
next lower level in the hierarchy that are sub-machines to this machine
*/
#include "ES_Configure.h"
#include "ES_Framework.h"
#include "Game.h"
#include "EventCheckers.h"
#include "TargetLED.h"
#include "Hoop.h"
#include "Countdown.h"
#include "GeneralBase.h"
#include "Button.h"
#include "Broom.h"
#include "Music.h"
/*----------------------------- Module Defines ----------------------------*/
// BIT number corresponding to all target LEDs
#define rightRedLED BIT4HI
#define centerRedLED BIT5HI
#define leftRedLED BIT6HI
#define rightGreenLED BIT1HI
#define centerGreenLED BIT2HI
#define leftGreenLED BIT3HI
// IR IO input port
#define IRport 'F'
// IR IO input pins
#define IRpin1 BIT4HI
#define IRpin2 BIT3HI
#define IRpin3 BIT2HI
// BIT number corresponding to all hoops
#define LEFT_HOOP BIT2HI;
#define CENTER_HOOP BIT1HI;
#define RIGHT_HOOP BIT0HI;
// The score threshold to trigger the snitch
#define ScoreLimit 5
/*---------------------------- Module Functions ---------------------------*/
/* prototypes for private functions for this machine.They should be functions
relevant to the behavior of this state machine
*/
void PickNextHoop(void);
/*---------------------------- Module Variables ---------------------------*/
// everybody needs a state variable, you may need others as well.
// type of state variable should match htat of enum in header file
static GameState_t CurrentState;
// variable to track the open hoop
static int openHoop;
// variable to track status of red target LEDs
static uint8_t redLEDStatus;
// variable to track status of green target LEDs
static uint8_t greenLEDStatus;

// variable to trigger the 30S game key


static bool SnitchTimerRunning;
// with the introduction of Gen2, we need a module level Priority var as well
static uint8_t MyPriority;
// variable to trigger the status of blinking LED button
static uint8_t ButtonBlinkStatus;
/*------------------------------ Module Code ------------------------------*/
/****************************************************************************
Function
InitGameFSM
Parameters
uint8_t : the priorty of this service
Returns
bool, false if error in initialization, true otherwise
Description
Saves away the priority, sets up the initial transition and initialize
all pins needed.
Final Edit: Dongao Yang 11/25/14
****************************************************************************/
bool InitGameFSM ( uint8_t Priority )
{
//Initialize the priority for this SM
MyPriority = Priority;
//Initialize the target LED pins
InitTargetLED();
//Initialize the hoop pins
InitHoops();
//Initialize the music control pins
InitMusic();
//Reset music module
ResetMusic();
//Play the first music
PlayFirst();
//Activate the system clock of IR port
InitSystemClock(IRport);
//Initialize all IR pins to IO
InitPinIO(IRport, IRpin3);
InitPinIO(IRport, IRpin2);
InitPinIO(IRport, IRpin1);
//Initialize all IR pins to IO input
InitPinDir(IRport, IRpin3, 0);
InitPinDir(IRport, IRpin2, 0);
InitPinDir(IRport, IRpin1, 0);
//Turn on the LED on the button
SnitchLEDOn();
//Initialize button led blink status
ButtonBlinkStatus = 1;
//Start button LED blink timer, 1S
ES_Timer_InitTimer(BUTTONBLINK_TIMER, 1000);
//Initialize the state to TerrorState
CurrentState = TerrorState;
return true;

}
/****************************************************************************
Function
PostGameFSM
Parameters
ES_Event ThisEvent , the event to post to the queue
Returns
boolean False if the Enqueue operation failed, True otherwise
Description
Posts an event to this state machine's queue
Notes
Final Edit: Dongao Yang 11/25/14
****************************************************************************/
bool PostGameFSM( ES_Event ThisEvent )
{
return ES_PostToService( MyPriority, ThisEvent);
}
/****************************************************************************
Function
RunGameFSM
Parameters
ES_Event : the event to process
Returns
ES_Event, ES_NO_EVENT if no error ES_ERROR otherwise
Description
Runs main state machine for the whole game
Final Edit: Dongao Yang 11/25/14
****************************************************************************/
ES_Event RunGameFSM( ES_Event ThisEvent )
{
// Event to return at the end, ES_NO_EVENT
ES_Event ReturnEvent;
ReturnEvent.EventType = ES_NO_EVENT; // assume no errors
// Event to post to countdown SM
ES_Event TimerEvent;
// Event to post to Broom SM
ES_Event BroomEvent;
// Set Next state to current state
GameState_t NextState = CurrentState;
// variable to track the current score
static uint8_t score;
/*In this switch statement, the possible states are: TerrorState,
WaitForTiltInput, WaitForScore, WaitForSnitchPress, and HappyState*/
// switch on current state
switch ( CurrentState )
{

//If the state is TerrorState


case TerrorState:
//If the event is button down
if (ThisEvent.EventType == ES_BUTTON_DOWN)
{
//Play the first music
PlayFirst();
//Post start count event to countdown module
TimerEvent.EventType = START_COUNT;
PostCountdownFSM(TimerEvent);
//Turn off the button LEDs
SnitchLEDOff();
//Post tilt ready event to Broom module
BroomEvent.EventType = TILT_READY;
PostBroomFSM( BroomEvent);
//Set open hoop track variable to middle
openHoop = CENTER_HOOP;
//Lift the middle hoop
MoveHoopUp(openHoop);
//Set score track to 0
score = 0;
//Set all Green target LEDs status to 0
greenLEDStatus = 0;
//Start the main game timer, 60S
ES_Timer_InitTimer(GAME_TIMER, 60000);
//Start the snitch game key timer, 30S
ES_Timer_InitTimer(SNITCH_TIMER, 30000);
//Set the snitch game key to 0
SnitchTimerRunning = 0;
//Set next state to wait for tilt
NextState = WaitForTiltInput;
}
//if the event is ES_TIMEOUT and posted by button blink
timer
else if (ThisEvent.EventType == ES_TIMEOUT &&
ThisEvent.EventParam == BUTTONBLINK_TIMER)
{
// if the blink status is on
if(ButtonBlinkStatus == 1)
{
//Turn off the button LED
SnitchLEDOff();
//Change button blink status to 0
ButtonBlinkStatus = 0;
//Restart the button blink timer, 0.5S
ES_Timer_InitTimer(BUTTONBLINK_TIMER, 500);
}
else
{
//Turn on the button LED
SnitchLEDOn();
//Change button blink status to 1
ButtonBlinkStatus = 1;
//Restart the button blink timer, 1S
ES_Timer_InitTimer(BUTTONBLINK_TIMER, 1000);
}
}

break;
// If current state is wait for tilt
case WaitForTiltInput :
// switch on event type
switch ( ThisEvent.EventType )
{
//if the event is LEFT_TILT_DETECTED
case LEFT_TILT_DETECTED :
//set red target LEDs status to left
redLEDStatus = leftRedLED;
//light new arrangement on target LED
LightTargetLED(redLEDStatus | greenLEDStatus);
//If left is the right tilt
if(openHoop == LEFT_HOOP)
{
//Set next state to wait for score
NextState = WaitForScore;
}
break;
//if the event is CENTER_TILT_DETECTED
case CENTER_TILT_DETECTED :
//set red target LEDs status to center
redLEDStatus = centerRedLED;
//light new arrangement on target LED
LightTargetLED(redLEDStatus | greenLEDStatus);
//If center is the right tilt
if(openHoop == CENTER_HOOP)
{
//Set next state to wait for score
NextState = WaitForScore;
}
break;
//if the event is RIGHT_TILT_DETECTED
case RIGHT_TILT_DETECTED :
//set red target LEDs status to right
redLEDStatus = rightRedLED;
//light new arrangement on target LED
LightTargetLED(redLEDStatus | greenLEDStatus);
//If right is the right tilt
if(openHoop == RIGHT_HOOP)
{
//Set next state to wait for score
NextState = WaitForScore;
}
break;
//If event is ES_TIMEOUT
case ES_TIMEOUT :
//switch on event param (timer)
switch(ThisEvent.EventParam)
{
//If main timer expired
case GAME_TIMER:
//Post STOP_COUNT to countdown module
TimerEvent.EventType = STOP_COUNT;
PostCountdownFSM(TimerEvent);
//Light all timer LEDs

LightAllTimerLEDs();
//Close all hoops
MoveHoopDown(BIT0HI);
MoveHoopDown(BIT1HI);
MoveHoopDown(BIT2HI);
//Start the reset timer, 15S
ES_Timer_InitTimer(HAPPY_TIMER, 15000);
//Post CAPTURE_SNITCH_READY event to Broom
BroomEvent.EventType = CAPTURE_SNITCH_READY;
PostBroomFSM( BroomEvent);
//Set next state to HappyState
NextState = HappyState;
break;
//If snitch timer expired
case SNITCH_TIMER:
//Set snitch key value to 1
SnitchTimerRunning = 1;
break;
//If Green LED timer expired
case GLED_TIMER:
//Set all green light to 0
greenLEDStatus = 0;
//light new arrangement on target LED
LightTargetLED(redLEDStatus | greenLEDStatus);
//Shut down the vibration
VibrationOff();
break;
}// end switch on timer
break;
default :
;
}// end switch on event type
break;
// If the current state is wait for score
case WaitForScore :
// Switch on event type
switch(ThisEvent.EventType)
{
//If the event is LEFT_TILT_DETECTED
case LEFT_TILT_DETECTED :
//set red target LEDs status to left
redLEDStatus = leftRedLED;
//light new arrangement on target LED
LightTargetLED(redLEDStatus | greenLEDStatus);
//if left is not right tilt
if(openHoop != LEFT_HOOP)
{
//Set next state to wait for tilt
NextState = WaitForTiltInput;
}
break;
//If the event is CENTER_TILT_DETECTED
case CENTER_TILT_DETECTED :
//set red target LEDs status to center
redLEDStatus = centerRedLED;
//light new arrangement on target LED
LightTargetLED(redLEDStatus | greenLEDStatus);

//if center is not right tilt


if(openHoop != CENTER_HOOP)
{
//Set next state to wait for tilt
NextState = WaitForTiltInput;
}
break;
//If the event is RIGHT_TILT_DETECTED
case RIGHT_TILT_DETECTED :
//set red target LEDs status to right
redLEDStatus = rightRedLED;
//light new arrangement on target LED
LightTargetLED(redLEDStatus | greenLEDStatus);
//if right is not right tilt
if(openHoop != RIGHT_HOOP)
{
//Set next state to wait for tilt
NextState = WaitForTiltInput;
}
break;
//If the event is LEFT_BALL_DETECTED
case LEFT_BALL_DETECTED :
//If Left is right hoop position
if(openHoop == LEFT_HOOP)
{
//if score haven't reached the threshold or snitch
key is 0
if (score<ScoreLimit||SnitchTimerRunning == 0)
{
//increase score by 1
++score;
//close current open hoop
MoveHoopDown(openHoop);
//randomly pick another hoop
PickNextHoop();
//open this hoop
MoveHoopUp(openHoop);
//set green LED to left
greenLEDStatus = leftGreenLED;
//light new LED arrangement
LightTargetLED(redLEDStatus | greenLEDStatus);
//turn on the vibration
VibrationOn();
//Start the green LED timer, 2S
ES_Timer_InitTimer(GLED_TIMER, 2000);
//Set Next state to wait for tilt
NextState = WaitForTiltInput;
}
else
{
//increase score by 1
++score;
//close current open hoop
MoveHoopDown(openHoop);
//set green LED to left
greenLEDStatus = leftGreenLED;

//light new LED arrangement


LightTargetLED(redLEDStatus | greenLEDStatus);
//turn on the vibration
VibrationOn();
//Start the green LED timer, 2S
ES_Timer_InitTimer(GLED_TIMER, 2000);
//turn on the button LED
SnitchLEDOn();
//Set the button blink status to 1
ButtonBlinkStatus = 1;
//Start the Button blink timer, 0.5S
ES_Timer_InitTimer(BUTTONBLINK_TIMER, 500);
//Set next state to WaitForSnitchPress
NextState = WaitForSnitchPress;
}
}
break;
//If the event is CENTER_BALL_DETECTED
case CENTER_BALL_DETECTED :
//If center is right hoop position
if(openHoop == CENTER_HOOP)
{
//if score haven't reached the threshold or snitch
key is 0
if (score<ScoreLimit||SnitchTimerRunning == 0)
{
//increase score by 1
++score;
//close current open hoop
MoveHoopDown(openHoop);
//randomly pick another hoop
PickNextHoop();
//open this hoop
MoveHoopUp(openHoop);
//set green LED to center
greenLEDStatus = centerGreenLED;
//light new LED arrangement
LightTargetLED(redLEDStatus | greenLEDStatus);
//turn on the vibration
VibrationOn();
//Start the green LED timer, 2S
ES_Timer_InitTimer(GLED_TIMER, 2000);
//Set Next state to wait for tilt
NextState = WaitForTiltInput;
}
else
{
//increase score by 1
++score;
//close current open hoop
MoveHoopDown(openHoop);
//set green LED to center
greenLEDStatus = centerGreenLED;
//light new LED arrangement
LightTargetLED(redLEDStatus | greenLEDStatus);
//turn on the vibration
VibrationOn();

//Start the green LED timer, 2S


ES_Timer_InitTimer(GLED_TIMER, 2000);
//turn on the button LED
SnitchLEDOn();
//Set the button blink status to 1
ButtonBlinkStatus = 1;
//Start the Button blink timer, 0.5S
ES_Timer_InitTimer(BUTTONBLINK_TIMER, 500);
//Set next state to WaitForSnitchPress
NextState = WaitForSnitchPress;
}
}
break;
//If the event is RIGHT_BALL_DETECTED
case RIGHT_BALL_DETECTED :
//If right is right hoop position
if(openHoop == RIGHT_HOOP)
{
//if score haven't reached the threshold or snitch
key is 0
if (score<ScoreLimit||SnitchTimerRunning == 0)
{
//increase score by 1
++score;
//close current open hoop
MoveHoopDown(openHoop);
//randomly pick another hoop
PickNextHoop();
//open this hoop
MoveHoopUp(openHoop);
//set green LED to right
greenLEDStatus = rightGreenLED;
//light new LED arrangement
LightTargetLED(redLEDStatus | greenLEDStatus);
//turn on the vibration
VibrationOn();
//Start the green LED timer, 2S
ES_Timer_InitTimer(GLED_TIMER, 2000);
//Set Next state to wait for tilt
NextState = WaitForTiltInput;
}
else
{
//increase score by 1
++score;
//close current open hoop
MoveHoopDown(openHoop);
//set green LED to right
greenLEDStatus = rightGreenLED;
//light new LED arrangement
LightTargetLED(redLEDStatus | greenLEDStatus);
//turn on the vibration
VibrationOn();
//Start the green LED timer, 2S
ES_Timer_InitTimer(GLED_TIMER, 2000);
//turn on the button LED
SnitchLEDOn();

//Set the button blink status to 1


ButtonBlinkStatus = 1;
//Start the Button blink timer, 0.5S
ES_Timer_InitTimer(BUTTONBLINK_TIMER, 500);
//Set next state to WaitForSnitchPress
NextState = WaitForSnitchPress;
}
}
break;
// If the event is ES_TIMEOUT
case ES_TIMEOUT :
// switch on even param (timer)
switch(ThisEvent.EventParam)
{
//if GAME_TIMER expired
case GAME_TIMER:
// Post STOP_COUNT event to count down module
TimerEvent.EventType = STOP_COUNT;
PostCountdownFSM(TimerEvent);
// Light all timer LEDs
LightAllTimerLEDs();
// Close all hoops
MoveHoopDown(BIT0HI);
MoveHoopDown(BIT1HI);
MoveHoopDown(BIT2HI);
// Post CAPTURE_SNITCH_READY event to Broom module
BroomEvent.EventType = CAPTURE_SNITCH_READY;
PostBroomFSM( BroomEvent);
// Start reset timer, 15S
ES_Timer_InitTimer(HAPPY_TIMER, 15000);
// Set next state to HappyState
NextState = HappyState;
break;
//if SNITCH_TIMER expired
case SNITCH_TIMER:
//Set snitch key to 1
SnitchTimerRunning = 1;
break;
//if Green LED timer expired
case GLED_TIMER:
//set all green LED to 0
greenLEDStatus = 0;
//light new LED arrangement
LightTargetLED(redLEDStatus | greenLEDStatus);
//turn off the vibration
VibrationOff();
break;
}//end switch on timer
break;
default :
;
} // end switch on event type
break;
//If current state is WaitForSnitchPress
case WaitForSnitchPress :

//If event is button down


if (ThisEvent.EventType == ES_BUTTON_DOWN)
{
//Post event STOP_COUNT to countdown module
TimerEvent.EventType = STOP_COUNT;
PostCountdownFSM(TimerEvent);
//Post event CAPTURE_SNITCH_READY to countdown module
BroomEvent.EventType = CAPTURE_SNITCH_READY;
PostBroomFSM( BroomEvent);
//Set all green LED to 1
greenLEDStatus = (rightGreenLED | centerGreenLED |
leftGreenLED);
//Set all Red LED to 0
redLEDStatus = 0;
//Light new LED arrangement
LightTargetLED(redLEDStatus | greenLEDStatus);
//Turn off the vibration
VibrationOff();
//Open all hoops
MoveHoopUp(BIT0HI);
MoveHoopUp(BIT1HI);
MoveHoopUp(BIT2HI);
//Turn off the button LED
SnitchLEDOff();
//Start Reset timer, 30S
ES_Timer_InitTimer(HAPPY_TIMER, 30000);
//Turn off the DDM state, output 0V
DDMOff();
//Play the second music
PlaySecond();
//Set Next state to HappyState
NextState = HappyState;
}
//If the event type is ES_TIMEOUT
else if (ThisEvent.EventType == ES_TIMEOUT)
{
//If GAME_TIMER expired
if(ThisEvent.EventParam == GAME_TIMER)
{
//Post STOP_COUNT event to countdown module
TimerEvent.EventType = STOP_COUNT;
PostCountdownFSM(TimerEvent);
//turn on all timer LEDs
LightAllTimerLEDs();
//close all hoops
MoveHoopDown(BIT0HI);
MoveHoopDown(BIT1HI);
MoveHoopDown(BIT2HI);
//Post CAPTURE_SNITCH_READY event to Broom
module
BroomEvent.EventType = CAPTURE_SNITCH_READY;
PostBroomFSM( BroomEvent);
//Start reset timer, 15S
ES_Timer_InitTimer(HAPPY_TIMER, 15000);
//Set next state to HappyState
NextState = HappyState;
}

//If Button Blink timer expired


else if (ThisEvent.EventParam == BUTTONBLINK_TIMER)
{
//If button blink is on
if(ButtonBlinkStatus == 1)
{
//turn off the button LED
SnitchLEDOff();
//set button blink status to 0
ButtonBlinkStatus = 0;
//start the button blink timer 0.25S
ES_Timer_InitTimer(BUTTONBLINK_TIMER,
250);
}
else
{
//turn on the button LED
SnitchLEDOn();
//set button blink status to 1
ButtonBlinkStatus = 1;
//start the button blink timer 0.5S
ES_Timer_InitTimer(BUTTONBLINK_TIMER,
500);
}
}
}
break;
//If current state is HappyState
case HappyState :
// if event is ES_TIMEOUT
if (ThisEvent.EventType == ES_TIMEOUT)
{
//if HAPPY_TIMER expired
if(ThisEvent.EventParam == HAPPY_TIMER)
{
//Close all hoops
MoveHoopDown(BIT0HI);
MoveHoopDown(BIT1HI);
MoveHoopDown(BIT2HI);
//Set all green LED to 0
greenLEDStatus = 0;
//Set all red LED to 0
redLEDStatus = 0;
//light new LED arrangement
LightTargetLED(redLEDStatus | greenLEDStatus);
//Turn off the vibration
VibrationOff();
//Turn off the button LED
SnitchLEDOn();
//Play the first music
PlayFirst();
//Turn on the DDM, output 5V
DDMOn();
//Set Button blink statuse to 1
ButtonBlinkStatus = 1;
//Start Button blink timer, 1S

ES_Timer_InitTimer(BUTTONBLINK_TIMER, 1000);
//Set Next state to TerrorState
NextState = TerrorState;
}
}
break;
default :
;
} // end switch on current state
// set current state to next state
CurrentState = NextState;
// return ES_NO_EVENT
return ReturnEvent;
}
/***************************************************************************
private functions
***************************************************************************/
/****************************************************************************
Function
PickNextHoop
Parameters
nothing
Returns
nothing
Description
Randomly pick a hoop, can't choose repeat hoop
Final Edit: Dongao Yang 11/25/14
****************************************************************************/
void PickNextHoop(void)
{
//Generate a random number from 0 to 1
double random = (double)rand() / (double)RAND_MAX ;
//If current hoop is left
if (openHoop == LEFT_HOOP)
{
//if random number is less than 0.5
if (random<0.5)
// next hoop is center hoop
openHoop = CENTER_HOOP;
else
// next hoop is right hoop
openHoop = RIGHT_HOOP;
}
//If current hoop is center
else if(openHoop == CENTER_HOOP)
{
//if random number is less than 0.5
if (random<0.5)
// next hoop is left hoop
openHoop = LEFT_HOOP;

else
// next hoop is right hoop
openHoop = RIGHT_HOOP;
}
//If current hoop is right
else if(openHoop== RIGHT_HOOP)
{
//if random number is less than 0.5
if (random<0.5)
// next hoop is center hoop
openHoop = CENTER_HOOP;
else
// next hoop is left hoop
openHoop = LEFT_HOOP;
}
}

You might also like