Jump to content



Photo
- - - - -

Tron Game


  • Please log in to reply
3 replies to this topic

#1 GodOfCows

GodOfCows

    Casio Addict

  • Members
  • PipPipPip
  • 79 posts
  • Gender:Male

  • Calculators:
    fx-9860gii, fx-9750gii, TI-92, TI-89, TI-83 Plus

Posted 26 August 2018 - 09:59 PM

I made this this month when learning C. I would appreciate comments/concerns relating to the code (feedback?) so I can get better
/*****************************************************************/
/*                                                               */
/*   CASIO fx-9860G SDK Library                                  */
/*                                                               */
/*   File name : Tron.c                                          */
/*                                                               */
/*   Copyright (c) 2006 CASIO COMPUTER CO., LTD.                 */
/*                                                               */
/*****************************************************************/
#include "fxlib.h"


//****************************************************************************
//  AddIn_main (Sample program main function)
//
//  param   :   isAppli   : 1 = This application is launched by MAIN MENU.
//                        : 0 = This application is launched by a strip in eACT application.
//
//              OptionNum : Strip number (0~3)
//                         (This parameter is only used when isAppli parameter is 0.)
//
//  retval  :   1 = No error / 0 = Error
//
//****************************************************************************



unsigned int key;
/*
*Lock is used so a player cannot change the direction before the 
Game loop is done. This is done because, although the player cannot directly change direction 
Backwards, insta killing themselves, they *CAN* cycle though one direction, and then to a direction
which would insta killthem (going backwards). Lock is used to stop the change of direction two times in a row, 
and if statements stop the player from going backwards

* Exit is used to exit form the control loop when the game ends (and subsequently restarts the game though the while loop in main function)

*/
unsigned char lock1, lock2, exit;

unsigned char ai; //1=ai is on; 0= ai is off
 unsigned short map[13][25]; //The reprensentation of the map that will handle game functions such as deciding if someone has won or not
struct {
	short x; // x-axis value (used for the array)
	short y; //y-axis value (used for the array)
	short lives; //lives for a player, 1=still alive and 0=not alive
	short direction; //direction of player (see game loop for representation)
} player1, player2; //The two objects (I could just use other variables, but would be very cryptic)




int get_speed();
/*
* Get the speed players want to go at
*/
void draw_player1_part(unsigned char, unsigned char);
/*
* This function draws players 1 body to a location (only the image, does not affect calculations)
*/
void draw_player2_part(unsigned char, unsigned char);
/*
* This function draws players 2 body to a location (only the image, does not affect calculations)
*/
void draw_pieces(unsigned char, unsigned char, unsigned char, unsigned char);
/*
* This function executes both draw player functions (see above 2+)
* It also adjusts it so it equates to the 2-d array called map
*/
void endgame();
/*
* This function shows the end game menu, saying who has won and hwo hasn't
*/
void ai_function();
/*
* this function decides on whether or not the ai (player 2) should move or not
* called only if the ai variable is 1 (on)
*/
void gamefunction();
/*
* The main game loop that handles all calculation, error correction
* and if the player has won
*/
void control();
/*
* This function controls the key input (There is probably a better solution, but this is what works for the time being)
*/

int get_speed()
{
	Bdisp_AllClr_DDVRAM();
	PrintXY(0,0,"Press 1-4 for ai",0);
	PrintXY(0,10,"Press 5-8 for multi",0);
	PrintXY(0,20,"Lower the number",0);
	PrintXY(0,30,"The faster it will go",0);
	PrintMini(0,50,"By: NotSOSmartGuy",0);
	while (1){
		GetKey(&key);
		switch(key)
		{
			case KEY_CHAR_1:
			return 1;
			break;

			case KEY_CHAR_2:
			return 2;
			break;

			case KEY_CHAR_3:
			return 3;
			break;

			case KEY_CHAR_4:
			return 4;
			break;

			case KEY_CHAR_5:
			return 5;
			break;

			case KEY_CHAR_6:
			return 6;
			break;

			case KEY_CHAR_7:
			return 7;
			break;

			case KEY_CHAR_8:
			return 8;
			break;

			case KEY_CHAR_9:
			return 9;
			break;
		}
	}

}

/*
Below are the player drawing functions. player 2 is identical to player 1 however the middle pixel is taken out
5x5 pixels

*/
void draw_player1_part(unsigned char x, unsigned char y)
{
									Bdisp_SetPoint_VRAM(x,y-2,1);
	Bdisp_SetPoint_VRAM(x-1,y-1,1); Bdisp_SetPoint_VRAM(x,y-1,1); Bdisp_SetPoint_VRAM(x+1,y-1,1);
	Bdisp_SetPoint_VRAM(x-2,y,1); Bdisp_SetPoint_VRAM(x-1,y,1); Bdisp_SetPoint_VRAM(x,y,1); Bdisp_SetPoint_VRAM(x+1,y,1); Bdisp_SetPoint_VRAM(x+2,y,1);
	Bdisp_SetPoint_VRAM(x-1,y+1,1); Bdisp_SetPoint_VRAM(x,y+1,1); Bdisp_SetPoint_VRAM(x+1,y+1,1);
									Bdisp_SetPoint_VRAM(x,y+2,1);
}

void draw_player2_part(unsigned char x, unsigned char y)
{
									Bdisp_SetPoint_VRAM(x,y-2,1);
	Bdisp_SetPoint_VRAM(x-1,y-1,1); Bdisp_SetPoint_VRAM(x,y-1,1); Bdisp_SetPoint_VRAM(x+1,y-1,1);
	Bdisp_SetPoint_VRAM(x-2,y,1); Bdisp_SetPoint_VRAM(x-1,y,1); /*Bdisp_SetPoint_VRAM(x,y,1);*/ Bdisp_SetPoint_VRAM(x+1,y,1); Bdisp_SetPoint_VRAM(x+2,y,1);
	Bdisp_SetPoint_VRAM(x-1,y+1,1); Bdisp_SetPoint_VRAM(x,y+1,1); Bdisp_SetPoint_VRAM(x+1,y+1,1);
									Bdisp_SetPoint_VRAM(x,y+2,1);
}




void draw_pieces(unsigned char x, unsigned char y, unsigned char xx, unsigned char yy)
{

draw_player1_part(x*5,y*5);
draw_player2_part(xx*5,yy*5);
//Bdisp_PutDisp_DD();

}

void endgame()
{
	KillTimer(1); //Stop the gameloop from continueing after player dies
	Bdisp_AllClr_DDVRAM(); 

	if (player1.lives == 0 && player2.lives == 1) //If player 1 is dead but player 2 lives, say it
	{
		if (ai)
		PrintXY(0,0,"AI has won!",0);
		else	
		PrintXY(0,0,"Player 2 has won!",0);
	} else if (player1.lives == 1 && player2.lives == 0) { //If player 1 lives but player 2 is dead, say it
		if (ai)
			PrintXY(0,0,"You won!",0);
		else
		PrintXY(0,0,"Player 1 has won!", 0);
	} else if (player1.lives == 0 && player2.lives == 0) { //If both players have died, say it
		PrintXY(0,0,"Both players killed",0);
		PrintXY(0,10,"Themselves!",0);
	} else if (player1.lives == 1 && player2.lives == 1) {
		PrintXY(0,0,"Both players killed",0);
		PrintXY(0,10,"Themselves at the same",0);
		PrintXY(0,20,"time!",0);
	}
	PrintXY(0,30,"Press EXE to restart", 0); //No need to issue this in all above if else statements as it would be the same for any one of them
	Bdisp_PutDisp_DD(); //Put information on screen
Sleep(2000); //Sleep for 2 seconds so they don't press EXE immedietly
	exit = 1; //Set to 1 so we can exit the control loop (and restart the game)
}

void ai_function() 
{
/*
0=up
1=down
2=right
3=left
*/

if (player2.direction == 0) //going up
{
	if (player2.y == 1)
	{
		if (map[12][player2.x] == 3)
			if (map[player2.y][player2.x+1] == 3)
				player2.direction = 3;
			else if (map[player2.y][player2.x-1] == 3)
				player2.direction = 2;
			else player2.direction = 1;
	} else {
		if (map[player2.y-1][player2.x] == 3)
		if (map[player2.y][player2.x+1] == 3)
				player2.direction = 3;
			else if (map[player2.y][player2.x-1] == 3)
				player2.direction = 2;
			else player2.direction = 2;
	}

} else if (player2.direction == 1) { //going down
	if (player2.y == 12) {
		if (map[1][player2.y] == 3)
			if (map[player2.y][player2.x+1] == 3)
				player2.direction = 3;
			else if (map[player2.y][player2.x-1] == 3)
				player2.direction = 2;
			else player2.direction = 2;
	} else {
		if (map[player2.y-1][player2.x] == 3)
			if (map[player2.y][player2.x+1] == 3)
				player2.direction = 3;
			else if (map[player2.y][player2.x-1] == 3)
				player2.direction = 2;
			else player2.direction = 2;
	} 
} else if (player2.direction == 2) { //going right
	if (player2.x == 24)
	{
		if (map[player2.y][1] == 3)
			if (map[player2.y+1][player2.x] == 3)
				player2.direction = 1;
			else if (map[player2.y-1][player2.x] == 3)
				player2.direction = 0;
			else player2.direction = 0;
	} else 
		if (map[player2.y][player2.x+1] == 3)
			if (map[player2.y+1][player2.x] == 3)
				player2.direction = 0;
			else if (map[player2.y-1][player2.x] == 3)
				player2.direction = 1;
			else player2.direction = 1;
	
} else if (player2.direction == 3) { //going left
	if (player2.x == 1)
	{
		if (map[player2.y][24] == 3)
			if (map[player2.y+1][player2.x] == 3)
				player2.direction = 1;
			else if (map[player2.y-1][player2.x] == 3)
				player2.direction = 0;
			else player2.direction = 0;
	} else if (map[player2.y][player2.x-1] == 3)
	if (map[player2.y+1][player2.x] == 3)
		player2.direction = 0;
	else if (map[player2.y-1][player2.x] == 3)
		player2.direction = 1;
	else player2.direction = 0;
}
}
/* 
} else if (player2.direction == 2) {
	if (player2.x == 24)
	{
		if (map[player2.y][1] == 3)
			if (map[player2.y+1][player2.x] == 3)
				player2.direction = 1;
			else if (map[player2.y-1][player2.x] == 3)
				player2.direction = 0;
	} else {
		if (map[player2.y][player2.x+1] == 3)
			if (map[player2.y+1][player2.x] == 3)
				player2.direction = 1;
			else if (map[player2.y-1][player2.x] == 3)
				player2.direction = 0;
	}
} 
*/


void gamefunction()
{
	 /*static short map[12][25] = {
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25}
};*/ 
/*
1 = Player 1' snake' head
2 = Player 2' snake' head
3 = The body of a snake, since a player can kill themselves
by the body of their own snake by touching it with the head 
of their snake, it does not matter what body the head touches,
since you die either way

0 = up
1 = down
2 = right 
3 = left
*/

//convert the previous location to a general snake body
map[player1.y][player1.x] = 3;

map[player2.y][player2.x] = 3;

if (ai)
{
ai_function();
}

//add or minus to the cordinate of the player
if (player1.direction == 0)
{
player1.y--;
} else if (player1.direction == 1) {
	player1.y++;
} else if (player1.direction == 2) {
	player1.x++;
} else if (player1.direction == 3) {
	player1.x--;
}

//Same for player 2
if (player2.direction == 0)
{
player2.y--;
} else if (player2.direction == 1) {
	player2.y++;
} else if (player2.direction == 2) {
	player2.x++;
} else if (player2.direction == 3) {
	player2.x--;
}

//addjust the players cordinates so we don't get an buffer overflow
if (player1.x <= 0)
	player1.x = 24;

if (player1.x > 24)
	player1.x = 1;

if (player1.y <= 0)
	player1.y = 12;

if (player1.y > 12)
	player1.y = 1;

if (player2.x <= 0)
	player2.x = 24;

if (player2.x > 24)
	player2.x = 1;

if (player2.y <= 0)
	player2.y = 12;

if (player2.y > 12)
	player2.y = 1;


//check if the player has lost by touching the body of a snake, and to see whitch one it is

if (map[player2.y][player2.x] + 2 == 5 && map[player1.y][player1.x] + 1 == 4) {
	endgame();
} else if (map[player1.y][player1.x] + 1 == 4) {
	player1.lives = 0;
	endgame();
} else if (map[player2.y][player2.x] + 2 == 5) {
	player2.lives = 0;
	endgame();
} else if (player1.x == player2.x && player1.y == player2.y) {
	player1.lives = 0;
	player2.lives = 0;
	endgame();
} else {
	//If no one has died, then add the new points
map[player1.y][player1.x] = 1; 
map[player2.y][player2.x] = 2;
lock1 = 0; //allows for the player to move
lock2 = 0;  //same as previous
draw_pieces(player1.x, player1.y, player2.x, player2.y); //Render the new snake pieces
Bdisp_PutDisp_DD();
}

}


void control()
{
	

	while (1)
	{
		GetKey(&key);

		switch (key) 
		{
			case KEY_CTRL_UP:
			if (player1.direction != 1 && !lock1) //If the player is already going down, it won't be able to go up and insta kill themselfe
			{
				player1.direction = 0;
				lock1 = 1;
			}
			break;
			case KEY_CTRL_DOWN:
			if (player1.direction != 0 && !lock1)  //If the player is alreay going up, they won't be able to go up and insta kill themselfe
			{
				player1.direction = 1;
				lock1 = 1;
			}
			break;
			case KEY_CTRL_RIGHT: 
			if (player1.direction != 3 && !lock1) //If the player is already moving left, they won't be bale to go right and insta kill themselfe
			{
				player1.direction = 2;
				lock1 = 1;
			}
			break;
			case KEY_CTRL_LEFT:
			if (player1.direction != 2 && !lock1) //if The player is already moving right, they won't be able to go left and insta kill themselfes
			{
				player1.direction = 3;
				lock1 = 1;
			}
			break;
			
		}
		
		if(!ai) {
		switch (key)
		{

			case KEY_CHAR_8:
			if (player2.direction != 1 && !lock2) //Same as above
			{
				player2.direction = 0;
				lock2 = 1;
			}
			break;
			case KEY_CHAR_2:
			if (player2.direction != 0 && !lock2) //Same as above
			{
				player2.direction = 1;
				lock2 = 1;
			}
			break;
			case KEY_CHAR_6:
			if (player2.direction != 3 && !lock2) //Same as above
			{
				player2.direction = 2;
				lock2 = 1;
			}
			break;
			case KEY_CHAR_4:
			if (player2.direction != 2 && !lock2) //Same as above
			{
				player2.direction = 3;
				lock2 = 1;
			}
			break;
		}
	} // if end

	if (exit == 1) // if the game has ended (see endgame function), break out of the loop, resuming the while loop in addin
		break;
	}
}


int AddIn_main(int isAppli, unsigned short OptionNum)
{
    unsigned char x,y; //Used in the for loop
    unsigned char speed; //for speed
    Bdisp_AllClr_DDVRAM();

   

   
while (1)
{
	//GetKey(&key);
	/*
     * When the game loop ends (player has lost and presses EXE)
     * This while loop restarts, initializing the variables
     * And essentially restarting the game as though the add-in just restarted
	*/
	Bdisp_AllClr_DDVRAM(); 
	//For definitions of these variables, see top of source where variables are delcared
ai = 0;
exit = 0; 
lock1 = 0;
lock2 = 0;
player1.x = 1; //Set to 1 to match location in array
player1.y = 6; //Same as above
player2.x = 24; //Same as above
player2.y = 6; //Same as above
player1.lives = 1; //1 = still alive
player2.lives = 1; //Same as previous
player1.direction = 2; //Direction the player1 is going (see gamefunction for number representation)
player2.direction = 3; //Same as previous but for player2

speed = get_speed();

if (speed <= 4)
	ai = 1;
else ai = 0;

if (speed >= 5)
{
	switch (speed)
	{
		case 5:
		speed = 1;
		break;
		case 6:
		speed = 2;
		break;
		case 7: 
		speed = 3;
		break;
		case 8:
		speed = 4;
		break;
	}
}

Bdisp_AllClr_DDVRAM();

for (y = 0; y <= 12; y++) for (x = 0; x <= 24; x++) 
map[y][x] = 5; //Sets all variables in the array to 0, for loops is the easiest way to do this

 map[6][1] = 1; //1 = Players 1 head of snake/whatever you call it
 map[6][24] = 2; //Same as player 1 but for player 2
 draw_pieces(player1.x, player1.y, player2.x, player2.y); //Initially draw the first snake part, as the gameloop renders image at end of updateing information

	SetTimer(1,speed*100,gamefunction); //Start the gameloop
	control(); //Start gathering information on keys pressed

}

 

   

    return 1;
}




//****************************************************************************
//**************                                              ****************
//**************                 Notice!                      ****************
//**************                                              ****************
//**************  Please do not change the following source.  ****************
//**************                                              ****************
//****************************************************************************


#pragma section _BR_Size
unsigned long BR_Size;
#pragma section


#pragma section _TOP

//****************************************************************************
//  InitializeSystem
//
//  param   :   isAppli   : 1 = Application / 0 = eActivity
//              OptionNum : Option Number (only eActivity)
//
//  retval  :   1 = No error / 0 = Error
//
//****************************************************************************
int InitializeSystem(int isAppli, unsigned short OptionNum)
{
    return INIT_ADDIN_APPLICATION(isAppli, OptionNum);
}

#pragma section






#2 tnt84268

tnt84268

    Casio Fan

  • Members
  • PipPip
  • 32 posts
  • Gender:Male
  • Location:The Universe

  • Calculators:
    fx-9750gii (ver 2.04)

Posted 05 September 2018 - 01:29 AM

In your ai_function(), you can clean up your if statements by using && so you aren't nesting as many if statements.

 

Although I don't know too much about c code, overall it looks pretty good.



#3 GodOfCows

GodOfCows

    Casio Addict

  • Members
  • PipPipPip
  • 79 posts
  • Gender:Male

  • Calculators:
    fx-9860gii, fx-9750gii, TI-92, TI-89, TI-83 Plus

Posted 05 September 2018 - 01:42 AM

Thanks for the comment, I see what you mean. Looking back at the code, there is a lot of nesting.



#4 GodOfCows

GodOfCows

    Casio Addict

  • Members
  • PipPipPip
  • 79 posts
  • Gender:Male

  • Calculators:
    fx-9860gii, fx-9750gii, TI-92, TI-89, TI-83 Plus

Posted 04 January 2019 - 04:37 AM

Video if anyone wants to see: 

 

https://youtu.be/JlYFgQ6bULw






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users