File indexing completed on 2024-09-08 06:48:19
0001 /* 0002 SPDX-FileCopyrightText: 2003 Russell Steffen <rsteffen@bayarea.net> 0003 SPDX-FileCopyrightText: 2003 Stephan Zehetner <s.zehetner@nevox.org> 0004 SPDX-FileCopyrightText: 2006 Dmitry Suzdalev <dimsuz@gmail.com> 0005 SPDX-FileCopyrightText: 2006 Inge Wallin <inge@lysator.liu.se> 0006 SPDX-FileCopyrightText: 2006 Pierre Ducroquet <pinaraf@pinaraf.info> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 0011 #include "default.h" 0012 #include "../../../game.h" 0013 #include "../../../planet.h" 0014 0015 #include <QDebug> 0016 #include <cmath> 0017 #include <cfloat> 0018 0019 AiDefault::AiDefault(Game *game, 0020 const QString &newName, 0021 const QColor &color, 0022 AiLevel level) 0023 : ComputerPlayer(game, newName, color), 0024 m_level(level) 0025 { 0026 0027 } 0028 0029 0030 void AiDefault::play() 0031 { 0032 //qDebug() << "computer playing"; 0033 int ships = 0, minimumShips =10, shipCountFactor = 2; 0034 Planet *target = nullptr; 0035 0036 switch (m_level) 0037 { 0038 case Weak: 0039 minimumShips = 20; 0040 shipCountFactor = 2; 0041 break; 0042 case Normal: // Offensive 0043 minimumShips = 10; 0044 shipCountFactor = 2; 0045 break; 0046 case Hard: // Defensive 0047 minimumShips = 30; 0048 shipCountFactor = 3; 0049 break; 0050 } 0051 0052 for (Planet *home : m_game->planets()) { 0053 if (home->player() == this) { 0054 ships = (int)floor(home->ships() * 0.7 ); 0055 0056 if (ships >= minimumShips) { 0057 bool hasAttack = false; 0058 double minDistance = 100; 0059 0060 for (Planet *attack : m_game->planets()) { 0061 if (attack->player() == this) 0062 continue; 0063 0064 bool skip = false; 0065 double dist = m_game->map()->distance( home, attack ); 0066 0067 if (dist < minDistance && attack->ships() < ships ) { 0068 for (AttackFleet *curFleet : attackList()) { 0069 if (curFleet->destination == attack) { 0070 skip = true; 0071 break; 0072 } 0073 } 0074 if (skip) 0075 continue; 0076 0077 target = attack; 0078 hasAttack = true; 0079 minDistance = dist; 0080 } 0081 } 0082 0083 if (hasAttack) { 0084 m_game->attack( home, target, ships ); 0085 } else { 0086 minDistance = DBL_MAX; 0087 int shipsToSend = 0; 0088 bool hasDestination = false; 0089 0090 for (Planet *attack : m_game->planets()) { 0091 bool skip = false; 0092 double dist = m_game->map()->distance( home, attack ); 0093 int homeships = (int)floor(home->ships() * 0.5 ); 0094 0095 if (dist < minDistance 0096 && attack->player() == this 0097 && attack->ships() < homeships ) { 0098 for (AttackFleet *curFleet : attackList()) { 0099 if (curFleet->destination == attack) { 0100 skip = true; 0101 break; 0102 } 0103 } 0104 if (skip) 0105 continue; 0106 0107 shipsToSend = (int)floor( double(home->ships() 0108 - attack->ships()) / shipCountFactor); 0109 0110 target = attack; 0111 hasDestination = true; 0112 minDistance = dist; 0113 } 0114 } 0115 if (hasDestination) { 0116 m_game->attack( home, target, shipsToSend ); 0117 } 0118 } 0119 } 0120 } 0121 } 0122 Q_EMIT donePlaying(); 0123 }