⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 minesweeper.mpsrc

📁 Minesweeper MidletPascal source code
💻 MPSRC
字号:
program Minesweeper;

const		maxWidth = 30;

				maxHeight = 30;

				minesDensity = 10; { 10 percent of the fields contain mines }



var	xPos, yPos              : integer;

		fieldWidth, fieldHeight : integer;

		numOfMines              : integer;

		cellSize                : integer;

		xDelta, yDelta          : integer;

		quit, play, clicked     : command;



		{

			values at the mineField element are two digit numbers where:

			the first digit is 0-8, the number of the mines around

			the second digit is:

			0 - does not contain a mine/1-contains a mine

			0 - is not opened/2 - is opened

			0 - is not marked/4 - is marked as a mine

		}

		mineField: array[1..maxWidth, 1..maxHeight] of integer;

		

		{

			the imageArray contains the block images:

			1-8: images with numbers 1-8

			9 -  element not yet open

			10 - empty element that is open

			11 - mine element

			12 - element marked as a mine

		}

		imageArray: array[1..12] of image;

		

		gameStatus : integer; { 0 - playing, 1 - lost, 2 - won }





{ initialize - initializes the global variables and the mine field }

procedure initialize;

var	i, j: integer;

		width, height: integer;

begin



	{ initialize the cursor position }

	xPos := 1;

	yPos := 1;

	

	

	{ load the images }

	for i:=1 to 12 do

	begin

		imageArray[i] := loadImage('/' + i + '.png');

	end;

	

	

	{ calculate the width and height of the field }

	cellSize := getImageWidth(imageArray[1]);

	fieldWidth := getWidth / cellSize;

	fieldHeight := getHeight / cellSize;

	

	if fieldWidth > maxWidth then fieldWidth := maxWidth;

	if fieldHeight > maxHeight then fieldHeight := maxHeight;

	

	xDelta := (getWidth - fieldWidth*cellSize) / 2;

	yDelta := (getHeight - fieldHeight*cellSize) / 2;

	

	numOfMines := fieldWidth * fieldHeight * minesDensity / 100;

	

	gameStatus := 0;	

	

	{ initialize the game field }

	for i:=1 to fieldWidth do

		for j:=1 to fieldHeight do

		mineField[i,j] := 0;

	

	

	{ place the mines }

	for i:=1 to numOfMines do

	begin

		width := random(fieldWidth) + 1;

		height := random(fieldHeight) + 1;

		

		if (mineField[width,height] <> 0) 

       or ((width = 1) and (height = 1)) then

       i := i - 1;

    else

			mineField[width,height] := 1;

	end;

	

	{ calculate the number of surronding mines for each cell }

	for i:=1 to fieldWidth do

		  for j:=1 to fieldHeight do

		  begin

		    if ((mineField[i,j] mod 10) mod 2) = 1 then

		    begin

		    

		      if i>1 then

		        mineField[i-1,j] := mineField[i-1,j] + 10;

		        

		      if i<fieldWidth then

		        mineField[i+1,j] := mineField[i+1,j] + 10;

		        

		      if j>1 then

		        mineField[i,j-1] := mineField[i,j-1] + 10;

		        

		      if j<fieldHeight then

		        mineField[i,j+1] := mineField[i,j+1] + 10;

		        

		      if (i>1) and (j>1) then

		        mineField[i-1,j-1] := mineField[i-1,j-1] + 10;

		        

		      if (i<fieldWidth) and (j>1) then

		        mineField[i+1,j-1] := mineField[i+1,j-1] + 10;

		        

		      if (i<fieldWidth) and (j<fieldHeight) then

		        mineField[i+1,j+1] := mineField[i+1,j+1] + 10;

		        

		      if (i>1) and (j<fieldHeight) then

		        mineField[i-1,j+1] := mineField[i-1,j+1] + 10;

		    

		    end;

		  end; 

end;





{ game over - returns true if the game is over and sets the

global game success code }

function gameOver: boolean;

var i,j:integer;

begin

  gameStatus := 2;

  

  for i:=1 to fieldWidth do

    for j:=1 to fieldHeight do

    begin

      { if a cell is open and it contains a mine, the player lost }

      if ((((mineField[i,j] mod 10) mod 4)div 2) = 1)

        and (((mineField[i,j] mod 10) mod 2) = 1) then

      begin        

        gameStatus := 1;

        

        { these two commands act as break }

        i := fieldWidth - 1;

        j := fieldHeight - 1;

      end;



      { if a cell is not open, but it does not contain a mine, the game is still on }

      if (not (((mineField[i,j] mod 10) mod 2) = 1)) 

        and not((((mineField[i,j] mod 10) mod 4)div 2) = 1)

        and (gameStatus <> 1)

      then

        gameStatus := 0;

      

    end;

    

	if gameStatus = 0 then

	  gameOver := false;

	else

	  gameOver := true; 

    

end;





{ drawField - draws the current state of the field on the screen }

procedure drawField;

var	i, j                : integer;

    imageIndex          : integer;

    text                : string;

    x, y, width, height : integer;

begin

  { clear the screen }

  setColor(0, 0, 0);

  fillRect(0, 0, getWidth, getHeight);

	

	{ draw all the elements }

	for i:=1 to fieldWidth do

		for j:=1 to fieldHeight do

		begin

		

		  { if the element is open }

			if (((mineField[i,j] mod 10) mod 4)div 2) = 1 then

			begin

			

			  { if it contains the mine }

			  if ((mineField[i,j] mod 10) mod 2) = 1 then

			    imageIndex := 11;

			  else

			    imageIndex := mineField[i,j] div 10;

			    

			    if imageIndex = 0 then imageIndex := 10;

			end;

			else { the element is not open }

			begin

			  { if the non opened elemet is marked as a mine }

			  if ((mineField[i,j] mod 10) div 4) = 1 then

			    imageIndex := 12;

			  else

			    imageIndex := 9;

			end;

			

			drawImage(imageArray[imageIndex], (i-1)*cellSize + xDelta, (j-1)*cellSize + yDelta);

		end;

		

		{ draw the rectangle around the selected cell }

		setColor(0, 0, 255);

		drawRect((xPos-1)*cellSize + xDelta, (yPos-1)*cellSize + yDelta, cellSize, cellSize);

		drawRect((xPos-1)*cellSize + xDelta + 1, (yPos-1)*cellSize + yDelta + 1, cellSize-2, cellSize-2);

		

		if gameStatus = 1 then

		begin

		  setColor(63, 0, 0);

		  text := 'You lost the game';

		end;

		  

		if gameStatus = 2 then

		begin

		  setColor(0, 63, 0);

		  text := 'You won!';

		end;

		  

		{ print the game status inside a rectangle }

		if gameStatus <> 0 then

		begin

			setFont(FONT_FACE_SYSTEM, FONT_STYLE_BOLD, FONT_SIZE_MEDIUM);

		  width := getStringWidth(text) + 6;

		  height := getStringHeight(text) + 6;

	

		  x := (getWidth - width)/2;

		  y := (getHeight - height)/2;

		  

		  drawRect(x, y, width, height);

		  drawRect(x+1, y+1, width-2, height-2);

		  

		  setColor(getColorRed*2, getColorGreen*2, 0);

		  fillRect(x+2, y+2, width-3, height-3);

		   

		  setColor(255, 255, 255);		  

		  drawText(text, x+3, y+3);

		end;

		

		repaint;		

end;





{ openEmptyMine - recursively opens all surrounding empty mines }

procedure openEmptyMine(x,y: integer);

begin

  if ((mineField[x, y] mod 10) mod 4) div 2 = 0 then

  begin

    mineField[x, y] := mineField[x, y] + 2;

    

    { if the current mine field is labeled 0, open it }

    if mineField[x,y] < 10 then

    begin            

      { open all surrounding fields }

      if x>1 then

				openEmptyMine(x-1, y);

			

		  if x<fieldWidth then

				openEmptyMine(x+1, y);

			

		  if y>1 then

				openEmptyMine(x, y-1);

			

		  if y<fieldHeight then

				openEmptyMine(x, y+1);

			

		  if (x>1) and (y>1) then

				openEmptyMine(x-1, y-1);

			

		  if (x<fieldWidth) and (y>1) then

				openEmptyMine(x+1, y-1);

			

		  if (x<fieldWidth) and (y<fieldHeight) then

				openEmptyMine(x+1, y+1);

			

		  if (x>1) and (y<fieldHeight) then

				openEmptyMine(x-1, y+1);

    end;

    

  end;

end;



{ openMine - opens the mine that contains the cursor and opens all

  surrounding empty cells }

procedure openMine(x, y: integer);

begin

  if ((mineField[x, y] mod 10) mod 4) div 2 = 0 then

  begin 

	  if mineField[x,y] < 10 then

			openEmptyMine(x,y);

	  else

			mineField[x, y] := mineField[x, y] + 2;

  end;  

end;





{ playGame - the main game loop }

procedure playGame;

var		mineCommand, quitCommand, clickedCommand : command;

			keyAction : integer;

begin

  mineCommand := createCommand('*', CM_SCREEN, 1);

  quitCommand := createCommand('Exit', CM_EXIT, 1);

  addCommand(mineCommand);

  addCommand(quitCommand);

  repaint;

  

  repeat

    { read the key from the keypad }

		keyAction := keyToAction(getKeyClicked);

		if keyAction <> GA_NONE then

		begin

		  if keyAction = GA_UP then

		    yPos := yPos - 1;

		    

		  if keyAction = GA_DOWN then

		    yPos := yPos + 1;

		    

		  if keyAction = GA_LEFT then

		    xPos := xPos - 1;

		    

		  if keyAction = GA_RIGHT then

		    xPos := xPos + 1;

		    

		  if xPos < 1 then xPos := 1;

		  if yPos < 1 then yPos := 1;

		  if xPos > fieldWidth then xPos := fieldWidth;

		  if yPos > fieldWidth then yPos := fieldWidth;

		  

		  if keyAction = GA_FIRE then

		    openMine(xPos, yPos);

		

			drawField;

		end;

		

		{ read the pressed command }

		clickedCommand := getClickedCommand;

		if clickedCommand = mineCommand then

		begin

		  if ((mineField[xPos, yPos] mod 10) div 4) = 1 then

		    mineField[xPos, yPos] := mineField[xPos, yPos] - 4;

		  else

		    mineField[xPos, yPos] := mineField[xPos, yPos] + 4;

		    

			drawField;

		end;		

		

  until gameOver or (clickedCommand = quitCommand);

  

  drawField;

  

  removeCommand(mineCommand);

  removeCommand(quitCommand);

end;





{ showWelcomeScreen - displays the game info screen }

procedure showWelcomeScreen;

var

  textToDisplay : string;

  textXPos      : integer;

  textYPos      : integer;

begin

	setColor(255, 255, 255);  

  fillRect(0, 0, getWidth, getHeight);  


  setColor(0, 0, 255);  

  setFont(FONT_FACE_PROPORTIONAL, FONT_STYLE_BOLD, FONT_SIZE_LARGE);


  textToDisplay := 'Minesweeper';

  textXPos := (getWidth - getStringWidth(textToDisplay)) div 2; 

  textYPos := (getHeight - getStringHeight(textToDisplay)) / 2;

  drawText(textToDisplay, textXPos, textYPos);

  textYPos := textYPos + getStringHeight(textToDisplay);
  

  setColor(0, 0, 0);  


  setFont(FONT_FACE_PROPORTIONAL, FONT_STYLE_PLAIN, FONT_SIZE_SMALL);  


  textToDisplay := 'Created with MIDletPascal';

  textXPos := (getWidth - getStringWidth(textToDisplay)) div 2;

  drawText(textToDisplay, textXPos, textYPos);

  textYPos := textYPos + getStringHeight(textToDisplay);


  repaint;
end;





begin

  showWelcomeScreen;

  

  repeat

  until getKeyClicked <> KE_NONE;

  

  repeat
	  initialize;

	  drawField;

	  playGame;

	  

	  if gameStatus <> 0 then

	  begin

		  quit := createCommand('OK', CM_OK, 1);

		  addCommand(quit);

		  repaint;

		  repeat

				clicked := getClickedCommand;

		  until clicked <> emptyCommand;	  

		  removeCommand(quit);

	  end;

	  

	  showWelcomeScreen;

	  

	  quit := createCommand('Exit', CM_EXIT, 1);

	  play := createCommand('Play', CM_OK, 1);

	  

	  addCommand(quit);

	  addCommand(play);

	  repaint;

	  

	  repeat

	    clicked := getClickedCommand;

	  until clicked <> emptyCommand;

	  

	  removeCommand(quit);

	  removeCommand(play);

	until clicked = quit;
end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -