Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <stdio.h>
- #include <time.h>
- #include <windows.h>
- #include <conio.h>
- #define myName "4kgame"
- #define sSpace " "
- #define sCoin "$"
- #define sEnemy 42
- #define sPlayer 30
- #define sTree 177
- #define sWater 176
- #define worldW 60
- #define worldH 40
- #define numCoins 5
- #define startEnemies 1
- #define enemyRange 10
- enum {
- none = 0,
- tree = 1,
- rock = 2,
- water = 3,
- coin = 4,
- enemy = 5,
- movedEnemy = 6,
- player = 7
- };
- enum {
- dirRight = 0,
- dirLeft = 1,
- dirDown = 2,
- dirUp = 3
- };
- enum {
- KEY_ESC = 27,
- KEY_RETURN = 13,
- ARROW_UP = 256 + 72,
- ARROW_DOWN = 256 + 80,
- ARROW_LEFT = 256 + 75,
- ARROW_RIGHT = 256 + 77
- };
- char pWorld[worldW][worldH];
- int i;
- int ch;
- int x;
- int y;
- int playerX;
- int playerY;
- int coinsCollected;
- int numOfTurns;
- int level = 0;
- static int get_code(void) {
- int ch = _getch();
- if (ch == 0 || ch == 224)
- ch = 256 + _getch();
- return ch;
- }
- void setConsole(int Width, int Height) {
- COORD coord;
- coord.X = Width;
- coord.Y = Height;
- SMALL_RECT Rect;
- Rect.Top = 0;
- Rect.Left = 0;
- Rect.Bottom = Height - 1;
- Rect.Right = Width - 1;
- CONSOLE_CURSOR_INFO CURSOR;
- CURSOR.dwSize = 1;
- CURSOR.bVisible = 0;
- HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
- SetConsoleWindowInfo(hCon, TRUE, &Rect);
- SetConsoleScreenBufferSize(hCon, coord);
- SetConsoleCursorInfo(hCon, &CURSOR);
- }
- unsigned int realRand(unsigned int min, unsigned int max) {
- unsigned int r;
- const unsigned int range = 1 + max - min;
- const unsigned int buckets = RAND_MAX / range;
- const unsigned int limit = buckets * range;
- do {
- r = rand();
- } while (r >= limit);
- return min + (r / buckets);
- }
- void drawObject(int x, int y, char type) {
- HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
- COORD coord = { x, y };
- SetConsoleCursorPosition(hCon, coord);
- switch (type) {
- case player:
- SetConsoleTextAttribute(hCon, FOREGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED);
- printf("%c",sPlayer);
- break;
- case none:
- SetConsoleTextAttribute(hCon, BACKGROUND_GREEN | BACKGROUND_RED);
- printf(sSpace);
- break;
- case tree:
- SetConsoleTextAttribute(hCon, BACKGROUND_GREEN);
- printf("%c", sTree);
- break;
- case rock:
- SetConsoleTextAttribute(hCon, BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED);
- printf(sSpace);
- break;
- case water:
- SetConsoleTextAttribute(hCon, BACKGROUND_GREEN | BACKGROUND_BLUE);
- printf("%c", sWater);
- break;
- case coin:
- SetConsoleTextAttribute(hCon, BACKGROUND_GREEN | BACKGROUND_RED);
- printf(sCoin);
- break;
- case enemy:
- SetConsoleTextAttribute(hCon, FOREGROUND_RED | BACKGROUND_RED | BACKGROUND_GREEN);
- printf("%c", sEnemy);
- break;
- default:
- SetConsoleTextAttribute(hCon, BACKGROUND_RED);
- printf(sSpace);
- break;
- }
- }
- int moveEnemy(int x, int y, char type) {
- switch (type) {
- case dirRight:
- if ((x + 1) < worldW) {
- if (pWorld[x + 1][y] == none) {
- pWorld[x][y] = none;
- pWorld[x + 1][y] = enemy;
- drawObject(x, y, pWorld[x][y]);
- drawObject(x + 1, y, pWorld[x + 1][y]);
- pWorld[x + 1][y] = movedEnemy;
- return TRUE;
- }
- }
- break;
- case dirLeft:
- if ((x - 1) >= 0) {
- if (pWorld[x - 1][y] == none) {
- pWorld[x][y] = none;
- pWorld[x - 1][y] = enemy;
- drawObject(x, y, pWorld[x][y]);
- drawObject(x - 1, y, pWorld[x - 1][y]);
- pWorld[x - 1][y] = movedEnemy;
- return TRUE;
- }
- }
- break;
- case dirDown:
- if ((y + 1) < worldH) {
- if (pWorld[x][y + 1] == none) {
- pWorld[x][y] = none;
- pWorld[x][y + 1] = enemy;
- drawObject(x, y, pWorld[x][y]);
- drawObject(x, y + 1, pWorld[x][y + 1]);
- pWorld[x][y + 1] = movedEnemy;
- return TRUE;
- }
- }
- break;
- case dirUp:
- if ((y - 1) >= 0) {
- if (pWorld[x][y - 1] == none) {
- pWorld[x][y] = none;
- pWorld[x][y - 1] = enemy;
- drawObject(x, y, pWorld[x][y]);
- drawObject(x, y - 1, pWorld[x][y - 1]);
- pWorld[x][y - 1] = movedEnemy;
- return TRUE;
- }
- }
- break;
- }
- return FALSE;
- }
- float noise(int x, int y) {
- int n;
- n = x + y * 57;
- n = (n << 13) ^ n;
- return (float)(1.0 - ((n * ((n * n * 15731) + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
- }
- void createWorld() {
- x = 0;
- y = 0;
- playerX = 0;
- playerY = 0;
- coinsCollected = 0;
- numOfTurns = 0;
- level++;
- // setting console and buffer +1 of the real height so we can work with the last line safely
- setConsole(worldW, worldH + 1);
- for (x = 0; x < worldW; x++) {
- for (y = 0; y < worldH; y++) {
- pWorld[x][y] = none;
- }
- }
- int noiseOffset = realRand(0,10000);
- for (y = 0; y < worldH; y++) {
- for (x = 0; x < worldW; x++) {
- float curnoise = noise(noiseOffset + x, noiseOffset + y);
- // if noise value is high enough
- if (curnoise > 0.5) {
- // trying to create solid blocks of the same type
- if ((x - 1 >= 0) && (pWorld[x - 1][y] != none)) {
- pWorld[x][y] = pWorld[x - 1][y];
- } else if ((x + 1 < worldW) && (pWorld[x + 1][y] != none)) {
- pWorld[x][y] = pWorld[x + 1][y];
- } else if ((y - 1 >= 0) && (pWorld[x][y - 1] != none)) {
- pWorld[x][y] = pWorld[x][y - 1];
- } else if ((y + 1 < worldH) && (pWorld[x][y + 1] != none)) {
- pWorld[x][y] = pWorld[x][y + 1];
- } else if ((x + 1 < worldW) && (y + 1 < worldH) && (pWorld[x + 1][y + 1] != none)) {
- pWorld[x][y] = pWorld[x + 1][y + 1];
- } else if ((x - 1 >= 0) && (y + 1 < worldH) && (pWorld[x - 1][y + 1] != none)) {
- pWorld[x][y] = pWorld[x - 1][y + 1];
- } else if ((x + 1 < worldW) && (y - 1 >= 0) && (pWorld[x + 1][y - 1] != none)) {
- pWorld[x][y] = pWorld[x + 1][y - 1];
- } else if ((x - 1 >= 0) && (y - 1 >= 0) && (pWorld[x - 1][y - 1] != none)) {
- pWorld[x][y] = pWorld[x - 1][y - 1];
- } else {
- pWorld[x][y] = (char)realRand(1, 3);
- }
- } else {
- pWorld[x][y] = none;
- }
- drawObject(x, y, pWorld[x][y]);
- }
- }
- // dirty hack to make the last piece untouchable (as it mess the console buffer)
- pWorld[worldW - 1][worldH - 1] = rock;
- drawObject(worldW - 1, worldH - 1, pWorld[worldW - 1][worldH - 1]);
- for (i = 0; i < numCoins; i++) {
- // trying to place coins in the open area
- while (1) {
- x = realRand(1, worldW - 2);
- y = realRand(1, worldH - 2);
- 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)) {
- break;
- }
- }
- pWorld[x][y] = coin;
- drawObject(x, y, pWorld[x][y]);
- }
- for (i = 0; i < startEnemies + level; i++) {
- // trying to place enemies in the open area
- while (1) {
- x = realRand(1, worldW - 2);
- y = realRand(1, worldH - 2);
- 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))) {
- break;
- }
- }
- pWorld[x][y] = enemy;
- drawObject(x, y, pWorld[x][y]);
- }
- // placing the player in the open area
- while (1) {
- playerX = realRand(1, worldW - 2);
- playerY = realRand(1, worldH - 2);
- 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)) {
- break;
- }
- }
- // for debug purposes
- //printf("[%d]",playerX);
- //printf("[%d]",playerY);
- drawObject(playerX, playerY, player);
- // setting the console to the desired size
- setConsole(worldW, worldH);
- }
- void endGame(char won) {
- drawObject(playerX, playerY, pWorld[playerX][playerY]);
- HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
- COORD coord1 = { worldW / 2 - 4, worldH / 2 - 2 };
- SetConsoleTextAttribute(hCon, BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE);
- SetConsoleCursorPosition(hCon, coord1);
- printf("Level %d", level);
- if (won != TRUE) {
- COORD coord2 = { worldW / 2 - 5, worldH / 2 };
- SetConsoleCursorPosition(hCon, coord2);
- printf("Game over!");
- level = 0;
- } else {
- COORD coord2 = { worldW / 2 - 10, worldH / 2 };
- SetConsoleCursorPosition(hCon, coord2);
- printf("You won in %d turns!", numOfTurns);
- }
- COORD coord3 = { worldW / 2 - 11, worldH / 2 + 2 };
- SetConsoleCursorPosition(hCon, coord3);
- printf("Press ENTER to continue", level);
- while ((ch = get_code()) != KEY_ESC) {
- // restart the game on enter
- if (ch == KEY_RETURN) {
- createWorld();
- return;
- }
- }
- exit(0);
- }
- int main() {
- srand((unsigned int)time(NULL));
- char playerMoved;
- SetConsoleTitle(TEXT(myName));
- createWorld();
- while ((ch = get_code()) != KEY_ESC) {
- playerMoved = FALSE;
- switch (ch) {
- case ARROW_UP:
- if (playerY - 1 >= 0) {
- if ((pWorld[playerX][playerY - 1] == none) || (pWorld[playerX][playerY - 1] == coin) || (pWorld[playerX][playerY - 1] == enemy)) {
- drawObject(playerX, playerY, pWorld[playerX][playerY]);
- playerY -= 1;
- playerMoved = TRUE;
- }
- }
- break;
- case ARROW_DOWN:
- if (playerY + 1 < worldH) {
- if ((pWorld[playerX][playerY + 1] == none) || (pWorld[playerX][playerY + 1] == coin) || (pWorld[playerX][playerY + 1] == enemy)) {
- drawObject(playerX, playerY, pWorld[playerX][playerY]);
- playerY += 1;
- playerMoved = TRUE;
- }
- }
- break;
- case ARROW_LEFT:
- if (playerX - 1 >= 0) {
- if ((pWorld[playerX - 1][playerY] == none) || (pWorld[playerX - 1][playerY] == coin) || (pWorld[playerX - 1][playerY] == enemy)) {
- drawObject(playerX, playerY, pWorld[playerX][playerY]);
- playerX -= 1;
- playerMoved = TRUE;
- }
- }
- break;
- case ARROW_RIGHT:
- if (playerX + 1 < worldW) {
- if ((pWorld[playerX + 1][playerY] == none) || (pWorld[playerX + 1][playerY] == coin) || (pWorld[playerX + 1][playerY] == enemy)) {
- drawObject(playerX, playerY, pWorld[playerX][playerY]);
- playerX += 1;
- playerMoved = TRUE;
- }
- }
- break;
- }
- if (pWorld[playerX][playerY] == enemy) {
- endGame(FALSE);
- }
- if (playerMoved == TRUE) {
- for (x = 0; x < worldW; x++) {
- for (y = 0; y < worldH; y++) {
- if (pWorld[x][y] == enemy) {
- int distX = x - playerX;
- int distY = y - playerY;
- if ((distX <= enemyRange) && (distY <= enemyRange)) {
- if (abs(distX) > abs(distY)) {
- // closer by y
- if (distX > 0) {
- if (moveEnemy(x, y, dirLeft) != TRUE) {
- if (realRand(0,1) == 1) {
- if (moveEnemy(x, y, dirUp) != TRUE) {
- if (moveEnemy(x, y, dirDown) != TRUE) moveEnemy(x, y, dirRight);
- }
- } else {
- if (moveEnemy(x, y, dirDown) != TRUE) {
- if (moveEnemy(x, y, dirUp) != TRUE) moveEnemy(x, y, dirRight);
- }
- }
- }
- } else {
- if (moveEnemy(x, y, dirRight) != TRUE) {
- if (realRand(0, 1) == 1) {
- if (moveEnemy(x, y, dirUp) != TRUE) {
- if (moveEnemy(x, y, dirDown) != TRUE) moveEnemy(x, y, dirLeft);
- }
- } else {
- if (moveEnemy(x, y, dirDown) != TRUE) {
- if (moveEnemy(x, y, dirUp) != TRUE) moveEnemy(x, y, dirLeft);
- }
- }
- }
- }
- } else {
- // closer by x
- if (distY > 0) {
- if (moveEnemy(x, y, dirUp) != TRUE) {
- if (realRand(0, 1) == 1) {
- if (moveEnemy(x, y, dirLeft) != TRUE) {
- if (moveEnemy(x, y, dirRight) != TRUE) moveEnemy(x, y, dirDown);
- }
- } else {
- if (moveEnemy(x, y, dirRight) != TRUE) {
- if (moveEnemy(x, y, dirLeft) != TRUE) moveEnemy(x, y, dirDown);
- }
- }
- }
- } else {
- if (moveEnemy(x, y, dirDown) != TRUE) {
- if (realRand(0, 1) == 1) {
- if (moveEnemy(x, y, dirLeft) != TRUE) {
- if (moveEnemy(x, y, dirRight) != TRUE) moveEnemy(x, y, dirUp);
- }
- } else {
- if (moveEnemy(x, y, dirRight) != TRUE) {
- if (moveEnemy(x, y, dirLeft) != TRUE) moveEnemy(x, y, dirUp);
- }
- }
- }
- }
- }
- } else {
- moveEnemy(x, y, realRand(0, 3));
- }
- }
- }
- }
- for (x = 0; x < worldW; x++) {
- for (y = 0; y < worldH; y++) {
- if (pWorld[x][y] == movedEnemy) {
- pWorld[x][y] = enemy;
- }
- }
- }
- if (playerMoved == TRUE) {
- numOfTurns++;
- }
- drawObject(playerX, playerY, player);
- if (pWorld[playerX][playerY] == enemy) {
- endGame(FALSE);
- }
- if (pWorld[playerX][playerY] == coin) {
- pWorld[playerX][playerY] = none;
- coinsCollected++;
- if (coinsCollected == numCoins) {
- endGame(TRUE);
- }
- }
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement