#include "primlib.h"
#include <stdlib.h>
#include <math.h>
#include "stack.h"
#define POLES 3
#define BLOCKS 5
#define BLOCK_WIDTH 40
#define BLOCK_HEIGHT 20
#define MOVE_SPEED 4
void drawStructure(int *Poles);
void drawBlock(int x1, int y1, int x2, int y2);
void moveBlock(int *Blocks[], int BlockNumber, int BlockToMove, int *Poles, int FinishY);
void drawRemaining(int *Blocks[], int *Poles, int BlockToSkip);
void clearScreen();
void clearBlock(int x1, int y1, int x2, int y2);
int main(int argc, char* argv[])
{
stackT Pole1;
stackT Pole2;
stackT Pole3;
int centerX;
int centerY;
int maxX;
int maxY;
int poles[POLES];
int i;
int firstKey;
int secondKey;
int buffer;
int elems;
int **blocks = malloc(BLOCKS * sizeof(int *));
for(i = 0; i < BLOCKS; i++)
blocks[i] = malloc(2 * sizeof(int));
StackInit(&Pole1, BLOCKS);
StackInit(&Pole2, BLOCKS);
StackInit(&Pole3, BLOCKS);
if(initGraph())
exit(3);
centerX = screenWidth()/2;
centerY = screenHeight()/2;
maxX = screenWidth();
maxY = screenHeight();
drawStructure(poles);
for(i = BLOCKS; i > 0; i--)
{
StackPush(&Pole1, i);
elems = StackElems(&Pole1);
drawBlock(poles[0]-BLOCK_WIDTH/2*i, maxY-1-BLOCK_HEIGHT*elems, poles[0]+BLOCK_WIDTH/2*i, maxY-21-BLOCK_HEIGHT*elems);
blocks[i-1][0] = poles[0];
blocks[i-1][1] = maxY-1-BLOCK_HEIGHT*elems;
}
do
{
updateScreen();
printf("Choose your destiny:\n");
firstKey = getkey();
secondKey = getkey();
switch(firstKey)
{
case SDLK_1:
if(StackIsEmpty(&Pole1))
else
{
switch(secondKey)
{
case SDLK_1:
printf("Invalid Operation!\n");
break;
case SDLK_2:
if(StackTop(&Pole1)>StackTop(&Pole2) && StackTop(&Pole2)!=0)
printf("You cant put bigger block on a smaller one.\n");
else
{
elems = StackElems(&Pole2);
buffer = StackPop(&Pole1);
StackPush(&Pole2, buffer);
moveBlock(blocks, 2, buffer, poles, maxY-21-BLOCK_HEIGHT*(elems+1));
printf("Moved from 1 to 2 block number: %d.\n", buffer
);
}
break;
case SDLK_3:
if(StackTop(&Pole1)>StackTop(&Pole3) && StackTop(&Pole3)!=0)
printf("You cant put bigger block on a smaller one.\n");
else
{
elems = StackElems(&Pole3);
buffer = StackPop(&Pole1);
StackPush(&Pole3, buffer);
moveBlock(blocks, 3, buffer, poles, maxY-21-BLOCK_HEIGHT*(elems+1));
printf("Moved from 1 to 3 block number: %d.\n", buffer
);
}
break;
default:
break;
}
}
break;
case SDLK_2:
if(StackIsEmpty(&Pole2))
else
{
switch(secondKey)
{
case SDLK_1:
if(StackTop(&Pole2)>StackTop(&Pole1) && StackTop(&Pole1)!=0)
printf("You cant put bigger block on a smaller one.\n");
else
{
elems = StackElems(&Pole1);
buffer = StackPop(&Pole2);
StackPush(&Pole1, buffer);
moveBlock(blocks, 1, buffer, poles, maxY-21-BLOCK_HEIGHT*(elems+1));
printf("Moved from 2 to 1 block number: %d.\n", buffer
);
}
break;
case SDLK_2:
printf("Invalid Operation!\n");
break;
case SDLK_3:
if(StackTop(&Pole2)>StackTop(&Pole3) && StackTop(&Pole3)!=0)
printf("You cant put bigger block on a smaller one.\n");
else
{
elems = StackElems(&Pole3);
buffer = StackPop(&Pole2);
StackPush(&Pole3, buffer);
moveBlock(blocks, 3, buffer, poles, maxY-21-BLOCK_HEIGHT*(elems+1));
printf("Moved from 2 to 3 block number: %d.\n", buffer
);
}
break;
default:
break;
}
}
break;
case SDLK_3:
if(StackIsEmpty(&Pole3))
else
{
switch(secondKey)
{
case SDLK_1:
if(StackTop(&Pole3)>StackTop(&Pole1) && StackTop(&Pole1)!=0)
printf("You cant put bigger block on a smaller one.\n");
else
{
elems = StackElems(&Pole1);
buffer = StackPop(&Pole3);
StackPush(&Pole1, buffer);
moveBlock(blocks, 1, buffer, poles, maxY-21-BLOCK_HEIGHT*(elems+1));
printf("Moved from 3 to 1 block number: %d.\n", buffer
);
}
break;
case SDLK_2:
if(StackTop(&Pole3)>StackTop(&Pole2) && StackTop(&Pole2)!=0)
printf("You cant put bigger block on a smaller one.\n");
else
{
elems = StackElems(&Pole2);
buffer = StackPop(&Pole3);
StackPush(&Pole2, buffer);
moveBlock(blocks, 2, buffer, poles, maxY-21-BLOCK_HEIGHT*(elems+1));
printf("Moved from 3 to 2 block number: %d.\n", buffer
);
}
break;
case SDLK_3:
printf("Invalid Operation!\n");
break;
default:
break;
}
}
break;
default:
break;
}
printf("To quit press \"q\" \n");
}while(getkey() != SDLK_q);
return 1;
}
void drawStructure(int *Poles)
{
int centerX;
int centerY;
int maxX;
int maxY;
int i;
int position;
centerX = screenWidth()/2;
centerY = screenHeight()/2;
maxX = screenWidth();
maxY = screenHeight();
position = maxX/POLES;
filledRect(0, maxY-20, maxX, maxY, RED);
for(i = 1; i < POLES+1; i++)
{
filledRect(position*i-position/2+10, maxY, position*i-position/2-10, maxY-200, YELLOW);
Poles[i-1] = position*i-position/2;
updateScreen();
}
}
void drawBlock(int x1, int y1, int x2, int y2)
{
filledRect( x1, y1, x2, y2, BLUE);
updateScreen();
}
void clearBlock(int x1, int y1, int x2, int y2)
{
filledRect( x1, y1, x2, y2, BLACK);
updateScreen();
}
void moveBlock(int *Blocks[], int PoleNumber, int BlockToMove, int *Poles, int FinishY)
{ int move_speed;
int temp;
int i;
move_speed = 1;
for(i = Blocks[BlockToMove-1][1]; i > 200; i=i-1)
{
if(move_speed == MOVE_SPEED)
{
drawRemaining(Blocks, Poles, BlockToMove);
filledRect(Blocks[BlockToMove-1][0]-BLOCK_WIDTH/2*BlockToMove, i, Blocks[BlockToMove-1][0]+BLOCK_WIDTH/2*BlockToMove, i-20, BLUE);
move_speed = 1;
}
else
move_speed++;
updateScreen();
}
temp = i;
i = Blocks[BlockToMove-1][0];
move_speed = 1;
if(Poles[PoleNumber-1]<i)
{
while(Poles[PoleNumber-1]<i)
{
if(move_speed == MOVE_SPEED)
{
drawRemaining(Blocks, Poles, BlockToMove);
filledRect(i-BLOCK_WIDTH/2*BlockToMove, temp, i+BLOCK_WIDTH/2*BlockToMove, temp-20, BLUE);
move_speed = 1;
}
else
move_speed++;
i=i-1;
updateScreen();
}
}
else if(Poles[PoleNumber-1]>i)
{
while(Poles[PoleNumber-1]>=i)
{
if(move_speed == MOVE_SPEED)
{
drawRemaining(Blocks, Poles, BlockToMove);
filledRect(i-BLOCK_WIDTH/2*BlockToMove, temp, i+BLOCK_WIDTH/2*BlockToMove, temp-20, BLUE);
move_speed = 1;
}
else
move_speed++;
i=i+1;
updateScreen();
}
}
temp = i;
move_speed = 1;
for(i = 200; i < FinishY+22; i=i+1)
{
if(move_speed == MOVE_SPEED)
{
drawRemaining(Blocks, Poles, BlockToMove);
filledRect(temp-BLOCK_WIDTH/2*BlockToMove, i, temp+BLOCK_WIDTH/2*BlockToMove, i-20, BLUE);
move_speed = 1;
}
else
move_speed++;
updateScreen();
}
Blocks[BlockToMove-1][0] = temp;
Blocks[BlockToMove-1][1] = i-1;
}
void drawRemaining(int *Blocks[], int *Poles, int BlockToSkip)
{
int i;
clearScreen();
drawStructure(Poles);
for(i = BLOCKS; i > 0; i--)
{
if(i == BlockToSkip)
continue;
else
{
drawBlock(Blocks[i-1][0]-BLOCK_WIDTH/2*i, Blocks[i-1][1], Blocks[i-1][0]+BLOCK_WIDTH/2*i, Blocks[i-1][1]-20);
}
}
updateScreen();
}
void clearScreen()
{
filledRect(0, 0, screenWidth()-1, screenHeight()-1, BLACK);
}