File indexing completed on 2024-04-21 04:03:15

0001 /*
0002     SPDX-FileCopyrightText: 2007 Paolo Capriotti <p.capriotti@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "aientity.h"
0008 #include "ai/smartai.h"
0009 #include "ai/dummyai.h"
0010 #include "shot.h"
0011 #include "seaview.h"
0012 #include "settings.h"
0013 
0014 #include <KGameDifficulty>
0015 
0016 #include <QIcon>
0017 
0018 AIEntity::AIEntity(Sea::Player player, Sea* sea, SeaView *seaview)
0019 : Entity(player, seaview, sea->battleShipsConfiguration())
0020 , m_sea(sea)
0021 {
0022     switch (KGameDifficulty::globalLevel()) {
0023     case KGameDifficultyLevel::Easy:
0024         m_ai = new DummyAI(m_player, m_sea, sea->battleShipsConfiguration());
0025         break;
0026     case KGameDifficultyLevel::Medium:
0027         m_ai = new SmartAI(m_player, m_sea, true, sea->battleShipsConfiguration());
0028         break;
0029     default: // hard
0030         m_ai = new SmartAI(m_player, m_sea, false, sea->battleShipsConfiguration());
0031         break;
0032     }
0033 }
0034 
0035 AIEntity::~AIEntity()
0036 {
0037     delete m_ai;
0038 }
0039 
0040 void AIEntity::notify(Sea::Player player, const Coord& c, const HitInfo& info)
0041 {
0042     m_ai->notify(player, c, info);
0043 
0044     // add a border around opponent sunk ship in KBS4 mode when no adjacentShips
0045     // are allowed, the AI will not try to shoot at points that are not free
0046     if (m_level == COMPAT_KBS4 &&
0047         player == m_player &&
0048         !m_sea->isAdjacentShipsAllowed() &&
0049         info.shipDestroyed) {
0050             m_sea->addBorder(Sea::opponent(player), info.shipPos);
0051     }
0052 
0053     if (Settings::enableSounds()) {
0054         // This 3sec is hardcoded to current sounds
0055         QTimer::singleShot(3000, this, &AIEntity::getShoot);
0056     } else {
0057         getShoot();
0058     }
0059 }
0060 
0061 void AIEntity::notifyGameOptions()
0062 {
0063     Q_EMIT gameOptionsInterchanged();
0064 }
0065 
0066 void AIEntity::start()
0067 {
0068     Q_EMIT ready(m_player);
0069 }
0070 
0071 void AIEntity::startPlacing()
0072 {
0073     m_seaview->setStatus(Sea::PLACING_SHIPS);
0074     m_ai->setShips();
0075     Q_EMIT shipsPlaced();
0076 }
0077 
0078 void AIEntity::startPlaying()
0079 {
0080     getShoot();
0081     m_seaview->setStatus(Sea::PLAYING);
0082 }
0083 
0084 void AIEntity::hit(Shot* shot)
0085 {
0086     if (shot->player() != m_player && m_sea->canHit(shot->player(), shot->pos())) {
0087         shot->execute(m_sea->hit(shot->pos()));
0088     }
0089     else {
0090         shot->execute(HitInfo::INVALID);
0091     }
0092 }
0093 
0094 void AIEntity::getShoot()
0095 {
0096     if (m_sea->turn() == m_player) {
0097         Coord c = m_ai->getMove();
0098         
0099         Q_EMIT shoot(m_player, c);
0100     }
0101 }
0102 
0103 QIcon AIEntity::icon() const
0104 {
0105     return QIcon::fromTheme( QLatin1String( "roll" ));
0106 }
0107 
0108 #include "moc_aientity.cpp"