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

📄 mainform.cpp

📁 本人用BCB编写的扫雷小游戏
💻 CPP
📖 第 1 页 / 共 3 页
字号:

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include <Registry.hpp>
#include <stdlib.h>
#include <MMSystem.h>
#include "Mainform.h"
#include "CustomizeForm.h"
#include "Hero.h"
#include "HeroName.h"
#include "About.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

/***************************************************************************/

#define _Index(X,Y,COL) ((Y)*(COL) + (X))

const char g_RegistryPath[] = "MyMine";
const char g_Lost_SoundPath[] = "resource\\GameLost.wav";
const char g_Win_SoundPath[] = "resource\\GameWin.wav";
const char g_Second_SoundPath[] = "resource\\Second.wav";
const char g_ChmFile_Path[] = "resource\\mine.chm";
const char g_SysHelpFile_Path[] = "resource\\SysHelp.chm";

TImage *Image_Block, *Image_Number, *Image_Face;

int Xpos,Ypos;
int GridCol,GridRow,BombCount,GameLevel = l_Easy;
bool isHaveColor = true, isHaveQuestionMark = true, isHaveSound = false;

int UsedTime,BlockOpenCount,LeftBombCount,CurrentFace;
int GameStatus = g_Waiting;
bool isLeftBtnDown, isRightBtnDown, isLeftAndRightBtnDown;
TPoint CurrentPosition;
struct {
  int value;
  int view;
  int status;
}GridArray[g_MaxRow*g_MaxCol];

struct _hero hero[4];

/***************************************************************************/
void InitGridArray(int col,int row,int count, TPoint first)
{  
  for (int i=0; i<row*col; ++i)
  {
    GridArray[i].value  = 0;
    GridArray[i].view = b_Blank;
    GridArray[i].status = s_Default;
  }

  GridArray[first.y*col + first.x].value  = -1;
  for (int i=0; i<count; ++i)
  {
    int pos;

    do {
      pos = random(row*col);
    } while (GridArray[pos].value == -1);

    GridArray[pos].value = -1;
  }
  GridArray[first.y*col + first.x].value  = 0;

  for (int i=0; i<col; ++i)
  {
    for (int j=0; j<row; ++j)
    {
      int & value = GridArray[_Index(i,j,col)].value;
      int x, y;

      if (value) continue;

      for (int k=0; k<8; ++k)
      {
        x = i + DIR[k].x;
        y = j + DIR[k].y;

        if (x<0 || x>=col || y<0 || y>=row) continue;
        if (GridArray[y*col + x].value  == -1) GridArray[j*col + i].value += 1;
      }
    }
  }
}
/***************************************************************************/
TPoint ChangePixelToBlock(TPoint pixel)
{
  return Point(pixel.x / g_BlockWidth, pixel.y / g_BlockHeight);
}
/***************************************************************************/
void ReadRegister()
{
  TRegistry *reg = new TRegistry();

  reg->RootKey = HKEY_CURRENT_USER;
  if ( !reg->OpenKey(g_RegistryPath, false) ) {
    delete reg;
    return;
  }

  try {
    isHaveColor = reg->ReadBool("Color");
    isHaveQuestionMark = reg->ReadBool("Mark");
    isHaveSound = reg->ReadBool("Sound");

    Xpos = reg->ReadInteger("Xpos");
    Ypos = reg->ReadInteger("Ypos");
    GridCol = reg->ReadInteger("Width");
    GridRow = reg->ReadInteger("Height");
    GameLevel = reg->ReadInteger("Difficulty");
    BombCount = reg->ReadInteger("Mines");

    hero[0].time = reg->ReadInteger("Time1");
    hero[0].name = reg->ReadString("Name1");

    hero[1].time = reg->ReadInteger("Time2");
    hero[1].name = reg->ReadString("Name2");

    hero[2].time = reg->ReadInteger("Time3");
    hero[2].name = reg->ReadString("Name3");

    hero[3].time = reg->ReadInteger("Time4");
    hero[3].name = reg->ReadString("Name4");
  }
  catch(...)
  {
    delete reg;
    reg = NULL;
  }
  delete reg;
}
/***************************************************************************/
void WriteRegister()
{
  TRegistry *reg = new TRegistry();

  reg->RootKey = HKEY_CURRENT_USER;

  if ( !reg->KeyExists(g_RegistryPath) )
  {
    reg->CreateKey(g_RegistryPath);
  }

  if ( !reg->OpenKey(g_RegistryPath,false) )
  {
    delete reg;
    return;
  }

  try {
    reg->WriteBool("Color", isHaveColor);
    reg->WriteBool("Sound", isHaveSound);
    reg->WriteBool("Mark", isHaveQuestionMark);

    reg->WriteInteger("Width", GridCol);
    reg->WriteInteger("Height", GridRow);
    reg->WriteInteger("Difficulty", GameLevel);
    reg->WriteInteger("Mines", BombCount);
    reg->WriteInteger("Xpos", Xpos);
    reg->WriteInteger("Ypos", Ypos);

    reg->WriteInteger("Time1", hero[0].time);
    reg->WriteString("Name1", hero[0].name);

    reg->WriteInteger("Time2", hero[1].time);
    reg->WriteString("Name2", hero[1].name);

    reg->WriteInteger("Time3", hero[2].time);
    reg->WriteString("Name3", hero[2].name);

    reg->WriteInteger("Time4", hero[3].time);
    reg->WriteString("Name4", hero[3].name);
  }
  catch(...)
  {
    delete reg;
    reg = NULL;
  }
  delete reg;
}
/***************************************************************************/

TMainWin *MainWin;
//###########################################################################
void TMainWin::SetGameLevel(int level, int col, int row, int count)
{
  N_Level_Easy->Checked = false;
  N_Level_Middle->Checked = false;
  N_Level_Expert->Checked = false;
  N_Level_Professional->Checked = false;
  N_Level_Customize->Checked = false;

  GameLevel = level;
  BlockOpenCount = 0;

  switch (level)
  {
    case l_Easy:
      N_Level_Easy->Checked = true;
      GridRow = g_Level_1_Row;
      GridCol = g_Level_1_Col;
      BombCount = g_Level_1_Count;
      break;
    case l_Middle:
      N_Level_Middle->Checked = true;
      GridRow = g_Level_2_Row;
      GridCol = g_Level_2_Col;
      BombCount = g_Level_2_Count;
      break;
    case l_Expert:
      N_Level_Expert->Checked = true;
      GridRow = g_Level_3_Row;
      GridCol = g_Level_3_Col;
      BombCount = g_Level_3_Count;
      break;
    case l_Professional:
      N_Level_Professional->Checked = true;
      GridRow = g_Level_4_Row;
      GridCol = g_Level_4_Col;
      BombCount = g_Level_4_Count;
      break;
    case l_Customize:
      N_Level_Customize->Checked = true;
      GridRow = row;
      GridCol = col;
      BombCount = count;
      break;
    default:
      break;
  }

  SetControlSize(GridCol, GridRow);
  LeftBombCount = BombCount;

  CurrentFace = f_Smile;
  DrawGame(GridCol, GridRow);
}
//###########################################################################
void TMainWin::SetControlSize(int col, int row)
{
  Panel_Top->Top = 0;
  Panel_Top->Left = 0;
  Panel_Top->Width = col * g_BlockWidth + 16;
  Panel_Top->Height = g_FaceHeight + 16 + 8;

  Panel_Bottom->Left = 0;
  Panel_Bottom->Top = Panel_Top->Top + Panel_Top->Height;
  Panel_Bottom->Width = Panel_Top->Width;
  Panel_Bottom->Height = row * g_BlockHeight + 16;

  MainWin->Width = Panel_Top->Width + 6;
  MainWin->Height = Panel_Bottom->Top + Panel_Bottom->Height + 52;

  Panel_Left->Left = 10;
  Panel_Left->Top = 12;
  Panel_Right->Left = Panel_Top->Width - Panel_Right->Width - 10;
  Panel_Right->Top = 12;
  Image_Middle->Left = (Panel_Top->Width -Image_Middle->Width)/2;
  Image_Middle->Top = 12;
}
//###########################################################################
void TMainWin::DrawNumber(TImage *image, int num)
{
  int digit[4] = {0};

  if (num < 0) digit[3] = -10;
  num = abs(num);
  for (int i=2; i>=0; --i)
  {
    digit[i] = num % 10;
    num /= 10;
  }

  digit[0] += digit[3];
  for (int i=0; i<3; i++)
  {
    if (digit[i]<10 && digit[i]>=0)
    {
      num = 11-digit[i];
    }
    else
    {
      num = 0;
    }

    image->Canvas->CopyRect(TRect(g_NumberWidth*i, 0, g_NumberWidth*(i+1), g_NumberHeight),
                            Image_Number->Canvas,
                            TRect(0, g_NumberHeight*num, g_NumberWidth, g_NumberHeight*(num+1)));
  }

  return;
}
//###########################################################################
void TMainWin::DrawBlock(int col,int row,int block)
{
  if (block>15 || block<0) return;

  Image_Main->Canvas->CopyRect(TRect(col*g_BlockWidth, row*g_BlockHeight, (col+1)*g_BlockWidth, (row+1)*g_BlockHeight),
                            Image_Block->Canvas,
                            TRect(0, block*g_BlockHeight, g_BlockWidth, (block+1)*g_BlockHeight));

}
//###########################################################################
void TMainWin::DrawGame(int col, int row)
{
  DrawNumber(Image_Left,LeftBombCount);
  DrawNumber(Image_Right,UsedTime);
  ChangeFace(CurrentFace);
  
  for (int j=0; j<row; ++j)
  {
    for (int i=0; i<col; i++)
    {
      DrawBlock(i,j,GridArray[_Index(i,j,col)].view);
    }
  }
}
//###########################################################################
void TMainWin::ChangeFace(int face)
{
  if (CurrentFace != face) {
    CurrentFace = face;
  }

  if (face>4 || face<0) return;

  Image_Middle->Canvas->CopyRect(TRect(0, 0, g_FaceWidth, g_FaceHeight),
                            Image_Face->Canvas,
                            TRect(0, face*g_FaceHeight, g_FaceWidth, (face+1)*g_FaceHeight));

}
//###########################################################################
void TMainWin::SearchBlankBlock(int col, int row)
{
  #define ARRAY_SIZE (g_MaxCol * g_MaxRow)
  TPoint queue[ARRAY_SIZE] = {Point(0,0)};
  int first=0,len=1;

  queue[0] = Point(col,row);

  for (;len > 0;)
  {
    int index;   // GridArray index
    TPoint point;
    int x, y;

    point = queue[first % ARRAY_SIZE];
    --len; first = (first+1)%ARRAY_SIZE;
    index = _Index(point.x,point.y,GridCol);

    GridArray[index].view = b_Blank_Down;
    if (GridArray[index].status != s_Opened) {
      GridArray[index].status = s_Opened;
      ++BlockOpenCount;////////////////////
    }

    DrawBlock(point.x,point.y,b_Blank_Down);

    for (int i=0; i<8; ++i)
    {
      x = point.x + DIR[i].x; y = point.y + DIR[i].y;
      if (x<0 || x>=GridCol || y<0 || y>=GridRow) continue;

      int j = _Index(x,y,GridCol);

      if (GridArray[j].value == -1)
      {
      }
      else if (GridArray[j].value==0)
      {
        if (GridArray[j].status==s_Default)
        {
          ++len;
          queue[(first+len-1)%ARRAY_SIZE] = Point(x,y);
          GridArray[j].status = s_Listed;
        }
      }
      else if (GridArray[j].view==b_Blank || GridArray[j].view==b_Blank_Down ||
               GridArray[j].view==b_QuestionMark || GridArray[j].view==b_QuestionMark_Down )
      {
        GridArray[j].view = 15 - GridArray[j].value;
        if (GridArray[j].status != s_Opened) {
          GridArray[j].status = s_Opened;
          ++BlockOpenCount;///////////////////////////
        }
        DrawBlock(x,y,GridArray[j].view);
      }
    }
  }
  #undef ARRAY_SIZE
}
//###########################################################################
void TMainWin::GameLost()
{
  if (isHaveSound) {
    sndPlaySound(g_Lost_SoundPath, SND_ASYNC  );
  }
  ChangeFace(f_Sad);
  GameStatus = g_Gameover;

  GameTimer->Enabled = false;
  for (int i=0; i<GridCol; ++i)
  {
    for (int j=0; j<GridRow; ++j)

⌨️ 快捷键说明

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