Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <conio.h>
- #include <unistd.h>
- #include <pthread.h>
- #include <time.h>
- #include <windows.h>
- //game table size
- #define HEIGHT 20
- #define LENGHT 40
- //how many lines of free space does player have to operate
- #define SPACEFORPLAYER 10
- #define BORDERS 'x'
- #define PLAYERSHELL '*'
- #define ENEMYSHELL '!'
- //Can be used to modify ship models but ship fragments are hardcoded in this iteration so it will require further changes
- #define SHIPHEIGHT 1
- #define SHIPLENGHT 3
- #define ENEMYSHIPCOUNT (LENGHT/4)*((HEIGHT-SPACEFORPLAYER)/2)
- #define ENEMYAPPROXCOUNT (LENGHT/3)
- static char gameTable[HEIGHT][LENGHT];
- const char enemyShip[SHIPHEIGHT][SHIPLENGHT]={{'|','^','|'}};//shipType 'e' for enemy
- const char playerShip[SHIPHEIGHT][SHIPLENGHT]={{'(','=',')'}};//shipTtype 'p' for player
- pthread_mutex_t lockRefresh=PTHREAD_MUTEX_INITIALIZER;
- pthread_t shot;
- pthread_t enemyShot;
- pthread_t enemyShotDelay;
- pthread_t gtimer;
- typedef struct
- {
- size_t shotPosX;
- size_t shotPosY;
- }shootingParams;
- void GameTableInitiate();
- void GameStatePrint();
- void ClearScreen();
- void AddEnemies();
- void DrawShip(char shipType, size_t shipPosX, size_t shipPosY);
- void ClearShip(size_t shipPosX,size_t shipPosY);//used both in movement as well as when you hit enemy
- void TestForGameOver(size_t shipPosX,size_t shipPosY);
- void PlayerMovement(size_t shipPosX,size_t shipPosY);
- void ShootingInputConversion(size_t shipPosX,size_t shipPosY);
- void *PlayerShooting(void *pShooting);
- void EnemyShipDestroy(size_t shipPosX, size_t shipPosY);
- shootingParams scanForEnemy();
- void *EnemyShooting(void *f);
- void *EnemyShootingDelay();
- void *GlobalTimer();
- int main()
- {
- GameTableInitiate(gameTable[HEIGHT][LENGHT]);
- AddEnemies();
- //print starting position of the ship-last possible lane on x and i the middle of y
- size_t shipPosX=HEIGHT-2;
- size_t shipPosY=LENGHT/2;
- DrawShip('p', shipPosX,shipPosY);
- GameStatePrint(gameTable[HEIGHT][LENGHT]);
- scanForEnemy();
- pthread_create(&enemyShotDelay,NULL,EnemyShootingDelay,NULL);
- pthread_create(>imer,NULL,GlobalTimer,NULL);
- PlayerMovement(shipPosX,shipPosY);
- return 0;
- }
- void GameTableInitiate()
- {
- for(size_t i=0;i<HEIGHT;i++)
- {
- for(size_t j=0;j<LENGHT;j++)
- {
- if(i==0||i==HEIGHT-1)
- {
- gameTable[i][j]=BORDERS;
- }
- else
- {
- gameTable[i][j]=' ';
- gameTable[i][0]=BORDERS;
- gameTable[i][LENGHT-1]=BORDERS;
- }
- }
- }
- }
- void GameStatePrint()
- {
- //in case if some 1 wanted to make it as a pthread close func in while(1)
- pthread_mutex_lock(&lockRefresh);
- ClearScreen();
- for(size_t i=0;i<HEIGHT;i++)
- {
- for(size_t j=0;j<LENGHT;j++)
- {
- printf("%c", gameTable[i][j]);
- }
- printf("\n");
- }
- pthread_mutex_unlock(&lockRefresh);
- //
- //uSleep(refreshTime);
- }
- void ClearScreen()
- { //kind off overkill to make function out of this but i went with it anyway
- system("@cls||clear");
- }
- void DrawShip(char shipType, size_t shipPosX, size_t shipPosY)
- {
- switch(shipType)
- {
- case 'e':
- for(size_t i=0;i<SHIPHEIGHT;i++)
- {
- for(size_t j=0;j<SHIPLENGHT;j++)
- {
- gameTable[shipPosX][shipPosY+j]=enemyShip[i][j];
- }
- }
- break;
- case 'p':
- for(size_t i=0;i<SHIPHEIGHT;i++)
- {
- for(size_t j=0;j<SHIPLENGHT;j++)
- {
- gameTable[shipPosX][shipPosY+j]=playerShip[i][j];
- }
- }
- break;
- default:
- break;
- }
- }
- void AddEnemies()
- {
- size_t gapX=0;
- size_t gapY=2;
- //so we dont spawn ships in map border
- size_t startPointForX=2;
- size_t startPointForY=2;
- //ship spawn to this point
- size_t endLineForEnemies=HEIGHT-SPACEFORPLAYER;
- for(;startPointForX<endLineForEnemies;)
- {
- for(;startPointForY<LENGHT-SHIPLENGHT;)//adding ships if we have a place for it
- {
- DrawShip('e',startPointForX,startPointForY);
- gapY=gapY+4;
- startPointForY=gapY;
- }
- gapX=gapX+2;
- startPointForX=gapX;
- startPointForY=2;
- gapY=2;
- }
- }
- void PlayerMovement(size_t shipPosX,size_t shipPosY)
- {
- char Controls;
- while(1)
- {
- Controls=getch();
- switch(Controls)
- {
- case 'a':
- ClearShip(shipPosX,shipPosY);
- shipPosY=shipPosY-1;
- TestForGameOver(shipPosX,shipPosY);
- DrawShip('p',shipPosX,shipPosY);
- //GameStatePrint();
- break;
- case 'd':
- ClearShip(shipPosX,shipPosY);
- shipPosY=shipPosY+1;
- TestForGameOver(shipPosX,shipPosY);
- DrawShip('p',shipPosX,shipPosY);
- //GameStatePrint();
- break;
- case 'w':
- ClearShip(shipPosX,shipPosY);
- shipPosX=shipPosX-1;
- TestForGameOver(shipPosX,shipPosY);
- DrawShip('p',shipPosX,shipPosY);
- //GameStatePrint();
- break;
- case 's':
- ClearShip(shipPosX,shipPosY);
- shipPosX=shipPosX+1;
- TestForGameOver(shipPosX,shipPosY);
- DrawShip('p',shipPosX,shipPosY);
- //GameStatePrint();
- break;
- case 'e':
- ShootingInputConversion(shipPosX,shipPosY);
- break;
- default:
- break;
- }
- }
- }
- void ClearShip(size_t shipPosX,size_t shipPosY)
- {
- for(size_t i=0;i<SHIPHEIGHT;i++)
- {
- for(size_t j=0;j<SHIPLENGHT;j++)
- {
- gameTable[shipPosX][shipPosY+j]=' ';
- }
- }
- }
- void TestForGameOver(size_t shipPosX,size_t shipPosY)
- {
- //this loop checks if any of the player ship elements collide with enemy ship or borders
- for(size_t i=0;i<SHIPLENGHT;i++)
- {
- if(gameTable[shipPosX][shipPosY+i]==BORDERS||gameTable[shipPosX][shipPosY+i]=='^'||gameTable[shipPosX][shipPosY+i]=='|'||gameTable[shipPosX][shipPosY+i]==ENEMYSHELL)
- {
- //ClearScreen();
- printf("game over");
- Sleep(2000);
- exit(1);
- }
- }
- }
- void ShootingInputConversion(size_t shipPosX,size_t shipPosY)
- {//function converts ship position and converts it so that it can be accepted by thread which will remember shells that already have been shot
- shipPosX=shipPosX-1;
- shipPosY=shipPosY+1;
- shootingParams *s=malloc(sizeof(shootingParams));
- s->shotPosX=shipPosX;
- s->shotPosY=shipPosY;
- pthread_create(&shot,NULL,PlayerShooting,s);
- }
- void *PlayerShooting(void *s)
- {
- int j=1;
- size_t shootingTrajectoryX;
- size_t shootingTrajectoryY;
- shootingTrajectoryX=((shootingParams*)s)->shotPosX;
- shootingTrajectoryY=((shootingParams*)s)->shotPosY;
- for(int i=0;i<30;i++)
- {
- if(gameTable[shootingTrajectoryX-j][shootingTrajectoryY]==BORDERS)
- {
- goto jump;
- }
- else if(gameTable[shootingTrajectoryX-j][shootingTrajectoryY]=='^')
- {
- ClearShip(shootingTrajectoryX-j,shootingTrajectoryY-1);
- gameTable[shootingTrajectoryX-j+1][shootingTrajectoryY]=' ';
- //GameStatePrint();
- goto jump;
- }
- else if(gameTable[shootingTrajectoryX-j][shootingTrajectoryY]=='|'&&gameTable[shootingTrajectoryX-j][shootingTrajectoryY+1]=='^')
- {
- ClearShip(shootingTrajectoryX-j,shootingTrajectoryY);
- gameTable[shootingTrajectoryX-j+1][shootingTrajectoryY]=' ';
- //GameStatePrint();
- goto jump;
- }
- else if(gameTable[shootingTrajectoryX-j][shootingTrajectoryY]=='|')
- {
- ClearShip(shootingTrajectoryX-j,shootingTrajectoryY-2);
- gameTable[shootingTrajectoryX-j+1][shootingTrajectoryY]=' ';
- //GameStatePrint();
- goto jump;
- }
- else
- {
- gameTable[shootingTrajectoryX-j][shootingTrajectoryY]=PLAYERSHELL;
- gameTable[shootingTrajectoryX-j+1][shootingTrajectoryY]=' ';
- j++;
- //GameStatePrint();
- Sleep(1000);
- }
- }
- jump:
- gameTable[shootingTrajectoryX-j+1][shootingTrajectoryY]=' ';
- free(s);
- pthread_cancel(shot);
- }
- shootingParams scanForEnemy()
- {
- shootingParams s;
- int tempTableX[ENEMYAPPROXCOUNT];
- int tempTableY[ENEMYAPPROXCOUNT];
- size_t index=0;
- for(size_t i=0;i<HEIGHT;i++)
- {
- for(size_t j=0;j<LENGHT;j++)
- {
- if(gameTable[i][j]=='^'&&gameTable[i+2][j]!='^')
- {
- tempTableX[index]=i;
- tempTableY[index]=j;
- index++;
- }
- }
- }
- int r=rand()% index;
- s.shotPosX=tempTableX[r];
- s.shotPosY=tempTableY[r];
- return s;
- }
- void *EnemyShooting(void *f)
- {
- pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
- size_t shootingTrajectoryX;
- size_t shootingTrajectoryY;
- shootingTrajectoryX=((shootingParams*)f)->shotPosX;
- shootingTrajectoryY=((shootingParams*)f)->shotPosY;
- Sleep(1000);
- while(shootingTrajectoryX<LENGHT-1)
- {
- shootingTrajectoryX++;
- if(gameTable[shootingTrajectoryX+1][shootingTrajectoryY]==BORDERS)
- {
- goto jump;
- }
- else if(gameTable[shootingTrajectoryX+1][shootingTrajectoryY]=='='||gameTable[shootingTrajectoryX+1][shootingTrajectoryY]=='('||gameTable[shootingTrajectoryX+1][shootingTrajectoryY]==')')
- {
- //ClearScreen();
- printf("game over");
- Sleep(2000);
- exit(1);
- }
- else if(gameTable[shootingTrajectoryX+1][shootingTrajectoryY]==PLAYERSHELL)
- {
- gameTable[shootingTrajectoryX][shootingTrajectoryY]=' ';
- goto jump;
- }
- else
- {
- gameTable[shootingTrajectoryX+1][shootingTrajectoryY]=ENEMYSHELL;
- gameTable[shootingTrajectoryX][shootingTrajectoryY]=' ';
- //GameStatePrint();
- Sleep(1000);
- }
- }
- jump:
- gameTable[shootingTrajectoryX][shootingTrajectoryY]=' ';
- pthread_cancel(enemyShot);
- }
- void *EnemyShootingDelay()
- {
- shootingParams f;
- while(1)
- {
- //warning-if you remove this Sleep you will kill your PC
- Sleep(1000);
- f=scanForEnemy();
- pthread_create(&enemyShot,NULL,EnemyShooting,&f);
- }
- }
- void *GlobalTimer()
- {
- shootingParams f;
- while(1)
- {
- //warning-if you remove this Sleep you will kill your PC
- Sleep(300);
- //f=scanForEnemy();
- GameStatePrint();
- //pthread_create(&enemyShot,NULL,EnemyShooting,&f);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement