1///////////////////////////////////////////////////////////////////////////////
2// Name:        bombs1.cpp
3// Purpose:     Implementation of the class BombsGame
4// Author:      P. Foggia 1996
5// Modified by: Wlodzimierz Skiba (ABX) since 2003
6// Created:     1996
7// RCS-ID:      $Id: game.cpp 35650 2005-09-23 12:56:45Z MR $
8// Copyright:   (c) 1996 P. Foggia
9// Licence:     wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12#include "wx/wxprec.h"
13
14#ifdef __BORLANDC__
15  #pragma hdrstop
16#endif
17
18#ifndef  WX_PRECOMP
19#   include "wx/wx.h"
20#endif
21
22#include "game.h"
23#include <stdlib.h>
24#include <limits.h>
25
26#define PROB 0.2
27
28#ifndef RAND_MAX
29#   define RAND_MAX INT_MAX
30#endif
31
32
33BombsGame::~BombsGame()
34{
35    if (m_field)
36    {
37        delete[] m_field;
38    }
39}
40
41// Initialize the play field. Returns false on failure
42bool BombsGame::Init(int aWidth, int aHeight, bool easyCorner)
43{
44    m_gridFocusX = m_gridFocusY = -1;
45
46    int x, y;
47    int xx, yy;
48
49    if (m_field)
50    {
51        delete[] m_field;
52    }
53
54    m_field = new short[aWidth*aHeight];
55    if (!m_field)
56    {
57        m_width = m_height = 0;
58        return false;
59    }
60
61    m_width = aWidth;
62    m_height = aHeight;
63
64    for(x=0; x<m_width; x++)
65    {
66        for(y=0; y<m_height; y++)
67        {
68            m_field[x+y*m_width] = ((float)rand()/RAND_MAX <PROB)
69                ? BG_HIDDEN | BG_BOMB
70                : BG_HIDDEN;
71        }
72    }
73
74    /* Force (0,0) not to have a bomb for those that don't want to have
75       to guess on the first move. Better would be to for the MS rule that
76       whatever is picked first isn't a bomb.
77     */
78    if(easyCorner)
79    {
80        m_field[0] = BG_HIDDEN;
81    }
82
83    m_numBombCells = 0;
84    for(x=0; x<m_width; x++)
85        for(y=0; y<m_height; y++)
86            if (m_field[x+y*m_width] & BG_BOMB)
87            {
88                m_numBombCells++;
89
90                for(xx=x-1; xx<=x+1; xx++)
91                    if (xx>=0 && xx<m_width)
92                        for(yy=y-1; yy<=y+1; yy++)
93                            if (yy>=0 && yy<m_height && (yy!=y || xx!=x))
94                                m_field[xx+yy*m_width]++;
95            }
96
97    m_numRemainingCells = m_height*m_width-m_numBombCells;
98    m_numMarkedCells = 0;
99
100    return true;
101}
102
103void BombsGame::Mark(int x, int y)
104{
105    m_field[x+y*m_width] ^= BG_MARKED;
106    if (IsMarked(x, y))
107        m_numMarkedCells++;
108    else
109        m_numMarkedCells--;
110}
111
112void BombsGame::Unhide(int x, int y, bool b_selected)
113{
114    if (!IsHidden(x,y))
115    {
116        return;
117    }
118
119    if (b_selected)
120        m_field[x+y*m_width] |= BG_SELECTED;
121
122    m_field[x+y*m_width] &= ~BG_HIDDEN;
123
124    if (!IsBomb(x,y))
125    {
126        m_numRemainingCells--;
127    }
128}
129
130
131void BombsGame::Explode(int x, int y)
132{
133    m_field[x+y*m_width] |= BG_EXPLODED;
134}
135