Advertisement
deseven

4kgame

May 28th, 2015
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 12.55 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <time.h>
  4. #include <windows.h>
  5. #include <conio.h>
  6.  
  7. #define myName "4kgame"
  8.  
  9. #define sSpace " "
  10. #define sCoin "$"
  11. #define sEnemy 42
  12. #define sPlayer 30
  13. #define sTree 177
  14. #define sWater 176
  15.  
  16. #define worldW 60
  17. #define worldH 40
  18. #define numCoins 5
  19. #define startEnemies 1
  20. #define enemyRange 10
  21.  
  22. enum {
  23.     none = 0,
  24.     tree = 1,
  25.     rock = 2,
  26.     water = 3,
  27.     coin = 4,
  28.     enemy = 5,
  29.     movedEnemy = 6,
  30.     player = 7
  31. };
  32.  
  33. enum {
  34.     dirRight = 0,
  35.     dirLeft = 1,
  36.     dirDown = 2,
  37.     dirUp = 3
  38. };
  39.  
  40. enum {
  41.     KEY_ESC = 27,
  42.     KEY_RETURN = 13,
  43.     ARROW_UP = 256 + 72,
  44.     ARROW_DOWN = 256 + 80,
  45.     ARROW_LEFT = 256 + 75,
  46.     ARROW_RIGHT = 256 + 77
  47. };
  48.  
  49. char pWorld[worldW][worldH];
  50. int i;
  51. int ch;
  52. int x;
  53. int y;
  54. int playerX;
  55. int playerY;
  56. int coinsCollected;
  57. int numOfTurns;
  58. int level = 0;
  59.  
  60. static int get_code(void) {
  61.     int ch = _getch();
  62.     if (ch == 0 || ch == 224)
  63.         ch = 256 + _getch();
  64.     return ch;
  65. }
  66.  
  67. void setConsole(int Width, int Height) {
  68.     COORD coord;
  69.     coord.X = Width;
  70.     coord.Y = Height;
  71.     SMALL_RECT Rect;
  72.     Rect.Top = 0;
  73.     Rect.Left = 0;
  74.     Rect.Bottom = Height - 1;
  75.     Rect.Right = Width - 1;
  76.     CONSOLE_CURSOR_INFO CURSOR;
  77.     CURSOR.dwSize = 1;
  78.     CURSOR.bVisible = 0;
  79.     HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
  80.     SetConsoleWindowInfo(hCon, TRUE, &Rect);
  81.     SetConsoleScreenBufferSize(hCon, coord);
  82.     SetConsoleCursorInfo(hCon, &CURSOR);
  83. }
  84.  
  85. unsigned int realRand(unsigned int min, unsigned int max) {
  86.     unsigned int r;
  87.     const unsigned int range = 1 + max - min;
  88.     const unsigned int buckets = RAND_MAX / range;
  89.     const unsigned int limit = buckets * range;
  90.  
  91.     do {
  92.         r = rand();
  93.     } while (r >= limit);
  94.  
  95.     return min + (r / buckets);
  96. }
  97.  
  98. void drawObject(int x, int y, char type) {
  99.     HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
  100.     COORD coord = { x, y };
  101.     SetConsoleCursorPosition(hCon, coord);
  102.     switch (type) {
  103.     case player:
  104.         SetConsoleTextAttribute(hCon, FOREGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED);
  105.         printf("%c",sPlayer);
  106.         break;
  107.     case none:
  108.         SetConsoleTextAttribute(hCon, BACKGROUND_GREEN | BACKGROUND_RED);
  109.         printf(sSpace);
  110.         break;
  111.     case tree:
  112.         SetConsoleTextAttribute(hCon, BACKGROUND_GREEN);
  113.         printf("%c", sTree);
  114.         break;
  115.     case rock:
  116.         SetConsoleTextAttribute(hCon, BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED);
  117.         printf(sSpace);
  118.         break;
  119.     case water:
  120.         SetConsoleTextAttribute(hCon, BACKGROUND_GREEN | BACKGROUND_BLUE);
  121.         printf("%c", sWater);
  122.         break;
  123.     case coin:
  124.         SetConsoleTextAttribute(hCon, BACKGROUND_GREEN | BACKGROUND_RED);
  125.         printf(sCoin);
  126.         break;
  127.     case enemy:
  128.         SetConsoleTextAttribute(hCon, FOREGROUND_RED | BACKGROUND_RED | BACKGROUND_GREEN);
  129.         printf("%c", sEnemy);
  130.         break;
  131.     default:
  132.         SetConsoleTextAttribute(hCon, BACKGROUND_RED);
  133.         printf(sSpace);
  134.         break;
  135.     }
  136. }
  137.  
  138. int moveEnemy(int x, int y, char type) {
  139.     switch (type) {
  140.     case dirRight:
  141.         if ((x + 1) < worldW) {
  142.             if (pWorld[x + 1][y] == none) {
  143.                 pWorld[x][y] = none;
  144.                 pWorld[x + 1][y] = enemy;
  145.                 drawObject(x, y, pWorld[x][y]);
  146.                 drawObject(x + 1, y, pWorld[x + 1][y]);
  147.                 pWorld[x + 1][y] = movedEnemy;
  148.                 return TRUE;
  149.             }
  150.         }
  151.         break;
  152.     case dirLeft:
  153.         if ((x - 1) >= 0) {
  154.             if (pWorld[x - 1][y] == none) {
  155.                 pWorld[x][y] = none;
  156.                 pWorld[x - 1][y] = enemy;
  157.                 drawObject(x, y, pWorld[x][y]);
  158.                 drawObject(x - 1, y, pWorld[x - 1][y]);
  159.                 pWorld[x - 1][y] = movedEnemy;
  160.                 return TRUE;
  161.             }
  162.         }
  163.         break;
  164.     case dirDown:
  165.         if ((y + 1) < worldH) {
  166.             if (pWorld[x][y + 1] == none) {
  167.                 pWorld[x][y] = none;
  168.                 pWorld[x][y + 1] = enemy;
  169.                 drawObject(x, y, pWorld[x][y]);
  170.                 drawObject(x, y + 1, pWorld[x][y + 1]);
  171.                 pWorld[x][y + 1] = movedEnemy;
  172.                 return TRUE;
  173.             }
  174.         }
  175.         break;
  176.     case dirUp:
  177.         if ((y - 1) >= 0) {
  178.             if (pWorld[x][y - 1] == none) {
  179.                 pWorld[x][y] = none;
  180.                 pWorld[x][y - 1] = enemy;
  181.                 drawObject(x, y, pWorld[x][y]);
  182.                 drawObject(x, y - 1, pWorld[x][y - 1]);
  183.                 pWorld[x][y - 1] = movedEnemy;
  184.                 return TRUE;
  185.             }
  186.         }
  187.         break;
  188.     }
  189.     return FALSE;
  190. }
  191.  
  192. float noise(int x, int y) {
  193.     int n;
  194.     n = x + y * 57;
  195.     n = (n << 13) ^ n;
  196.     return (float)(1.0 - ((n * ((n * n * 15731) + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
  197. }
  198.  
  199. void createWorld() {
  200.     x = 0;
  201.     y = 0;
  202.     playerX = 0;
  203.     playerY = 0;
  204.     coinsCollected = 0;
  205.     numOfTurns = 0;
  206.  
  207.     level++;
  208.  
  209.     // setting console and buffer +1 of the real height so we can work with the last line safely
  210.     setConsole(worldW, worldH + 1);
  211.  
  212.     for (x = 0; x < worldW; x++) {
  213.         for (y = 0; y < worldH; y++) {
  214.             pWorld[x][y] = none;
  215.         }
  216.     }
  217.  
  218.     int noiseOffset = realRand(0,10000);
  219.  
  220.     for (y = 0; y < worldH; y++) {
  221.         for (x = 0; x < worldW; x++) {
  222.             float curnoise = noise(noiseOffset + x, noiseOffset + y);
  223.             // if noise value is high enough
  224.             if (curnoise > 0.5) {
  225.                 // trying to create solid blocks of the same type
  226.                 if ((x - 1 >= 0) && (pWorld[x - 1][y] != none)) {
  227.                     pWorld[x][y] = pWorld[x - 1][y];
  228.                 } else if ((x + 1 < worldW) && (pWorld[x + 1][y] != none)) {
  229.                     pWorld[x][y] = pWorld[x + 1][y];
  230.                 } else if ((y - 1 >= 0) && (pWorld[x][y - 1] != none)) {
  231.                     pWorld[x][y] = pWorld[x][y - 1];
  232.                 } else if ((y + 1 < worldH) && (pWorld[x][y + 1] != none)) {
  233.                     pWorld[x][y] = pWorld[x][y + 1];
  234.                 } else if ((x + 1 < worldW) && (y + 1 < worldH) && (pWorld[x + 1][y + 1] != none)) {
  235.                     pWorld[x][y] = pWorld[x + 1][y + 1];
  236.                 } else if ((x - 1 >= 0) && (y + 1 < worldH) && (pWorld[x - 1][y + 1] != none)) {
  237.                     pWorld[x][y] = pWorld[x - 1][y + 1];
  238.                 } else if ((x + 1 < worldW) && (y - 1 >= 0) && (pWorld[x + 1][y - 1] != none)) {
  239.                     pWorld[x][y] = pWorld[x + 1][y - 1];
  240.                 } else if ((x - 1 >= 0) && (y - 1 >= 0) && (pWorld[x - 1][y - 1] != none)) {
  241.                     pWorld[x][y] = pWorld[x - 1][y - 1];
  242.                 } else {
  243.                     pWorld[x][y] = (char)realRand(1, 3);
  244.                 }
  245.             } else {
  246.                 pWorld[x][y] = none;
  247.             }
  248.             drawObject(x, y, pWorld[x][y]);
  249.         }
  250.     }
  251.  
  252.     // dirty hack to make the last piece untouchable (as it mess the console buffer)
  253.     pWorld[worldW - 1][worldH - 1] = rock;
  254.     drawObject(worldW - 1, worldH - 1, pWorld[worldW - 1][worldH - 1]);
  255.  
  256.     for (i = 0; i < numCoins; i++) {
  257.         // trying to place coins in the open area
  258.         while (1) {
  259.             x = realRand(1, worldW - 2);
  260.             y = realRand(1, worldH - 2);
  261.             if ((pWorld[x][y] == none) && (pWorld[x - 1][y] == none) && (pWorld[x + 1][y] == none) && (pWorld[x][y - 1] == none) && (pWorld[x][y + 1] == none)) {
  262.                 break;
  263.             }
  264.         }
  265.         pWorld[x][y] = coin;
  266.         drawObject(x, y, pWorld[x][y]);
  267.     }
  268.  
  269.     for (i = 0; i < startEnemies + level; i++) {
  270.         // trying to place enemies in the open area
  271.         while (1) {
  272.             x = realRand(1, worldW - 2);
  273.             y = realRand(1, worldH - 2);
  274.             if ((pWorld[x][y] == none) && ((pWorld[x - 1][y] == none) || (pWorld[x + 1][y] == none) || (pWorld[x][y - 1] == none) || (pWorld[x][y + 1] == none))) {
  275.                 break;
  276.             }
  277.         }
  278.         pWorld[x][y] = enemy;
  279.         drawObject(x, y, pWorld[x][y]);
  280.     }
  281.  
  282.     // placing the player in the open area
  283.     while (1) {
  284.         playerX = realRand(1, worldW - 2);
  285.         playerY = realRand(1, worldH - 2);
  286.         if ((pWorld[playerX][playerY] == none) && (pWorld[playerX - 1][playerY] == none) && (pWorld[playerX + 1][playerY] == none) && (pWorld[playerX][playerY - 1] == none) && (pWorld[playerX][playerY + 1] == none)) {
  287.             break;
  288.         }
  289.     }
  290.  
  291.     // for debug purposes
  292.     //printf("[%d]",playerX);
  293.     //printf("[%d]",playerY);
  294.  
  295.     drawObject(playerX, playerY, player);
  296.  
  297.     // setting the console to the desired size
  298.     setConsole(worldW, worldH);
  299. }
  300.  
  301. void endGame(char won) {
  302.     drawObject(playerX, playerY, pWorld[playerX][playerY]);
  303.     HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
  304.     COORD coord1 = { worldW / 2 - 4, worldH / 2 - 2 };
  305.     SetConsoleTextAttribute(hCon, BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE);
  306.     SetConsoleCursorPosition(hCon, coord1);
  307.     printf("Level %d", level);
  308.     if (won != TRUE) {
  309.         COORD coord2 = { worldW / 2 - 5, worldH / 2 };
  310.         SetConsoleCursorPosition(hCon, coord2);
  311.         printf("Game over!");
  312.         level = 0;
  313.     } else {
  314.         COORD coord2 = { worldW / 2 - 10, worldH / 2 };
  315.         SetConsoleCursorPosition(hCon, coord2);
  316.         printf("You won in %d turns!", numOfTurns);
  317.     }
  318.     COORD coord3 = { worldW / 2 - 11, worldH / 2 + 2 };
  319.     SetConsoleCursorPosition(hCon, coord3);
  320.     printf("Press ENTER to continue", level);
  321.     while ((ch = get_code()) != KEY_ESC) {
  322.         // restart the game on enter
  323.         if (ch == KEY_RETURN) {
  324.             createWorld();
  325.             return;
  326.         }
  327.     }
  328.     exit(0);
  329. }
  330.  
  331. int main() {
  332.     srand((unsigned int)time(NULL));
  333.     char playerMoved;
  334.  
  335.     SetConsoleTitle(TEXT(myName));
  336.  
  337.     createWorld();
  338.  
  339.     while ((ch = get_code()) != KEY_ESC) {
  340.         playerMoved = FALSE;
  341.         switch (ch) {
  342.         case ARROW_UP:
  343.             if (playerY - 1 >= 0) {
  344.                 if ((pWorld[playerX][playerY - 1] == none) || (pWorld[playerX][playerY - 1] == coin) || (pWorld[playerX][playerY - 1] == enemy)) {
  345.                     drawObject(playerX, playerY, pWorld[playerX][playerY]);
  346.                     playerY -= 1;
  347.                     playerMoved = TRUE;
  348.                 }
  349.             }
  350.             break;
  351.         case ARROW_DOWN:
  352.             if (playerY + 1 < worldH) {
  353.                 if ((pWorld[playerX][playerY + 1] == none) || (pWorld[playerX][playerY + 1] == coin) || (pWorld[playerX][playerY + 1] == enemy)) {
  354.                     drawObject(playerX, playerY, pWorld[playerX][playerY]);
  355.                     playerY += 1;
  356.                     playerMoved = TRUE;
  357.                 }
  358.             }
  359.             break;
  360.         case ARROW_LEFT:
  361.             if (playerX - 1 >= 0) {
  362.                 if ((pWorld[playerX - 1][playerY] == none) || (pWorld[playerX - 1][playerY] == coin) || (pWorld[playerX - 1][playerY] == enemy)) {
  363.                     drawObject(playerX, playerY, pWorld[playerX][playerY]);
  364.                     playerX -= 1;
  365.                     playerMoved = TRUE;
  366.                 }
  367.             }
  368.             break;
  369.         case ARROW_RIGHT:
  370.             if (playerX + 1 < worldW) {
  371.                 if ((pWorld[playerX + 1][playerY] == none) || (pWorld[playerX + 1][playerY] == coin) || (pWorld[playerX + 1][playerY] == enemy)) {
  372.                     drawObject(playerX, playerY, pWorld[playerX][playerY]);
  373.                     playerX += 1;
  374.                     playerMoved = TRUE;
  375.                 }
  376.             }
  377.             break;
  378.         }
  379.         if (pWorld[playerX][playerY] == enemy) {
  380.             endGame(FALSE);
  381.         }
  382.         if (playerMoved == TRUE) {
  383.             for (x = 0; x < worldW; x++) {
  384.                 for (y = 0; y < worldH; y++) {
  385.                     if (pWorld[x][y] == enemy) {
  386.                         int distX = x - playerX;
  387.                         int distY = y - playerY;
  388.                         if ((distX <= enemyRange) && (distY <= enemyRange)) {
  389.                             if (abs(distX) > abs(distY)) {
  390.                                 // closer by y
  391.                                 if (distX > 0) {
  392.                                     if (moveEnemy(x, y, dirLeft) != TRUE) {
  393.                                         if (realRand(0,1) == 1) {
  394.                                             if (moveEnemy(x, y, dirUp) != TRUE) {
  395.                                                 if (moveEnemy(x, y, dirDown) != TRUE) moveEnemy(x, y, dirRight);
  396.                                             }
  397.                                         } else {
  398.                                             if (moveEnemy(x, y, dirDown) != TRUE) {
  399.                                                 if (moveEnemy(x, y, dirUp) != TRUE) moveEnemy(x, y, dirRight);
  400.                                             }
  401.                                         }
  402.                                     }
  403.                                 } else {
  404.                                     if (moveEnemy(x, y, dirRight) != TRUE) {
  405.                                         if (realRand(0, 1) == 1) {
  406.                                             if (moveEnemy(x, y, dirUp) != TRUE) {
  407.                                                 if (moveEnemy(x, y, dirDown) != TRUE) moveEnemy(x, y, dirLeft);
  408.                                             }
  409.                                         } else {
  410.                                             if (moveEnemy(x, y, dirDown) != TRUE) {
  411.                                                 if (moveEnemy(x, y, dirUp) != TRUE) moveEnemy(x, y, dirLeft);
  412.                                             }
  413.                                         }
  414.                                     }
  415.                                 }
  416.                             } else {
  417.                                 // closer by x
  418.                                 if (distY > 0) {
  419.                                     if (moveEnemy(x, y, dirUp) != TRUE) {
  420.                                         if (realRand(0, 1) == 1) {
  421.                                             if (moveEnemy(x, y, dirLeft) != TRUE) {
  422.                                                 if (moveEnemy(x, y, dirRight) != TRUE) moveEnemy(x, y, dirDown);
  423.                                             }
  424.                                         } else {
  425.                                             if (moveEnemy(x, y, dirRight) != TRUE) {
  426.                                                 if (moveEnemy(x, y, dirLeft) != TRUE) moveEnemy(x, y, dirDown);
  427.                                             }
  428.                                         }
  429.                                     }
  430.                                 } else {
  431.                                     if (moveEnemy(x, y, dirDown) != TRUE) {
  432.                                         if (realRand(0, 1) == 1) {
  433.                                             if (moveEnemy(x, y, dirLeft) != TRUE) {
  434.                                                 if (moveEnemy(x, y, dirRight) != TRUE) moveEnemy(x, y, dirUp);
  435.                                             }
  436.                                         } else {
  437.                                             if (moveEnemy(x, y, dirRight) != TRUE) {
  438.                                                 if (moveEnemy(x, y, dirLeft) != TRUE) moveEnemy(x, y, dirUp);
  439.                                             }
  440.                                         }
  441.                                     }
  442.                                 }
  443.                             }
  444.                         } else {
  445.                             moveEnemy(x, y, realRand(0, 3));
  446.                         }
  447.                     }
  448.  
  449.                 }
  450.             }
  451.             for (x = 0; x < worldW; x++) {
  452.                 for (y = 0; y < worldH; y++) {
  453.                     if (pWorld[x][y] == movedEnemy) {
  454.                         pWorld[x][y] = enemy;
  455.                     }
  456.                 }
  457.             }
  458.             if (playerMoved == TRUE) {
  459.                 numOfTurns++;
  460.             }
  461.             drawObject(playerX, playerY, player);
  462.             if (pWorld[playerX][playerY] == enemy) {
  463.                 endGame(FALSE);
  464.             }
  465.             if (pWorld[playerX][playerY] == coin) {
  466.                 pWorld[playerX][playerY] = none;
  467.                 coinsCollected++;
  468.                 if (coinsCollected == numCoins) {
  469.                     endGame(TRUE);
  470.                 }
  471.             }
  472.         }
  473.     }
  474.     return 0;
  475. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement