aboutsummaryrefslogtreecommitdiffstats
path: root/demos/applications/minesweeper/mines.c
diff options
context:
space:
mode:
Diffstat (limited to 'demos/applications/minesweeper/mines.c')
-rw-r--r--demos/applications/minesweeper/mines.c446
1 files changed, 0 insertions, 446 deletions
diff --git a/demos/applications/minesweeper/mines.c b/demos/applications/minesweeper/mines.c
deleted file mode 100644
index 55d70984..00000000
--- a/demos/applications/minesweeper/mines.c
+++ /dev/null
@@ -1,446 +0,0 @@
-#include <stdlib.h>
-#include "gfx.h"
-#include "mines.h"
-
-typedef struct { // Node properties
- uint8_t num; // Node number, how many mines around
- bool_t open; // Node shown or hidden
- bool_t check; // Node needs to be checked or not, used for opening up empty nodes
- bool_t flag; // Node is marked with flag by player
- uint16_t fieldNum; // Node number, used to randomize gamestart "animation"
-} nodeProps;
-
-static GEventMouse ev;
-static nodeProps minesField[MINES_FIELD_WIDTH][MINES_FIELD_HEIGHT]; // Mines field array
-static bool_t minesGameOver = FALSE;
-static bool_t minesGameWinner = FALSE;
-static int16_t minesEmptyNodes; // Empty node counter
-static int16_t minesFlags; // Flag counter
-static int16_t minesTime; // Time counter
-static GTimer minesTimeCounterTimer;
-static const char* minesGraph[] = {"1.bmp","2.bmp","3.bmp","4.bmp","5.bmp","6.bmp","7.bmp","8.bmp", "closed.bmp", "empty.bmp", "explode.bmp", "flag.bmp", "mine.bmp", "wrong.bmp"}; // 14 elements (0-13)
-static gdispImage minesImage;
-static uint8_t minesStatusIconWidth = 0;
-static uint8_t minesStatusIconHeight = 0;
-static bool_t minesFirstGame = TRUE; // Just don't clear field for the first time, as we have black screen already... :/
-static bool_t minesSplashTxtVisible = FALSE;
-#if MINES_SHOW_SPLASH
- static GTimer minesSplashBlink;
-#endif
-
-static int uitoa(unsigned int value, char* buf, int max)
-{
- int n = 0;
- int i = 0;
- int tmp = 0;
-
- if (!buf)
- return -3;
- if (2 > max)
- return -4;
-
- i=1;
- tmp = value;
- if (0 > tmp) {
- tmp *= -1;
- i++;
- }
-
- for (;;) {
- tmp /= 10;
- if (0 >= tmp)
- break;
- i++;
- }
- if (i >= max) {
- buf[0] = '?';
- buf[1] = 0x0;
- return 2;
- }
-
- n = i;
- tmp = value;
- if (0 > tmp) {
- tmp *= -1;
- }
-
- buf[i--] = 0x0;
- for (;;) {
- buf[i--] = (tmp % 10) + '0';
- tmp /= 10;
- if (0 >= tmp)
- break;
- }
-
- if (-1 != i) {
- buf[i--] = '-';
- }
-
- return n;
-}
-
-static void initRng(void)
-{
- srand(gfxSystemTicks());
-}
-
-static uint32_t randomInt(uint32_t max)
-{
- return rand() % max;
-}
-
-static void printStats(void)
-{
- char pps_str[12];
-
- font_t font = gdispOpenFont("fixed_5x8");
- uitoa(MINES_MINE_COUNT, pps_str, sizeof(pps_str));
- gdispFillString(minesStatusIconWidth+8, gdispGetHeight()-11, " ", font, Black, Black);
- gdispDrawString(minesStatusIconWidth+8, gdispGetHeight()-11, pps_str, font, White);
- uitoa(minesFlags, pps_str, sizeof(pps_str));
- gdispFillString(8+(minesStatusIconWidth*2)+gdispGetStringWidth("99999", font), gdispGetHeight()-11, " ", font, Black, Black);
- gdispDrawString(8+(minesStatusIconWidth*2)+gdispGetStringWidth("99999", font), gdispGetHeight()-11, pps_str, font, White);
- gdispCloseFont(font);
-}
-
-static void minesUpdateTime(void)
-{
- char pps_str[12];
-
- if (minesTime > 9999)
- minesTime = 9999;
-
- font_t font = gdispOpenFont("digital_7__mono_20");
- uitoa(minesTime, pps_str, sizeof(pps_str));
- gdispFillArea((MINES_FIELD_WIDTH*MINES_CELL_WIDTH)-gdispGetStringWidth("9999", font), gdispGetHeight()-15, gdispGetWidth(), 15, Black);
- gdispDrawString((MINES_FIELD_WIDTH*MINES_CELL_WIDTH)-gdispGetStringWidth(pps_str, font), gdispGetHeight()-15, pps_str, font, Lime);
- gdispCloseFont(font);
-}
-
-static void minesTimeCounter(void* arg)
-{
- (void)arg;
-
- minesTime++;
- minesUpdateTime();
-}
-
-static bool_t inRange(int16_t x, int16_t y)
-{
- if ((x >= 0) && (x < MINES_FIELD_WIDTH) && (y >= 0) && (y < MINES_FIELD_HEIGHT))
- return TRUE;
- else
- return FALSE;
-}
-
-static void showOne(int16_t x, int16_t y)
-{
- minesField[x][y].open = TRUE;
- if (minesField[x][y].flag) {
- minesField[x][y].flag = FALSE;
- minesFlags--;
- }
-
- gdispFillArea((x*MINES_CELL_WIDTH)+1, (y*MINES_CELL_HEIGHT)+1, MINES_CELL_WIDTH-1, MINES_CELL_HEIGHT-1, Black);
-
- if ((minesField[x][y].num > 0) && (minesField[x][y].num < 9)) {
- gdispImageOpenFile(&minesImage, minesGraph[minesField[x][y].num-1]);
- gdispImageDraw(&minesImage, (x*MINES_CELL_HEIGHT)+1, (y*MINES_CELL_WIDTH)+1, MINES_CELL_WIDTH, MINES_CELL_HEIGHT, 0, 0);
- gdispImageClose(&minesImage);
- minesEmptyNodes--;
- } else if (minesField[x][y].num == 9) {
- minesGameOver = TRUE;
- minesGameWinner = FALSE;
- gdispImageOpenFile(&minesImage, minesGraph[10]);
- gdispImageDraw(&minesImage, (x*MINES_CELL_HEIGHT)+1, (y*MINES_CELL_WIDTH)+1, MINES_CELL_WIDTH, MINES_CELL_HEIGHT, 0, 0);
- gdispImageClose(&minesImage);
- // Dirty HACK to not draw mine icon on GameOver event :D
- minesField[x][y].num = 0;
- } else if (minesField[x][y].num == 0) {
- gdispImageOpenFile(&minesImage, minesGraph[9]);
- gdispImageDraw(&minesImage, (x*MINES_CELL_HEIGHT)+1, (y*MINES_CELL_WIDTH)+1, MINES_CELL_WIDTH, MINES_CELL_HEIGHT, 0, 0);
- gdispImageClose(&minesImage);
- minesField[x][y].check = TRUE;
- minesEmptyNodes--;
- }
-}
-
-static void openEmptyNodes(void)
-{
- int16_t x, y, i, j;
- bool_t needToCheck = TRUE;
-
- while (needToCheck) {
- needToCheck = FALSE;
- for (x = 0; x < MINES_FIELD_WIDTH; x++) {
- for (y = 0; y < MINES_FIELD_HEIGHT; y++) {
- if (minesField[x][y].check) {
- for (i = -1; i <= 1; i++) {
- for (j = -1; j <= 1; j++) {
- if ((i != 0) || (j != 0)) { // We don't need to check middle node as it is the one we are checking right now! :D
- if (inRange(x+i,y+j)) {
- if (!minesField[x+i][y+j].open) showOne(x+i,y+j);
- if (minesField[x+i][y+j].check) needToCheck = TRUE;
- }
- }
- }
- }
- minesField[x][y].check = FALSE;
- }
- }
- }
- }
-}
-
-static DECLARE_THREAD_FUNCTION(thdMines, msg)
-{
- (void)msg;
- uint16_t x,y, delay;
- bool_t delayed = FALSE;
- while (!minesGameOver) {
- if (minesEmptyNodes == 0) {
- minesGameOver = TRUE;
- minesGameWinner = TRUE;
- }
- initRng();
- ginputGetMouseStatus(0, &ev);
- delayed = FALSE;
- if (ev.buttons & GINPUT_MOUSE_BTN_LEFT) {
- x = ev.x/MINES_CELL_WIDTH;
- y = ev.y/MINES_CELL_WIDTH;
- delay = 0;
- while (ev.buttons & GINPUT_MOUSE_BTN_LEFT) { // Wait until release
- ginputGetMouseStatus(0, &ev);
- gfxSleepMilliseconds(1);
- delay++;
- if (delay >= MINES_FLAG_DELAY) {
- delay = MINES_FLAG_DELAY;
- if (!delayed && inRange(x, y) && !minesField[x][y].open) {
- if (minesField[x][y].flag) {
- gdispImageOpenFile(&minesImage, minesGraph[8]);
- gdispImageDraw(&minesImage, (x*MINES_CELL_HEIGHT)+1, (y*MINES_CELL_WIDTH)+1, MINES_CELL_WIDTH-1, MINES_CELL_HEIGHT-1, 0, 0);
- gdispImageClose(&minesImage);
- minesField[x][y].flag = FALSE;
- minesFlags--;
- printStats();
- } else {
- gdispImageOpenFile(&minesImage, minesGraph[11]);
- gdispImageDraw(&minesImage, (x*MINES_CELL_HEIGHT)+1, (y*MINES_CELL_WIDTH)+1, MINES_CELL_WIDTH, MINES_CELL_HEIGHT, 0, 0);
- gdispImageClose(&minesImage);
- minesField[x][y].flag = TRUE;
- minesFlags++;
- printStats();
- }
- delayed = TRUE;
- }
- }
- }
- // Check time, if longer than MINES_FLAG_DELAY then add flag...
- if (delay < MINES_FLAG_DELAY) {
- if ((x < MINES_FIELD_WIDTH) && (y < MINES_FIELD_HEIGHT) && !minesField[x][y].open && !minesField[x][y].flag) {
- showOne(x, y);
- openEmptyNodes();
- printStats();
- }
- }
- }
- }
- THREAD_RETURN(0);
-}
-
-static void printGameOver(void)
-{
- if (minesGameOver) {
- font_t font = gdispOpenFont("DejaVuSans16");
- if (minesGameWinner) {
- gdispDrawString((gdispGetWidth()-gdispGetStringWidth("You LIVE!", font))/2, gdispGetHeight()-15, "You LIVE!", font, White);
- } else {
- gdispDrawString((gdispGetWidth()-gdispGetStringWidth("You DIED!", font))/2, gdispGetHeight()-15, "You DIED!", font, White);
- }
- gdispCloseFont(font);
- } else {
- gdispFillArea(0, gdispGetHeight()-25, gdispGetWidth(), 25, Black);
- }
-}
-
-static void initField(void)
-{
- int16_t x, y, mines, i, j;
-
- minesFlags = 0;
- minesGameOver = FALSE;
- printGameOver();
-
- font_t font = gdispOpenFont("fixed_5x8");
- gdispImageOpenFile(&minesImage, "plainmine.bmp");
- // Saving status icons width/height for later use
- minesStatusIconWidth = minesImage.width;
- minesStatusIconHeight = minesImage.height;
- gdispImageDraw(&minesImage, 4, gdispGetHeight()-minesImage.height, minesImage.width, minesImage.height, 0, 0);
- gdispImageClose(&minesImage);
- gdispImageOpenFile(&minesImage, "plainflag.bmp");
- gdispImageDraw(&minesImage, 4+minesImage.width+gdispGetStringWidth("99999", font), gdispGetHeight()-minesImage.height, minesImage.width, minesImage.height, 0, 0);
- gdispImageClose(&minesImage);
- gdispCloseFont(font);
- printStats();
-
- initRng();
-
- // Clearing/resetting field here...
- i = 0;
- for (x = 0; x < MINES_FIELD_WIDTH; x++) {
- for (y = 0; y < MINES_FIELD_HEIGHT; y++) {
- minesField[x][y].num = 0;
- minesField[x][y].open = FALSE;
- minesField[x][y].check = FALSE;
- minesField[x][y].flag = FALSE;
- minesField[x][y].fieldNum = i;
- i++;
- }
- }
-
- // Randomizing closed field drawing...
- for (x = 0; x < MINES_FIELD_WIDTH; x++) {
- for (y = 0; y < MINES_FIELD_HEIGHT; y++) {
- // Getting random node and swapping it with current
- i = randomInt(MINES_FIELD_WIDTH);
- j = randomInt(MINES_FIELD_HEIGHT);
- mines = minesField[x][y].fieldNum;
- minesField[x][y].fieldNum = minesField[i][j].fieldNum;
- minesField[i][j].fieldNum = mines;
- }
- }
-
- // Clearing nodes randomly
- if (!minesFirstGame) {
- for (x = 0; x < MINES_FIELD_WIDTH; x++) {
- for (y = 0; y < MINES_FIELD_HEIGHT; y++) {
- i = minesField[x][y].fieldNum/MINES_FIELD_HEIGHT;
- j = minesField[x][y].fieldNum-(i*MINES_FIELD_HEIGHT);
- gdispFillArea((i*MINES_CELL_WIDTH)+1, (j*MINES_CELL_HEIGHT)+1, MINES_CELL_WIDTH, MINES_CELL_HEIGHT, Black);
- gfxSleepMilliseconds(2);
- }
- }
- } else {
- minesFirstGame = FALSE;
- }
-
- // Drawing closed nodes randomly
- gdispImageOpenFile(&minesImage, minesGraph[8]);
- for (x = 0; x < MINES_FIELD_WIDTH; x++) {
- for (y = 0; y < MINES_FIELD_HEIGHT; y++) {
- i = minesField[x][y].fieldNum/MINES_FIELD_HEIGHT;
- j = minesField[x][y].fieldNum-(i*MINES_FIELD_HEIGHT);
- gdispImageDraw(&minesImage, (i*MINES_CELL_HEIGHT)+1, (j*MINES_CELL_WIDTH)+1, MINES_CELL_WIDTH, MINES_CELL_HEIGHT, 0, 0);
- gfxSleepMilliseconds(2);
- }
- }
- gdispImageClose(&minesImage);
- minesEmptyNodes = MINES_FIELD_WIDTH*MINES_FIELD_HEIGHT;
-
- // Placing mines in random nodes :D
- mines = 0;
- while (mines != MINES_MINE_COUNT) {
- x = randomInt(MINES_FIELD_WIDTH);
- y = randomInt(MINES_FIELD_HEIGHT);
- if (minesField[x][y].num != 9) {
- mines++;
- minesEmptyNodes--;
- minesField[x][y].num = 9;
- }
- }
-
- // Calculating numbers for nearby mine nodes
- for (x = 0; x < MINES_FIELD_WIDTH; x++) {
- for (y = 0; y < MINES_FIELD_HEIGHT; y++) {
- if (minesField[x][y].num != 9) {
- for (i = -1; i <= 1; i++) {
- for (j = -1; j <= 1; j++) {
- if ((i != 0) || (j != 0)) { // We don't need to check middle node as we already know it is not a mine! :D
- if (inRange(x+i,y+j) && (minesField[x+i][y+j].num == 9)) {
- minesField[x][y].num++;
- }
- }
- }
- }
- }
- }
- }
-
- minesTime = 0;
- minesUpdateTime();
- gtimerStart(&minesTimeCounterTimer, minesTimeCounter, 0, TRUE, 1000);
-}
-
-void minesStart(void)
-{
- int16_t x, y;
-
-#if MINES_SHOW_SPLASH
- gtimerStop(&minesSplashBlink);
- gdispClear(Black);
-#endif
-
- initField();
- gfxThreadCreate(0, 1024, NORMAL_PRIORITY, thdMines, 0);
- while (!minesGameOver) {
- gfxSleepMilliseconds(100);
- }
- printGameOver();
- gtimerStop(&minesTimeCounterTimer);
-
- if (!minesGameWinner) {
- // Print generated mines for player to see
- font_t font = gdispOpenFont("fixed_10x20");
- for (x = 0; x < MINES_FIELD_WIDTH; x++) {
- for (y = 0; y < MINES_FIELD_HEIGHT; y++) {
- if (minesField[x][y].num == 9 && !minesField[x][y].flag) {
- gdispImageOpenFile(&minesImage, minesGraph[12]);
- gdispImageDraw(&minesImage, (x*MINES_CELL_HEIGHT)+1, (y*MINES_CELL_WIDTH)+1, MINES_CELL_WIDTH, MINES_CELL_HEIGHT, 0, 0);
- gdispImageClose(&minesImage);
- }
- if (minesField[x][y].flag && (minesField[x][y].num != 9)) {
- gdispImageOpenFile(&minesImage, minesGraph[13]);
- gdispImageDraw(&minesImage, (x*MINES_CELL_HEIGHT)+1, (y*MINES_CELL_WIDTH)+1, MINES_CELL_WIDTH, MINES_CELL_HEIGHT, 0, 0);
- gdispImageClose(&minesImage);
- }
- }
- }
- gdispCloseFont(font);
- }
-}
-
-#if MINES_SHOW_SPLASH
- static void minesSplashBlinker(void* arg)
- {
- (void)arg;
-
- minesSplashTxtVisible = !minesSplashTxtVisible;
-
- if (minesSplashTxtVisible) {
- gdispImageOpenFile(&minesImage, "splashtxt.bmp");
- } else {
- gdispImageOpenFile(&minesImage, "splashclr.bmp");
- }
-
- gdispImageDraw(&minesImage, (gdispGetWidth()/2)-150+93, (gdispGetHeight()/2)-100+161, 112, 10, 0, 0);
-
- gdispImageClose(&minesImage);
- }
-
- void minesShowSplash(void)
- {
- gdispImageOpenFile(&minesImage, "splash.bmp");
- gdispImageDraw(&minesImage, (gdispGetWidth()/2)-150, (gdispGetHeight()/2)-100, 300, 200, 0, 0);
- gdispImageClose(&minesImage);
-
- gtimerStart(&minesSplashBlink, minesSplashBlinker, 0, TRUE, 400);
- }
-#endif
-
-void minesInit(void)
-{
- initRng();
-
- gdispClear(Black);
-}