| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608 |
- //
- // MineSweeper By Andriy Doroshchuk
- //
- global cursorOverClosed = CA.F_RED | CA.F_INTENSITY | CA.B_BLACK | CA.TRAILING_BYTE;
- global cursorOverOpened = CA.F_RED | CA.F_INTENSITY | CA.B_BLUE | CA.TRAILING_BYTE;
- global frameColor = CA.F_RED | CA.F_GREEN | CA.F_BLUE | CA.B_BLACK | CA.TRAILING_BYTE;
- global closedColor = CA.F_BLUE | CA.B_BLACK | CA.TRAILING_BYTE;
- global openedColor = CA.F_BLUE | CA.B_BLUE | CA.TRAILING_BYTE;
- global numberColor = CA.F_BLUE | CA.F_GREEN| CA.F_INTENSITY | CA.B_BLUE | CA.TRAILING_BYTE;
- global markColor = CA.F_BLUE | CA.F_RED | CA.F_INTENSITY | CA.B_BLUE | CA.TRAILING_BYTE;
- global mineColor = CA.F_GREEN| CA.F_RED | CA.B_BLUE | CA.TRAILING_BYTE;
- global helpColor = CA.F_GREEN| CA.F_RED | CA.F_BLUE |CA.B_BLUE | CA.TRAILING_BYTE;
- global winColor = CA.F_GREEN| CA.F_INTENSITY | CA.B_BLACK | CA.TRAILING_BYTE;
- global looseColor = CA.F_RED | CA.F_INTENSITY | CA.B_BLACK | CA.TRAILING_BYTE;
- // wait till key will be released
- global WaitForKey = function(key)
- {
- for (;ISPRESSED(key);){}
- };
- // print debug message
- global DebugText = function(text)
- {
- CATTRIB(frameColor);
- XYTEXT(0, 0, text);
- };
- game = table(
- x = 15,
- y = 0,
- lx = 30,
- ly = 15,
- mineCurr = 0,
- mineMax = 10,
- currLevel = 2,
- cX = 0,
- cY = 0,
- field = table(),
- // index in the field
- Index = function(x, y)
- {
- return (y*.lx+x);
- },
- // draw field frame
- DrawFrame = function()
- {
- i;
- // set color
- CATTRIB(frameColor);
- // borders
- for (i=.x+1; i<.x+.lx+1; i=i+1)
- {
- XYTEXT(i, .y, "-");
- XYTEXT(i, .y+.ly+1, "-");
- }
- for (i=.y+1; i<.y+.ly+1; i=i+1)
- {
- XYTEXT(.x, i, "|");
- XYTEXT(.x+.lx+1, i, "|");
- }
- // corners
- XYTEXT(.x, .y, "\1");
- XYTEXT(.x+.lx+1, .y, "\1");
- XYTEXT(.x, .y+.ly+1, "\1");
- XYTEXT(.x+.lx+1, .y+.ly+1, "\1");
- // count
- XYTEXT(.x+3, .y, "[" + .mineCurr.String() + ":" + .mineMax.String() + "]");
- },
- // field cell drawing
- DrawCell = function(x, y, cursor)
- {
- index = .Index(x, y);
- // debug cell = .field[index].String();
- cell = " ";
- // closed cell
- if (.field[index] < 10)
- {
- if (cursor)
- {
- CATTRIB(cursorOverClosed);
- cell = "W";
- }
- else
- {
- CATTRIB(closedColor);
- }
- }
- // opened cell
- else if (.field[index] < 20)
- {
- if (.field[index] == 10)
- {
- if (cursor)
- {
- CATTRIB(cursorOverOpened);
- cell = "W";
- }
- else
- {
- CATTRIB(openedColor);
- }
- }
- else if (.field[index] < 19)
- {
- if (cursor)
- {
- CATTRIB(cursorOverOpened);
- }
- else
- {
- CATTRIB(numberColor);
- }
- val = .field[index] % 10;
- cell = val.String();
- }
- else
- {
- CATTRIB(mineColor);
- cell = "@";
- }
- }
- // intended mine
- else
- {
- if (cursor)
- {
- CATTRIB(cursorOverOpened);
- }
- else
- {
- CATTRIB(markColor);
- }
- cell = "?";
- }
- XYTEXT(.x+x+1, .y+y+1, cell);
- },
- // field cell drawing
- DrawCurrCell = function(cursor)
- {
- .DrawCell(.cX, .cY, cursor);
- },
- // field drawing
- DrawField = function()
- {
- i; j;
- .DrawFrame();
- for (i=0; i<.lx; i=i+1)
- {
- for (j=0; j<.ly; j=j+1)
- {
- .DrawCell(i, j, 0);
- }
- }
- },
- // help string
- HelpString = function(msg, line, mode)
- {
- if (mode == 1)
- {
- CATTRIB(CA.F_BLUE | CA.F_GREEN | CA.F_INTENSITY | CA.B_BLACK | CA.TRAILING_BYTE);
- }
- else if (mode == 2)
- {
- CATTRIB(CA.F_RED | CA.B_BLACK | CA.TRAILING_BYTE);
- }
- else
- {
- CATTRIB(CA.F_GREEN | CA.B_BLACK | CA.TRAILING_BYTE);
- }
- XYTEXT(0, 25-line, " ");
- XYTEXT((80-msg.Length())/2, 25-line, msg);
- },
- // Initialise field
- InitField = function(level)
- {
- i; j;
- t1;t2;
- count; position; index;
- // clear screen
- CATTRIB(frameColor);
- CLS();
- // set current level
- .currLevel = level;
- // field extents
- if (level == 1)
- {
- .lx = 10;
- .ly = 10;
- .mineMax = 8;
- }
- else if (level == 2)
- {
- .lx = 18;
- .ly = 15;
- .mineMax = 35;
- }
- else
- {
- .lx = 30;
- .ly = 15;
- .mineMax = 90;
- }
- .x = (80-.lx)/2;
- .mineCurr = 0;
- // init field contents
- max = .lx*.ly;
- for (i=0; i<max; i=i+1)
- {
- .field[i] = 0;
- }
- // put mines on the field
- for (count=1; count<=.mineMax; count=count+1)
- {
- position = randint(0, .lx*.ly+1-count);
- for (i=0; i<.lx; i=i+1)
- {
- for (j=0; j<.ly; j=j+1)
- {
- index = .Index(i, j);
- if (.field[index] == 0)
- {
- if (position == 0)
- {
- .field[index] = 9;
- i = .lx;
- j = .ly;
- }
- else
- {
- position = position - 1;
- }
- }
- }
- }
- }
- // calculate mines environment
- for (i=0; i<.lx; i=i+1)
- {
- for (j=0; j<.ly; j=j+1)
- {
- if (.field[.Index(i, j)] == 9)
- {
- for (t1=i-1; t1<i+2; t1=t1+1)
- {
- for (t2=j-1; t2<j+2; t2=t2+1)
- {
- if ((t1!=i || t2!=j)
- && (t1>=0) && (t1<.lx)
- && (t2>=0) && (t2<.ly))
- {
- index = .Index(t1, t2);
- if (.field[index] < 9)
- {
- .field[index] = .field[index] + 1;
- }
- }
- }
- }
- }
- }
- }
- // draw field frame
- .DrawFrame();
- // set current cell
- .cX=.lx/2;
- .cY=.ly/2;
- .DrawField();
- .DrawCell(.cX, .cY, 1);
- .HelpString("", 4, 0);
- .HelpString("F2 - beginner. F3 - intermediate. F4 - expert", 2, 0);
- .HelpString("Enter - open. Space - mark as a mine. Backspace - open around.", 1, 0);
- },
- // restart current game
- RestartField = function()
- {
- .InitField(.currLevel);
- },
- // restart game after finishing
- Restart = function(win)
- {
- .HelpString("", 2, 0);
- .HelpString("", 1, 0);
- if (win)
- {
- .HelpString("Congratulations, you won! Press F1 to continue.", 4, 1);
- for (; !ISPRESSED(112);){}
- }
- else
- {
- .HelpString("Sorry, you are dead! Press F1 to continue.", 4, 2);
- .DrawField();
- }
- for (; !ISPRESSED(112);){}
- .RestartField();
- },
- // field opening when open an empty cell
- CheckCell = function(x, y)
- {
- i; j;
- index = .Index(x, y);
- if (.field[index] == 0)
- {
- .field[index] = 10;
- // check surrounding
- for (i=x-1; i<x+2; i=i+1)
- {
- for (j=y-1; j<y+2; j=j+1)
- {
- if ((i!=x || j!=y)
- && (i>=0) && (i<.lx)
- && (j>=0) && (j<.ly))
- {
- .CheckCell(i, j);
- }
- }
- }
- }
- else
- {
- if (.field[index] < 9)
- {
- .field[index] = .field[index] + 10;
- }
- }
- .DrawCell(x, y, 0);
- },
- // check win condition
- CheckWin = function()
- {
- i; j; index;
- count = 0;
- for (i=0; i<.lx; i=i+1)
- {
- for (j=0; j<.ly; j=j+1)
- {
- index = .Index(i, j);
- if (.field[index] < 10)
- {
- count = 0;
- i = .lx;
- j = .ly;
- }
- else if (.field[index] >= 20)
- {
- count = count + 1;
- }
- }
- }
- if (count == .mineMax)
- {
- .DrawCell(.cX, .cY, 0);
- .Restart(1);
- }
- else
- {
- .DrawCell(.cX, .cY, 1);
- }
- },
- // open field cell
- OpenCell = function(x, y, check)
- {
- i; j;
- index = .Index(x, y);
- if (!check)
- {
- if (.field[index] >= 20)
- {
- return;
- }
- }
- // check the field
- if (check && (.field[index] % 10) == 9)
- {
- for (i=0; i<.lx; i=i+1)
- {
- for (j=0; j<.ly; j=j+1)
- {
- index = .Index(i, j);
- .field[index] = (.field[index] % 10) + 10;
- }
- }
- .Restart(0);
- }
- else
- {
- .CheckCell(x, y);
- .CheckWin();
- }
- },
- // open cells around open mine
- HelperCell = function()
- {
- i; j;
- index = .Index(.cX, .cY);
- // perform the action only if the cell is already open
- if (.field[index]>=10 && .field[index]<20)
- {
- // calculate mines around this cell
- mines = 0;
- for (i=.cX-1; i<.cX+2; i=i+1)
- {
- for (j=.cY-1; j<.cY+2; j=j+1)
- {
- if ((i!=.cX || j!=.cY)
- && (i>=0) && (i<.lx)
- && (j>=0) && (j<.ly))
- {
- index = .Index(i, j);
- if (.field[index] >= 20)
- {
- mines = mines + 1;
- }
- }
- }
- }
- // check that we can open
- index = .Index(.cX, .cY);
- if (mines == (.field[index] % 10))
- {
- for (i=.cX-1; i<.cX+2; i=i+1)
- {
- for (j=.cY-1; j<.cY+2; j=j+1)
- {
- if ((i!=.cX || j!=.cY)
- && (i>=0) && (i<.lx)
- && (j>=0) && (j<.ly))
- {
- .OpenCell(i, j, 0);
- }
- }
- }
- }
- }
- },
- // move cursor
- Move = function(dir)
- {
- .DrawCurrCell(0);
- if (dir == 1)
- {
- if (.cY > 0)
- {
- .cY = .cY - 1;
- }
- }
- else if (dir == 3)
- {
- if (.cY<.ly-1)
- {
- .cY = .cY + 1;
- }
- }
- else if (dir == 0)
- {
- if (.cX > 0)
- {
- .cX = .cX - 1;
- }
- }
- else if (dir == 2)
- {
- if (.cX<.lx-1)
- {
- .cX = .cX + 1;
- }
- }
- WaitForKey(37+dir);
- .DrawCurrCell(1);
- },
- // open current cell
- Open = function()
- {
- WaitForKey(13);
- .OpenCell(.cX, .cY, 1);
- },
- // mark current cell
- Mark = function()
- {
- WaitForKey(32);
- index = .Index(.cX, .cY);
- if (.field[index] < 10)
- {
- .field[index] = (.field[index] % 10) + 20;
- .mineCurr = .mineCurr + 1;
- .DrawFrame();
- .CheckWin();
- }
- else if (.field[index] >= 20)
- {
- .field[index] = .field[index] % 10;
- .mineCurr = .mineCurr -1;
- .DrawFrame();
- .DrawCurrCell(1);
- }
- },
- // init the game
- Run = function()
- {
- CURSOR(0, 0);
- .RestartField();
- for (;!ISPRESSED(27);)
- {
- if (ISPRESSED(37))
- {
- .Move(0);
- }
- else if (ISPRESSED(38))
- {
- .Move(1);
- }
- else if (ISPRESSED(39))
- {
- .Move(2);
- }
- else if (ISPRESSED(40))
- {
- .Move(3);
- }
- else if (ISPRESSED(32))
- {
- .Mark();
- }
- else if (ISPRESSED(13))
- {
- .Open();
- }
- else if (ISPRESSED(8))
- {
- .HelperCell();
- WaitForKey(8);
- }
- else if (ISPRESSED(113))
- {
- WaitForKey(113);
- .InitField(1);
- }
- else if (ISPRESSED(114))
- {
- WaitForKey(114);
- .InitField(2);
- }
- else if (ISPRESSED(115))
- {
- WaitForKey(115);
- .InitField(3);
- }
- else
- {
- DebugText(" ");
- }
- }
- }
- );
- game.Run();
|