1 /***************************************************************************
2  *   Copyright (C) 2012 by Andrey Afletdinov <fheroes2@gmail.com>          *
3  *                                                                         *
4  *   Part of the Free Heroes2 Engine:                                      *
5  *   http://sourceforge.net/projects/fheroes2                              *
6  *                                                                         *
7  *   This program is free software; you can redistribute it and/or modify  *
8  *   it under the terms of the GNU General Public License as published by  *
9  *   the Free Software Foundation; either version 2 of the License, or     *
10  *   (at your option) any later version.                                   *
11  *                                                                         *
12  *   This program is distributed in the hope that it will be useful,       *
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
15  *   GNU General Public License for more details.                          *
16  *                                                                         *
17  *   You should have received a copy of the GNU General Public License     *
18  *   along with this program; if not, write to the                         *
19  *   Free Software Foundation, Inc.,                                       *
20  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
21  ***************************************************************************/
22 
23 #ifndef H2BATTLE_BOARD_H
24 #define H2BATTLE_BOARD_H
25 
26 #include <random>
27 
28 #include "battle_cell.h"
29 
30 #define ARENAW 11
31 #define ARENAH 9
32 #define ARENASIZE ARENAW * ARENAH
33 
34 namespace Maps
35 {
36     class Tiles;
37 }
38 
39 namespace Battle
40 {
41     inline direction_t & operator++( direction_t & d )
42     {
43         return d = ( CENTER == d ? TOP_LEFT : direction_t( d << 1 ) );
44     }
45     inline direction_t & operator--( direction_t & d )
46     {
47         return d = ( TOP_LEFT == d ? CENTER : direction_t( d >> 1 ) );
48     }
49 
50     using Indexes = std::vector<int32_t>;
51 
52     class Board : public std::vector<Cell>
53     {
54     public:
55         Board();
56 
57         void Reset( void );
58 
59         void SetArea( const fheroes2::Rect & );
60 
61         s32 GetIndexAbsPosition( const fheroes2::Point & ) const;
62         std::vector<Unit *> GetNearestTroops( const Unit * startUnit, const std::vector<Unit *> & blackList );
63         Indexes GetPath( const Unit & unit, const Position & destination, const bool debug = true ) const;
64 
65         void SetEnemyQuality( const Unit & ) const;
66         void SetPositionQuality( const Unit & ) const;
67         void SetScanPassability( const Unit & );
68 
69         void SetCobjObjects( const Maps::Tiles & tile, std::mt19937 & gen );
70         void SetCovrObjects( int icn );
71 
72         static std::string GetMoatInfo( void );
73 
74         static Cell * GetCell( s32 position, int dir = CENTER );
75         static bool isNearIndexes( s32, s32 );
76         static bool isValidIndex( s32 );
77         static bool isCastleIndex( s32 );
78         static bool isMoatIndex( s32 index, const Unit & b );
79         static bool isBridgeIndex( s32 index, const Unit & b );
80         static bool isOutOfWallsIndex( s32 );
81         static bool isReflectDirection( int );
82         static bool IsLeftDirection( const int32_t startCellId, const int32_t endCellId, const bool prevLeftDirection );
83         static bool isNegativeDistance( s32 index1, s32 index2 );
84         static int DistanceFromOriginX( int32_t index, bool reflect );
85         static int GetReflectDirection( int );
86         static int GetDirection( s32, s32 );
87         static int32_t DoubleCellAttackValue( const Unit & attacker, const Unit & target, const int32_t from, const int32_t targetCell );
88         static int32_t OptimalAttackTarget( const Unit & attacker, const Unit & target, const int32_t from );
89         static int32_t OptimalAttackValue( const Unit & attacker, const Unit & target, const int32_t from );
90         static uint32_t GetDistance( s32, s32 );
91         static bool isValidDirection( s32, int );
92         static s32 GetIndexDirection( s32, int );
93         static Indexes GetDistanceIndexes( s32, u32 );
94         static Indexes GetAroundIndexes( s32 center, s32 ignore = -1 );
95         static Indexes GetAroundIndexes( const Unit & unit );
96         static Indexes GetAroundIndexes( const Position & position );
97         static Indexes GetMoveWideIndexes( s32, bool reflect );
98         static bool isValidMirrorImageIndex( s32, const Unit * );
99 
100         // Checks that the current unit (to which the current passability information relates) is able (in principle)
101         // to attack from the cell with the given index
102         static bool CanAttackUnitFromCell( const Unit & currentUnit, const int32_t from );
103         // Checks that the current unit (to which the current passability information relates) is able to attack the
104         // target from the position which corresponds to the given index
105         static bool CanAttackUnitFromPosition( const Unit & currentUnit, const Unit & target, const int32_t dst );
106 
107         static Indexes GetAdjacentEnemies( const Unit & unit );
108 
109         // Handles the situation when the cell with the given index is specified as the target cell for the movement of
110         // the current unit (to which the current passability information relates), this cell is located on the border
111         // of the cell space reachable for this unit and it should be the tail cell of this unit
112         static int32_t FixupDestinationCell( const Unit & currentUnit, const int32_t dst );
113 
114     private:
115         void SetCobjObject( const int icn, const int32_t dst );
116 
117         bool GetPathForUnit( const Unit & unit, const Position & destination, const uint32_t remainingSteps, const int32_t currentCellId,
118                              std::vector<bool> & visitedCells, Indexes & result ) const;
119         bool GetPathForWideUnit( const Unit & unit, const Position & destination, const uint32_t remainingSteps, const int32_t currentHeadCellId,
120                                  const int32_t prevHeadCellId, std::vector<bool> & visitedCells, Indexes & result ) const;
121         void StraightenPathForUnit( const int32_t currentCellId, Indexes & path ) const;
122     };
123 }
124 
125 #endif
126